Skip to content

Commit 88e0f92

Browse files
committed
COFF: Fix a bug of __imp_ symbol.
The change I made in r240620 was not correct. If a symbol foo is defined, and if you use __imp_foo, __imp_foo symbol is automatically defined as a pointer (not just an alias) to foo. Now that we need to create a chunk for automatically-created symbols. I defined LocalImportChunk class for them. llvm-svn: 240622
1 parent 0c36c27 commit 88e0f92

File tree

8 files changed

+71
-6
lines changed

8 files changed

+71
-6
lines changed

lld/COFF/Chunks.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ BaserelChunk::BaserelChunk(uint32_t Page, uint32_t *Begin, uint32_t *End) {
253253
}
254254
}
255255

256+
void LocalImportChunk::writeTo(uint8_t *Buf) {
257+
write32le(Buf + FileOff, Sym->getRVA());
258+
}
259+
256260
void BaserelChunk::writeTo(uint8_t *Buf) {
257261
memcpy(Buf + FileOff, Data.data(), Data.size());
258262
}

lld/COFF/Chunks.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,18 @@ class ImportThunkChunk : public Chunk {
211211
Defined *ImpSymbol;
212212
};
213213

214+
// Windows-specific.
215+
// See comments for DefinedLocalImport class.
216+
class LocalImportChunk : public Chunk {
217+
public:
218+
explicit LocalImportChunk(Defined *S) : Sym(S) {}
219+
size_t getSize() const override { return 4; }
220+
void writeTo(uint8_t *Buf) override;
221+
222+
private:
223+
Defined *Sym;
224+
};
225+
214226
// Windows-specific.
215227
// This class represents a block in .reloc section.
216228
// See the PE/COFF spec 5.6 for details.

lld/COFF/SymbolTable.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ bool SymbolTable::reportRemainingUndefines() {
8585
// This odd rule is for compatibility with MSVC linker.
8686
if (Name.startswith("__imp_")) {
8787
if (Defined *Imp = find(Name.substr(strlen("__imp_")))) {
88-
Sym->Body = Imp;
88+
auto *S = new (Alloc) DefinedLocalImport(Name, Imp);
89+
LocalImportChunks.push_back(S->getChunk());
90+
Sym->Body = S;
8991
continue;
9092
}
9193
}

lld/COFF/SymbolTable.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ class SymbolTable {
8080
// Rename From -> To in the symbol table.
8181
std::error_code rename(StringRef From, StringRef To);
8282

83+
// A list of chunks which to be added to .rdata.
84+
std::vector<Chunk *> LocalImportChunks;
85+
8386
private:
8487
std::error_code resolve(SymbolBody *Body);
8588
std::error_code resolveLazy(StringRef Name);

lld/COFF/Symbols.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class SymbolBody {
4949
DefinedAbsoluteKind,
5050
DefinedImportDataKind,
5151
DefinedImportThunkKind,
52+
DefinedLocalImportKind,
5253
DefinedCommonKind,
5354
DefinedCOMDATKind,
5455
DefinedRegularKind,
@@ -315,6 +316,30 @@ class DefinedImportThunk : public Defined {
315316
ImportThunkChunk Data;
316317
};
317318

319+
// If you have a symbol "__imp_foo" in your object file, a symbol name
320+
// "foo" becomes automatically available as a pointer to "__imp_foo".
321+
// This class is for such automatically-created symbols.
322+
// Yes, this is an odd feature. We didn't intend to implement that.
323+
// This is here just for compatibility with MSVC.
324+
class DefinedLocalImport : public Defined {
325+
public:
326+
DefinedLocalImport(StringRef N, Defined *S)
327+
: Defined(DefinedLocalImportKind), Name(N), Data(S) {}
328+
329+
static bool classof(const SymbolBody *S) {
330+
return S->kind() == DefinedLocalImportKind;
331+
}
332+
333+
StringRef getName() override { return Name; }
334+
uint64_t getRVA() override { return Data.getRVA(); }
335+
uint64_t getFileOff() override { return Data.getFileOff(); }
336+
Chunk *getChunk() { return &Data; }
337+
338+
private:
339+
StringRef Name;
340+
LocalImportChunk Data;
341+
};
342+
318343
class DefinedBitcode : public Defined {
319344
public:
320345
DefinedBitcode(StringRef N, bool R)

lld/COFF/Writer.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ std::error_code Writer::write(StringRef OutputPath) {
4343
markLive();
4444
dedupCOMDATs();
4545
createSections();
46+
createMiscChunks();
4647
createImportTables();
4748
createExportTable();
4849
if (Config->Relocatable)
@@ -169,6 +170,14 @@ void Writer::createSections() {
169170
}
170171
}
171172

173+
void Writer::createMiscChunks() {
174+
if (Symtab->LocalImportChunks.empty())
175+
return;
176+
OutputSection *Sec = createSection(".rdata");
177+
for (Chunk *C : Symtab->LocalImportChunks)
178+
Sec->addChunk(C);
179+
}
180+
172181
// Create .idata section for the DLL-imported symbol table.
173182
// The format of this section is inherently Windows-specific.
174183
// IdataContents class abstracted away the details for us,

lld/COFF/Writer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Writer {
8181
void markLive();
8282
void dedupCOMDATs();
8383
void createSections();
84+
void createMiscChunks();
8485
void createImportTables();
8586
void createExportTable();
8687
void assignAddresses();

lld/test/COFF/locally-imported.test

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# RUN: yaml2obj < %s > %t.obj
22
# RUN: lld -flavor link2 /out:%t.exe %t.obj
3+
# RUN: llvm-objdump -s %t.exe | FileCheck %s
34

4-
# The linker automatically removes __imp_ prefix if it helps to resolve all symbols.
5+
# CHECK: Contents of section .text:
6+
# CHECK-NEXT: 1000 00200000
7+
8+
# CHECK: Contents of section .rdata:
9+
# CHECK-NEXT: 2000 04100000
510

611
---
712
header:
@@ -11,7 +16,11 @@ sections:
1116
- Name: .text
1217
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
1318
Alignment: 4
14-
SectionData: B82A000000C3
19+
SectionData: 00000000
20+
Relocations:
21+
- VirtualAddress: 0
22+
SymbolName: __imp_mainCRTStartup
23+
Type: IMAGE_REL_AMD64_ADDR32NB
1524
symbols:
1625
- Name: .text
1726
Value: 0
@@ -20,14 +29,14 @@ symbols:
2029
ComplexType: IMAGE_SYM_DTYPE_NULL
2130
StorageClass: IMAGE_SYM_CLASS_STATIC
2231
SectionDefinition:
23-
Length: 6
24-
NumberOfRelocations: 0
32+
Length: 4
33+
NumberOfRelocations: 1
2534
NumberOfLinenumbers: 0
2635
CheckSum: 0
2736
Number: 0
2837
Selection: IMAGE_COMDAT_SELECT_ANY
2938
- Name: mainCRTStartup
30-
Value: 0
39+
Value: 4
3140
SectionNumber: 1
3241
SimpleType: IMAGE_SYM_TYPE_NULL
3342
ComplexType: IMAGE_SYM_DTYPE_FUNCTION

0 commit comments

Comments
 (0)