Skip to content

[LLD][COFF] Move addFile implementation to LinkerDriver (NFC) #121342

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 74 additions & 8 deletions lld/COFF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,71 @@ bool LinkerDriver::findUnderscoreMangle(StringRef sym) {
return s && !isa<Undefined>(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<BitcodeFile>(file))
f->parseLazy();
else
cast<ObjFile>(file)->parseLazy();
} else {
file->parse();
if (auto *f = dyn_cast<ObjFile>(file)) {
ctx.objFileInstances.push_back(f);
} else if (auto *f = dyn_cast<BitcodeFile>(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<ImportFile>(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<MemoryBuffer> mb) {
MemoryBufferRef mbref = *mb;
make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take ownership
Expand Down Expand Up @@ -222,25 +287,25 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
addArchiveBuffer(m, "<whole-archive>", filename, memberIndex++);
return;
}
ctx.symtab.addFile(make<ArchiveFile>(ctx, mbref));
addFile(make<ArchiveFile>(ctx, mbref));
break;
case file_magic::bitcode:
ctx.symtab.addFile(make<BitcodeFile>(ctx, mbref, "", 0, lazy));
addFile(make<BitcodeFile>(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<PDBInputFile>(ctx, mbref));
addFile(make<PDBInputFile>(ctx, mbref));
break;
case file_magic::coff_cl_gl_object:
Err(ctx) << filename
<< ": is not a native COFF file. Recompile without /GL";
break;
case file_magic::pecoff_executable:
if (ctx.config.mingw) {
ctx.symtab.addFile(make<DLLFile>(ctx.symtab, mbref));
addFile(make<DLLFile>(ctx.symtab, mbref));
break;
}
if (filename.ends_with_insensitive(".dll")) {
Expand Down Expand Up @@ -306,7 +371,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
if (magic == file_magic::coff_import_library) {
InputFile *imp = make<ImportFile>(ctx, mb);
imp->parentName = parentName;
ctx.symtab.addFile(imp);
addFile(imp);
return;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -1400,7 +1465,7 @@ void LinkerDriver::convertResources() {
}
ObjFile *f =
ObjFile::create(ctx, convertResToCOFF(resources, resourceObjFiles));
ctx.symtab.addFile(f);
addFile(f);
f->includeResourceChunks();
}

Expand Down Expand Up @@ -2702,6 +2767,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> 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 =
Expand Down
11 changes: 7 additions & 4 deletions lld/COFF/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,10 @@ class LinkerDriver {

void linkerMain(llvm::ArrayRef<const char *> 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);
Expand Down Expand Up @@ -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();
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lld/COFF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ImportFile>(symtab.ctx, mbref);
symtab.addFile(impFile);
symtab.ctx.driver.addFile(impFile);
}
70 changes: 2 additions & 68 deletions lld/COFF/SymbolTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<BitcodeFile>(file))
f->parseLazy();
else
cast<ObjFile>(file)->parseLazy();
} else {
file->parse();
if (auto *f = dyn_cast<ObjFile>(file)) {
ctx.objFileInstances.push_back(f);
} else if (auto *f = dyn_cast<BitcodeFile>(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<ImportFile>(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};
}
Expand All @@ -118,7 +53,7 @@ static void forceLazy(Symbol *s) {
case Symbol::Kind::LazyObjectKind: {
InputFile *file = cast<LazyObject>(s)->file;
file->lazy = false;
file->symtab.addFile(file);
file->symtab.ctx.driver.addFile(file);
break;
}
case Symbol::Kind::LazyDLLSymbolKind: {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -1054,7 +989,6 @@ Symbol *SymbolTable::addUndefined(StringRef name) {
}

void SymbolTable::compileBitcodeFiles() {
ltoCompilationDone = true;
if (ctx.bitcodeFileInstances.empty())
return;

Expand Down
3 changes: 0 additions & 3 deletions lld/COFF/SymbolTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -155,7 +153,6 @@ class SymbolTable {

llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> symMap;
std::unique_ptr<BitcodeCompiler> lto;
bool ltoCompilationDone = false;
std::vector<std::pair<Symbol *, Symbol *>> entryThunks;
llvm::DenseMap<Symbol *, Symbol *> exitThunks;
};
Expand Down
Loading