@@ -280,6 +280,12 @@ void LinkerDriver::addFile(StringRef path) {
280280 case file_magic::wasm_object:
281281 files.push_back (createObjectFile (mbref));
282282 break ;
283+ case file_magic::unknown:
284+ if (mbref.getBuffer ().starts_with (" #STUB\n " )) {
285+ files.push_back (make<StubFile>(mbref));
286+ break ;
287+ }
288+ [[fallthrough]];
283289 default :
284290 error (" unknown file type: " + mbref.getBufferIdentifier ());
285291 }
@@ -834,6 +840,53 @@ static void createOptionalSymbols() {
834840 WasmSym::tlsBase = createOptionalGlobal (" __tls_base" , false );
835841}
836842
843+ static void processStubLibraries () {
844+ log (" -- processStubLibraries" );
845+ for (auto &stub_file : symtab->stubFiles ) {
846+ LLVM_DEBUG (llvm::dbgs ()
847+ << " processing stub file: " << stub_file->getName () << " \n " );
848+ for (auto [name, deps]: stub_file->symbolDependencies ) {
849+ auto * sym = symtab->find (name);
850+ if (!sym || !sym->isUndefined () || !sym->isUsedInRegularObj ||
851+ sym->forceImport ) {
852+ LLVM_DEBUG (llvm::dbgs () << " stub not in needed: " << name << " \n " );
853+ continue ;
854+ }
855+ // The first stub library to define a given symbol sets this and
856+ // definitions in later stub libraries are ignored.
857+ sym->forceImport = true ;
858+ if (sym->traced )
859+ message (toString (stub_file) + " : importing " + name);
860+ else
861+ LLVM_DEBUG (llvm::dbgs ()
862+ << toString (stub_file) << " : importing " << name << " \n " );
863+ for (const auto dep : deps) {
864+ auto * needed = symtab->find (dep);
865+ if (!needed) {
866+ error (toString (stub_file) + " : undefined symbol: " + dep +
867+ " . Required by " + toString (*sym));
868+ } else if (needed->isUndefined ()) {
869+ error (toString (stub_file) +
870+ " : undefined symbol: " + toString (*needed) +
871+ " . Required by " + toString (*sym));
872+ } else {
873+ LLVM_DEBUG (llvm::dbgs ()
874+ << " force export: " << toString (*needed) << " \n " );
875+ needed->forceExport = true ;
876+ needed->isUsedInRegularObj = true ;
877+ if (auto *lazy = dyn_cast<LazySymbol>(needed)) {
878+ lazy->fetch ();
879+ if (!config->whyExtract .empty ())
880+ config->whyExtractRecords .emplace_back (stub_file->getName (),
881+ sym->getFile (), *sym);
882+ }
883+ }
884+ }
885+ }
886+ }
887+ log (" -- done processStubLibraries" );
888+ }
889+
837890// Reconstructs command line arguments so that so that you can re-run
838891// the same command with the same inputs. This is for --reproduce.
839892static std::string createResponseFile (const opt::InputArgList &args) {
@@ -1132,6 +1185,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
11321185 if (errorCount ())
11331186 return ;
11341187
1188+ processStubLibraries ();
1189+
11351190 createOptionalSymbols ();
11361191
11371192 // Resolve any variant symbols that were created due to signature
0 commit comments