aboutsummaryrefslogtreecommitdiff
path: root/lld/COFF/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/Driver.cpp')
-rw-r--r--lld/COFF/Driver.cpp91
1 files changed, 79 insertions, 12 deletions
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index a4d6b94..791382f 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -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
@@ -222,17 +287,17 @@ 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
@@ -240,7 +305,7 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
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")) {
@@ -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;
}
@@ -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();
}
@@ -2548,7 +2613,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
symtab.addAbsolute(mangle("__guard_eh_cont_count"), 0);
symtab.addAbsolute(mangle("__guard_eh_cont_table"), 0);
- if (isArm64EC(ctx.config.machine)) {
+ if (symtab.isEC()) {
symtab.addAbsolute("__arm64x_extra_rfe_table", 0);
symtab.addAbsolute("__arm64x_extra_rfe_table_size", 0);
symtab.addAbsolute("__arm64x_redirection_metadata", 0);
@@ -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 =
@@ -2812,10 +2878,10 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Handle /call-graph-ordering-file and /call-graph-profile-sort (default on).
if (config->callGraphProfileSort) {
llvm::TimeTraceScope timeScope("Call graph");
- if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file)) {
+ if (auto *arg = args.getLastArg(OPT_call_graph_ordering_file))
parseCallGraphFile(arg->getValue());
- }
- readCallGraphsFromObjectFiles(ctx);
+ else
+ readCallGraphsFromObjectFiles(ctx);
}
// Handle /print-symbol-order.
@@ -2824,6 +2890,7 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (ctx.symtabEC)
ctx.symtabEC->initializeECThunks();
+ ctx.forEachSymtab([](SymbolTable &symtab) { symtab.initializeLoadConfig(); });
// Identify unreferenced COMDAT sections.
if (config->doGC) {