Skip to content

Commit 25f3b01

Browse files
committed
Address review comments especially i386 support
1 parent 9a4b6b7 commit 25f3b01

File tree

5 files changed

+91
-68
lines changed

5 files changed

+91
-68
lines changed

lld/COFF/Driver.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -198,28 +198,8 @@ static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) {
198198
}
199199

200200
void LinkerDriver::addFile(InputFile *file) {
201-
Log(ctx) << "Reading " << toString(file);
202-
if (file->lazy) {
203-
if (auto *f = dyn_cast<BitcodeFile>(file))
204-
f->parseLazy();
205-
else
206-
cast<ObjFile>(file)->parseLazy();
207-
} else {
208-
file->parse();
209-
if (auto *f = dyn_cast<ObjFile>(file)) {
210-
ctx.objFileInstances.push_back(f);
211-
} else if (auto *f = dyn_cast<BitcodeFile>(file)) {
212-
if (ltoCompilationDone) {
213-
Err(ctx) << "LTO object file " << toString(file)
214-
<< " linked in after "
215-
"doing LTO compilation.";
216-
}
217-
f->symtab.bitcodeFileInstances.push_back(f);
218-
} else if (auto *f = dyn_cast<ImportFile>(file)) {
219-
ctx.importFileInstances.push_back(f);
220-
}
221-
}
222-
201+
// We need to process the machine type early on, so that APIs such as
202+
// `mangle()` won't fail.
223203
MachineTypes mt = file->getMachineType();
224204
// The ARM64EC target must be explicitly specified and cannot be inferred.
225205
if (mt == ARM64EC &&
@@ -242,6 +222,28 @@ void LinkerDriver::addFile(InputFile *file) {
242222
setMachine(mt);
243223
}
244224

225+
Log(ctx) << "Reading " << toString(file);
226+
if (file->lazy) {
227+
if (auto *f = dyn_cast<BitcodeFile>(file))
228+
f->parseLazy();
229+
else
230+
cast<ObjFile>(file)->parseLazy();
231+
} else {
232+
file->parse();
233+
if (auto *f = dyn_cast<ObjFile>(file)) {
234+
ctx.objFileInstances.push_back(f);
235+
} else if (auto *f = dyn_cast<BitcodeFile>(file)) {
236+
if (ltoCompilationDone) {
237+
Err(ctx) << "LTO object file " << toString(file)
238+
<< " linked in after "
239+
"doing LTO compilation.";
240+
}
241+
f->symtab.bitcodeFileInstances.push_back(f);
242+
} else if (auto *f = dyn_cast<ImportFile>(file)) {
243+
ctx.importFileInstances.push_back(f);
244+
}
245+
}
246+
245247
parseDirectives(file);
246248
}
247249

lld/COFF/InputFiles.cpp

Lines changed: 63 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,6 @@ static coff_symbol_generic *cloneSymbol(COFFSymbolRef sym) {
117117
// Skip importing DllMain thunks from import libraries.
118118
static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
119119
const Archive::Symbol &sym, bool &skipDllMain) {
120-
if (skipDllMain)
121-
return true;
122120
const Archive::Child &c =
123121
CHECK(sym.getMember(), file->getFileName() +
124122
": could not get the member for symbol " +
@@ -144,15 +142,15 @@ static bool fixupDllMain(COFFLinkerContext &ctx, llvm::object::Archive *file,
144142
}
145143

146144
ArchiveFile::ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m)
147-
: InputFile(ctx.symtab, ArchiveKind, m) {}
145+
: InputFile(ctx.symtab, ArchiveKind, m) {
146+
// Parse a MemoryBufferRef as an archive file.
147+
file = CHECK(Archive::create(mb), this);
148+
}
148149

149150
void ArchiveFile::parse() {
150151
COFFLinkerContext &ctx = symtab.ctx;
151152
SymbolTable *archiveSymtab = &symtab;
152153

153-
// Parse a MemoryBufferRef as an archive file.
154-
file = CHECK(Archive::create(mb), this);
155-
156154
// Try to read symbols from ECSYMBOLS section on ARM64EC.
157155
if (ctx.symtab.isEC()) {
158156
iterator_range<Archive::symbol_iterator> symbols =
@@ -168,56 +166,79 @@ void ArchiveFile::parse() {
168166
// be either a native-only ARM64 or x86_64 archive. Check the machine type
169167
// of the object containing a symbol to determine which symbol table to
170168
// use.
171-
Archive::symbol_iterator sym = file->symbol_begin();
172-
if (sym != file->symbol_end()) {
173-
MachineTypes machine = IMAGE_FILE_MACHINE_UNKNOWN;
174-
Archive::Child child =
175-
CHECK(sym->getMember(),
176-
file->getFileName() +
177-
": could not get the buffer for a child of the archive");
178-
MemoryBufferRef mb = CHECK(
179-
child.getMemoryBufferRef(),
180-
file->getFileName() +
181-
": could not get the buffer for a child buffer of the archive");
182-
switch (identify_magic(mb.getBuffer())) {
183-
case file_magic::coff_object: {
184-
std::unique_ptr<COFFObjectFile> obj =
185-
CHECK(COFFObjectFile::create(mb),
186-
check(child.getName()) + ":" + ": not a valid COFF file");
187-
machine = MachineTypes(obj->getMachine());
188-
break;
189-
}
190-
case file_magic::coff_import_library:
191-
machine = MachineTypes(COFFImportFile(mb).getMachine());
192-
break;
193-
case file_magic::bitcode: {
194-
std::unique_ptr<lto::InputFile> obj =
195-
check(lto::InputFile::create(mb));
196-
machine = BitcodeFile::getMachineType(obj.get());
197-
break;
198-
}
199-
default:
200-
break;
201-
}
169+
MachineTypes machine = getMachineType();
170+
if (machine != IMAGE_FILE_MACHINE_UNKNOWN)
202171
archiveSymtab = &ctx.getSymtab(machine);
203-
}
204172
}
205173
}
206174

207-
// Read the symbol table to construct Lazy objects.
208175
bool skipDllMain = false;
176+
StringRef mangledDllMain, impMangledDllMain;
177+
178+
// The calls below will fail if we haven't set the machine type yet. Instead
179+
// of failing, it is preferable to skip this "imported DllMain" check if we
180+
// don't know the machine type at this point.
181+
if (!file->isEmpty() && ctx.config.machine != IMAGE_FILE_MACHINE_UNKNOWN) {
182+
mangledDllMain = archiveSymtab->mangle("DllMain");
183+
impMangledDllMain = uniqueSaver().save("__imp_" + mangledDllMain);
184+
}
185+
186+
// Read the symbol table to construct Lazy objects.
209187
for (const Archive::Symbol &sym : file->symbols()) {
210188
// If an import library provides the DllMain symbol, skip importing it, as
211189
// we should be using our own DllMain, not another DLL's DllMain.
212-
if (sym.getName() == "__imp_DllMain" || sym.getName() == "DllMain" ||
213-
sym.getName() == "_DllMain") {
214-
if (fixupDllMain(ctx, file.get(), sym, skipDllMain))
190+
if (!mangledDllMain.empty() && (sym.getName() == mangledDllMain ||
191+
sym.getName() == impMangledDllMain)) {
192+
if (skipDllMain || fixupDllMain(ctx, file.get(), sym, skipDllMain))
215193
continue;
216194
}
217195
archiveSymtab->addLazyArchive(this, sym);
218196
}
219197
}
220198

199+
MachineTypes ArchiveFile::getMachineType() const {
200+
if (!file)
201+
return IMAGE_FILE_MACHINE_UNKNOWN;
202+
if (file->isEmpty())
203+
return IMAGE_FILE_MACHINE_UNKNOWN;
204+
Archive::symbol_iterator sym = file->symbol_begin();
205+
if (sym != file->symbol_end()) {
206+
Expected<Archive::Child> child = sym->getMember();
207+
if (!child) {
208+
consumeError(child.takeError());
209+
return IMAGE_FILE_MACHINE_UNKNOWN;
210+
}
211+
Expected<MemoryBufferRef> mb = child->getMemoryBufferRef();
212+
if (!mb) {
213+
consumeError(mb.takeError());
214+
return IMAGE_FILE_MACHINE_UNKNOWN;
215+
}
216+
switch (identify_magic(mb->getBuffer())) {
217+
case file_magic::coff_object: {
218+
Expected<std::unique_ptr<COFFObjectFile>> obj =
219+
COFFObjectFile::create(*mb);
220+
if (!obj) {
221+
consumeError(obj.takeError());
222+
return IMAGE_FILE_MACHINE_UNKNOWN;
223+
}
224+
return MachineTypes((*obj)->getMachine());
225+
break;
226+
}
227+
case file_magic::coff_import_library:
228+
return MachineTypes(COFFImportFile(*mb).getMachine());
229+
break;
230+
case file_magic::bitcode: {
231+
std::unique_ptr<lto::InputFile> obj = check(lto::InputFile::create(*mb));
232+
return BitcodeFile::getMachineType(obj.get());
233+
break;
234+
}
235+
default:
236+
break;
237+
}
238+
}
239+
return IMAGE_FILE_MACHINE_UNKNOWN;
240+
}
241+
221242
// Returns a buffer pointing to a member file containing a given symbol.
222243
void ArchiveFile::addMember(const Archive::Symbol &sym) {
223244
const Archive::Child &c =

lld/COFF/InputFiles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class ArchiveFile : public InputFile {
121121
explicit ArchiveFile(COFFLinkerContext &ctx, MemoryBufferRef m);
122122
static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
123123
void parse() override;
124+
MachineTypes getMachineType() const override;
124125

125126
// Enqueues an archive member load for the given symbol. If we've already
126127
// enqueued a load for the same archive member, this function does nothing,

lld/test/COFF/implib-machine.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
# RUN: llvm-mc -triple x86_64-windows-msvc %t.dir/test.s -filetype=obj -o %t.dir/test64.obj
77

88
# RUN: not lld-link -dll -noentry -out:%t32.dll %t.dir/test32.obj %t.dir/test64.lib 2>&1 | FileCheck --check-prefix=ERR32 %s
9-
# ERR32: error: test64.lib(test.dll): machine type x64 conflicts with x86
9+
# ERR32: error: {{.*[/\\]}}test64.lib: machine type x64 conflicts with x86
1010

1111
# RUN: not lld-link -dll -noentry -out:%t64.dll %t.dir/test64.obj %t.dir/test32.lib 2>&1 | FileCheck --check-prefix=ERR64 %s
12-
# ERR64: error: test32.lib(test.dll): machine type x86 conflicts with x64
12+
# ERR64: error: {{.*[/\\]}}test32.lib: machine type x86 conflicts with x64
1313

1414
#--- test.s
1515
.def @feat.00;

lld/test/COFF/imported-dllmain-i386.test

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ DISASM: DLL Name: b.dll
2525
DISASM-NOT: DllMain
2626
DISASM: bar
2727
DISASM: Disassembly of section .text:
28-
DISASM-EMPTY:
29-
DISASM-NEXT: b0 01 movb $0x1, %al
28+
DISASM: b0 01 movb $0x1, %al
3029
DISASM-NEXT: c3 retl
3130

3231
#--- a.s

0 commit comments

Comments
 (0)