forked from OSchip/llvm-project
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
This commit is contained in:
parent
0c36c27543
commit
88e0f9206b
|
@ -253,6 +253,10 @@ BaserelChunk::BaserelChunk(uint32_t Page, uint32_t *Begin, uint32_t *End) {
|
|||
}
|
||||
}
|
||||
|
||||
void LocalImportChunk::writeTo(uint8_t *Buf) {
|
||||
write32le(Buf + FileOff, Sym->getRVA());
|
||||
}
|
||||
|
||||
void BaserelChunk::writeTo(uint8_t *Buf) {
|
||||
memcpy(Buf + FileOff, Data.data(), Data.size());
|
||||
}
|
||||
|
|
|
@ -211,6 +211,18 @@ private:
|
|||
Defined *ImpSymbol;
|
||||
};
|
||||
|
||||
// Windows-specific.
|
||||
// See comments for DefinedLocalImport class.
|
||||
class LocalImportChunk : public Chunk {
|
||||
public:
|
||||
explicit LocalImportChunk(Defined *S) : Sym(S) {}
|
||||
size_t getSize() const override { return 4; }
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
|
||||
private:
|
||||
Defined *Sym;
|
||||
};
|
||||
|
||||
// Windows-specific.
|
||||
// This class represents a block in .reloc section.
|
||||
// See the PE/COFF spec 5.6 for details.
|
||||
|
|
|
@ -85,7 +85,9 @@ bool SymbolTable::reportRemainingUndefines() {
|
|||
// This odd rule is for compatibility with MSVC linker.
|
||||
if (Name.startswith("__imp_")) {
|
||||
if (Defined *Imp = find(Name.substr(strlen("__imp_")))) {
|
||||
Sym->Body = Imp;
|
||||
auto *S = new (Alloc) DefinedLocalImport(Name, Imp);
|
||||
LocalImportChunks.push_back(S->getChunk());
|
||||
Sym->Body = S;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,6 +80,9 @@ public:
|
|||
// Rename From -> To in the symbol table.
|
||||
std::error_code rename(StringRef From, StringRef To);
|
||||
|
||||
// A list of chunks which to be added to .rdata.
|
||||
std::vector<Chunk *> LocalImportChunks;
|
||||
|
||||
private:
|
||||
std::error_code resolve(SymbolBody *Body);
|
||||
std::error_code resolveLazy(StringRef Name);
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
DefinedAbsoluteKind,
|
||||
DefinedImportDataKind,
|
||||
DefinedImportThunkKind,
|
||||
DefinedLocalImportKind,
|
||||
DefinedCommonKind,
|
||||
DefinedCOMDATKind,
|
||||
DefinedRegularKind,
|
||||
|
@ -315,6 +316,30 @@ private:
|
|||
ImportThunkChunk Data;
|
||||
};
|
||||
|
||||
// If you have a symbol "__imp_foo" in your object file, a symbol name
|
||||
// "foo" becomes automatically available as a pointer to "__imp_foo".
|
||||
// This class is for such automatically-created symbols.
|
||||
// Yes, this is an odd feature. We didn't intend to implement that.
|
||||
// This is here just for compatibility with MSVC.
|
||||
class DefinedLocalImport : public Defined {
|
||||
public:
|
||||
DefinedLocalImport(StringRef N, Defined *S)
|
||||
: Defined(DefinedLocalImportKind), Name(N), Data(S) {}
|
||||
|
||||
static bool classof(const SymbolBody *S) {
|
||||
return S->kind() == DefinedLocalImportKind;
|
||||
}
|
||||
|
||||
StringRef getName() override { return Name; }
|
||||
uint64_t getRVA() override { return Data.getRVA(); }
|
||||
uint64_t getFileOff() override { return Data.getFileOff(); }
|
||||
Chunk *getChunk() { return &Data; }
|
||||
|
||||
private:
|
||||
StringRef Name;
|
||||
LocalImportChunk Data;
|
||||
};
|
||||
|
||||
class DefinedBitcode : public Defined {
|
||||
public:
|
||||
DefinedBitcode(StringRef N, bool R)
|
||||
|
|
|
@ -43,6 +43,7 @@ std::error_code Writer::write(StringRef OutputPath) {
|
|||
markLive();
|
||||
dedupCOMDATs();
|
||||
createSections();
|
||||
createMiscChunks();
|
||||
createImportTables();
|
||||
createExportTable();
|
||||
if (Config->Relocatable)
|
||||
|
@ -169,6 +170,14 @@ void Writer::createSections() {
|
|||
}
|
||||
}
|
||||
|
||||
void Writer::createMiscChunks() {
|
||||
if (Symtab->LocalImportChunks.empty())
|
||||
return;
|
||||
OutputSection *Sec = createSection(".rdata");
|
||||
for (Chunk *C : Symtab->LocalImportChunks)
|
||||
Sec->addChunk(C);
|
||||
}
|
||||
|
||||
// Create .idata section for the DLL-imported symbol table.
|
||||
// The format of this section is inherently Windows-specific.
|
||||
// IdataContents class abstracted away the details for us,
|
||||
|
|
|
@ -81,6 +81,7 @@ private:
|
|||
void markLive();
|
||||
void dedupCOMDATs();
|
||||
void createSections();
|
||||
void createMiscChunks();
|
||||
void createImportTables();
|
||||
void createExportTable();
|
||||
void assignAddresses();
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
# RUN: yaml2obj < %s > %t.obj
|
||||
# RUN: lld -flavor link2 /out:%t.exe %t.obj
|
||||
# RUN: llvm-objdump -s %t.exe | FileCheck %s
|
||||
|
||||
# The linker automatically removes __imp_ prefix if it helps to resolve all symbols.
|
||||
# CHECK: Contents of section .text:
|
||||
# CHECK-NEXT: 1000 00200000
|
||||
|
||||
# CHECK: Contents of section .rdata:
|
||||
# CHECK-NEXT: 2000 04100000
|
||||
|
||||
---
|
||||
header:
|
||||
|
@ -11,7 +16,11 @@ sections:
|
|||
- Name: .text
|
||||
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
|
||||
Alignment: 4
|
||||
SectionData: B82A000000C3
|
||||
SectionData: 00000000
|
||||
Relocations:
|
||||
- VirtualAddress: 0
|
||||
SymbolName: __imp_mainCRTStartup
|
||||
Type: IMAGE_REL_AMD64_ADDR32NB
|
||||
symbols:
|
||||
- Name: .text
|
||||
Value: 0
|
||||
|
@ -20,14 +29,14 @@ symbols:
|
|||
ComplexType: IMAGE_SYM_DTYPE_NULL
|
||||
StorageClass: IMAGE_SYM_CLASS_STATIC
|
||||
SectionDefinition:
|
||||
Length: 6
|
||||
NumberOfRelocations: 0
|
||||
Length: 4
|
||||
NumberOfRelocations: 1
|
||||
NumberOfLinenumbers: 0
|
||||
CheckSum: 0
|
||||
Number: 0
|
||||
Selection: IMAGE_COMDAT_SELECT_ANY
|
||||
- Name: mainCRTStartup
|
||||
Value: 0
|
||||
Value: 4
|
||||
SectionNumber: 1
|
||||
SimpleType: IMAGE_SYM_TYPE_NULL
|
||||
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
|
||||
|
|
Loading…
Reference in New Issue