diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index be01ee41c9a2f..83d3f5d4cf99c 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -189,6 +189,71 @@ bool LinkerDriver::findUnderscoreMangle(StringRef sym) { return s && !isa(s); } +static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) { + if (mt == IMAGE_FILE_MACHINE_UNKNOWN) + return true; + switch (ctx.config.machine) { + case ARM64: + return mt == ARM64 || mt == ARM64X; + case ARM64EC: + return isArm64EC(mt) || mt == AMD64; + case ARM64X: + return isAnyArm64(mt) || mt == AMD64; + case IMAGE_FILE_MACHINE_UNKNOWN: + return true; + default: + return ctx.config.machine == mt; + } +} + +void LinkerDriver::addFile(InputFile *file) { + Log(ctx) << "Reading " << toString(file); + if (file->lazy) { + if (auto *f = dyn_cast(file)) + f->parseLazy(); + else + cast(file)->parseLazy(); + } else { + file->parse(); + if (auto *f = dyn_cast(file)) { + ctx.objFileInstances.push_back(f); + } else if (auto *f = dyn_cast(file)) { + if (ltoCompilationDone) { + Err(ctx) << "LTO object file " << toString(file) + << " linked in after " + "doing LTO compilation."; + } + ctx.bitcodeFileInstances.push_back(f); + } else if (auto *f = dyn_cast(file)) { + ctx.importFileInstances.push_back(f); + } + } + + MachineTypes mt = file->getMachineType(); + // The ARM64EC target must be explicitly specified and cannot be inferred. + if (mt == ARM64EC && + (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN || + (ctx.config.machineInferred && + (ctx.config.machine == ARM64 || ctx.config.machine == AMD64)))) { + Err(ctx) << toString(file) + << ": machine type arm64ec is ambiguous and cannot be " + "inferred, use /machine:arm64ec or /machine:arm64x"; + return; + } + if (!compatibleMachineType(ctx, mt)) { + Err(ctx) << toString(file) << ": machine type " << machineToStr(mt) + << " conflicts with " << machineToStr(ctx.config.machine); + return; + } + if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN && + mt != IMAGE_FILE_MACHINE_UNKNOWN) { + ctx.config.machineInferred = true; + setMachine(mt); + } + + parseDirectives(file); +} + MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr mb) { MemoryBufferRef mbref = *mb; make>(std::move(mb)); // take ownership @@ -222,17 +287,17 @@ void LinkerDriver::addBuffer(std::unique_ptr mb, addArchiveBuffer(m, "", filename, memberIndex++); return; } - ctx.symtab.addFile(make(ctx, mbref)); + addFile(make(ctx, mbref)); break; case file_magic::bitcode: - ctx.symtab.addFile(make(ctx, mbref, "", 0, lazy)); + addFile(make(ctx, mbref, "", 0, lazy)); break; case file_magic::coff_object: case file_magic::coff_import_library: - ctx.symtab.addFile(ObjFile::create(ctx, mbref, lazy)); + addFile(ObjFile::create(ctx, mbref, lazy)); break; case file_magic::pdb: - ctx.symtab.addFile(make(ctx, mbref)); + addFile(make(ctx, mbref)); break; case file_magic::coff_cl_gl_object: Err(ctx) << filename @@ -240,7 +305,7 @@ void LinkerDriver::addBuffer(std::unique_ptr mb, break; case file_magic::pecoff_executable: if (ctx.config.mingw) { - ctx.symtab.addFile(make(ctx.symtab, mbref)); + addFile(make(ctx.symtab, mbref)); break; } if (filename.ends_with_insensitive(".dll")) { @@ -306,7 +371,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, if (magic == file_magic::coff_import_library) { InputFile *imp = make(ctx, mb); imp->parentName = parentName; - ctx.symtab.addFile(imp); + addFile(imp); return; } @@ -326,7 +391,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName, } obj->parentName = parentName; - ctx.symtab.addFile(obj); + addFile(obj); Log(ctx) << "Loaded " << obj << " for " << symName; } @@ -1400,7 +1465,7 @@ void LinkerDriver::convertResources() { } ObjFile *f = ObjFile::create(ctx, convertResToCOFF(resources, resourceObjFiles)); - ctx.symtab.addFile(f); + addFile(f); f->includeResourceChunks(); } @@ -2702,6 +2767,7 @@ void LinkerDriver::linkerMain(ArrayRef argsArr) { // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files (unless -thinlto-index-only was given, in which case we // resolve symbols and write indices, but don't generate native code or link). + ltoCompilationDone = true; ctx.symtab.compileBitcodeFiles(); if (Defined *d = diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h index c2b92f61dcf4b..b04a00e2d1cd1 100644 --- a/lld/COFF/Driver.h +++ b/lld/COFF/Driver.h @@ -80,13 +80,10 @@ class LinkerDriver { void linkerMain(llvm::ArrayRef args); - void setMachine(llvm::COFF::MachineTypes machine); + void addFile(InputFile *file); void addClangLibSearchPaths(const std::string &argv0); - // Used by the resolver to parse .drectve section contents. - void parseDirectives(InputFile *file); - // Used by ArchiveFile to enqueue members. void enqueueArchiveMember(const Archive::Child &c, const Archive::Symbol &sym, StringRef parentName); @@ -121,6 +118,7 @@ class LinkerDriver { // Symbol names are mangled by prepending "_" on x86. StringRef mangle(StringRef sym); + void setMachine(llvm::COFF::MachineTypes machine); llvm::Triple::ArchType getArch(); uint64_t getDefaultImageBase(); @@ -144,6 +142,9 @@ class LinkerDriver { void createImportLibrary(bool asLib); + // Used by the resolver to parse .drectve section contents. + void parseDirectives(InputFile *file); + void parseModuleDefs(StringRef path); // Parse an /order file. If an option is given, the linker places COMDAT @@ -279,6 +280,8 @@ class LinkerDriver { // Create export thunks for exported and patchable Arm64EC function symbols. void createECExportThunks(); void maybeCreateECExportThunk(StringRef name, Symbol *&sym); + + bool ltoCompilationDone = false; }; // Create enum with OPT_xxx values for each option in Options.td diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index ad21311e8b28f..e698f66b84f62 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -1412,5 +1412,5 @@ void DLLFile::makeImport(DLLFile::Symbol *s) { memcpy(p, s->dllName.data(), s->dllName.size()); MemoryBufferRef mbref = MemoryBufferRef(StringRef(buf, size), s->dllName); ImportFile *impFile = make(symtab.ctx, mbref); - symtab.addFile(impFile); + symtab.ctx.driver.addFile(impFile); } diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index fc78afb4c9e40..6f25ad0620927 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -37,71 +37,6 @@ StringRef ltrim1(StringRef s, const char *chars) { return s; } -static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) { - if (mt == IMAGE_FILE_MACHINE_UNKNOWN) - return true; - switch (ctx.config.machine) { - case ARM64: - return mt == ARM64 || mt == ARM64X; - case ARM64EC: - return COFF::isArm64EC(mt) || mt == AMD64; - case ARM64X: - return COFF::isAnyArm64(mt) || mt == AMD64; - case IMAGE_FILE_MACHINE_UNKNOWN: - return true; - default: - return ctx.config.machine == mt; - } -} - -void SymbolTable::addFile(InputFile *file) { - Log(ctx) << "Reading " << toString(file); - if (file->lazy) { - if (auto *f = dyn_cast(file)) - f->parseLazy(); - else - cast(file)->parseLazy(); - } else { - file->parse(); - if (auto *f = dyn_cast(file)) { - ctx.objFileInstances.push_back(f); - } else if (auto *f = dyn_cast(file)) { - if (ltoCompilationDone) { - Err(ctx) << "LTO object file " << toString(file) - << " linked in after " - "doing LTO compilation."; - } - ctx.bitcodeFileInstances.push_back(f); - } else if (auto *f = dyn_cast(file)) { - ctx.importFileInstances.push_back(f); - } - } - - MachineTypes mt = file->getMachineType(); - // The ARM64EC target must be explicitly specified and cannot be inferred. - if (mt == ARM64EC && - (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN || - (ctx.config.machineInferred && - (ctx.config.machine == ARM64 || ctx.config.machine == AMD64)))) { - Err(ctx) << toString(file) - << ": machine type arm64ec is ambiguous and cannot be " - "inferred, use /machine:arm64ec or /machine:arm64x"; - return; - } - if (!compatibleMachineType(ctx, mt)) { - Err(ctx) << toString(file) << ": machine type " << machineToStr(mt) - << " conflicts with " << machineToStr(ctx.config.machine); - return; - } - if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN && - mt != IMAGE_FILE_MACHINE_UNKNOWN) { - ctx.config.machineInferred = true; - ctx.driver.setMachine(mt); - } - - ctx.driver.parseDirectives(file); -} - static COFFSyncStream errorOrWarn(COFFLinkerContext &ctx) { return {ctx, ctx.config.forceUnresolved ? DiagLevel::Warn : DiagLevel::Err}; } @@ -118,7 +53,7 @@ static void forceLazy(Symbol *s) { case Symbol::Kind::LazyObjectKind: { InputFile *file = cast(s)->file; file->lazy = false; - file->symtab.addFile(file); + file->symtab.ctx.driver.addFile(file); break; } case Symbol::Kind::LazyDLLSymbolKind: { @@ -776,7 +711,7 @@ void SymbolTable::addLazyObject(InputFile *f, StringRef n) { return; s->pendingArchiveLoad = true; f->lazy = false; - addFile(f); + ctx.driver.addFile(f); } void SymbolTable::addLazyDLLSymbol(DLLFile *f, DLLFile::Symbol *sym, @@ -1054,7 +989,6 @@ Symbol *SymbolTable::addUndefined(StringRef name) { } void SymbolTable::compileBitcodeFiles() { - ltoCompilationDone = true; if (ctx.bitcodeFileInstances.empty()) return; diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 8548a6d036a9d..5443815172dfd 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -51,8 +51,6 @@ class SymbolTable { llvm::COFF::MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN) : ctx(c), machine(machine) {} - void addFile(InputFile *file); - // Emit errors for symbols that cannot be resolved. void reportUnresolvable(); @@ -155,7 +153,6 @@ class SymbolTable { llvm::DenseMap symMap; std::unique_ptr lto; - bool ltoCompilationDone = false; std::vector> entryThunks; llvm::DenseMap exitThunks; };