================
@@ -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