================
@@ -1272,6 +1310,77 @@ static void checkZOptions(opt::InputArgList &args) {
       warn("unknown -z value: " + StringRef(arg->getValue()));
 }
 
+// Determine the thread context ABI based on object file features.
+// This must be called after LTO, since LTO object files are needed.
+static void determineThreadContextABI(ArrayRef<ObjFile *> files) {
+  // A complication is that a user may attempt to link together object files
+  // compiled with different versions of LLVM, where one does not specifiy
+  // -component-model-thread-context when using the global thread context ABI.
+  // They may also attempt to link object files with the global ABI compiled 
with
+  // older LLVM versions, but link them with a newer wasm-ld. To ensure the 
correct behavior
+  // in both of these cases, we treat the import of a __stack_pointer global 
from the env module
+  // as an indication that the global thread context ABI is being used.
+
+  enum class ThreadContextABI {
+    Undetermined,
+    ComponentModelBuiltins,
+    Globals
+  };
+
+  ThreadContextABI threadContextABI = ThreadContextABI::Undetermined;
+
+  for (ObjFile *obj : files) {
+    auto targetFeatures = obj->getWasmObj()->getTargetFeatures();
+    auto threadContextFeature = llvm::find_if(targetFeatures,
+                              [](const auto &f) {
+                                return f.Name == 
"component-model-thread-context";
+                              });
+
+    bool usesComponentModelThreadContext = threadContextFeature != 
targetFeatures.end() &&
+                                    threadContextFeature->Prefix == 
WASM_FEATURE_PREFIX_USED;
+
+    if (threadContextFeature == targetFeatures.end()) {
+      // If the feature is not explicitly used or disallowed, check for the 
presence of a __stack_pointer
+      // import in this specific file to determine if the global thread 
context ABI is being used.
+      bool hasStackPointerImport = llvm::any_of(obj->getSymbols(), [](const 
auto &sym) {
+        return sym && sym->getName() == "__stack_pointer" && 
+               sym->kind() == Symbol::UndefinedGlobalKind &&
+               sym->importModule && sym->importModule == "env";
+      });
+      if (!hasStackPointerImport) {
+        // No __stack_pointer import, so this is probably an object file 
compiled from assembly or
+        // some other source that doesn't care about the thread context ABI. 
As such, we let it pass.
+        continue;
+      }
+      // Treat this as using the globals ABI
+      usesComponentModelThreadContext = false;
+    }     
+
+    if (usesComponentModelThreadContext) {
+      if (threadContextABI == ThreadContextABI::Undetermined) {
+        threadContextABI = ThreadContextABI::ComponentModelBuiltins;
+      } else if (threadContextABI != ThreadContextABI::ComponentModelBuiltins) 
{
+        error("thread context ABI mismatch: " + obj->getName() +
+              " uses component-model-thread-context but other files disallow 
it");
+      }
+    } else {
+      if (threadContextABI == ThreadContextABI::Undetermined) {
+        threadContextABI = ThreadContextABI::Globals;
+      } else if (threadContextABI != ThreadContextABI::Globals) {
+        error("thread context ABI mismatch: " + obj->getName() +
+              " disallows component-model-thread-context but other files use 
it"); 
+      }
+    }
----------------
alexcrichton wrote:

This looks great to me, thanks!

Or, well, great in the sense that an error is created, not great in the sense 
that no one outside of this PR's authors or reviewers will know what to do with 
the error. I'm not aware of anything better to do in that respect though, so I 
mostly just want to say that I acknowledge the tradeoff here.

https://github.com/llvm/llvm-project/pull/175800
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to