================
@@ -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"); 
+      }
+    }
----------------
TartanLlama wrote:

I guess a slightly more user-friendly error may help give an idea of what the 
problem is, then it's a case of googling the string. Something like

```
thread context ABI mismatch: <file> uses the component model thread context 
ABI, but other files use the global thread context ABI; the files may have been 
compiled with incompatible feature flags, or with incompatible compiler versions
``` 

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