[lld] r240622 - COFF: Fix a bug of __imp_ symbol.
Rui Ueyama
ruiu at google.com
Wed Jun 24 20:31:48 PDT 2015
Author: ruiu
Date: Wed Jun 24 22:31:47 2015
New Revision: 240622
URL: http://llvm.org/viewvc/llvm-project?rev=240622&view=rev
Log:
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.
Modified:
lld/trunk/COFF/Chunks.cpp
lld/trunk/COFF/Chunks.h
lld/trunk/COFF/SymbolTable.cpp
lld/trunk/COFF/SymbolTable.h
lld/trunk/COFF/Symbols.h
lld/trunk/COFF/Writer.cpp
lld/trunk/COFF/Writer.h
lld/trunk/test/COFF/locally-imported.test
Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Wed Jun 24 22:31:47 2015
@@ -253,6 +253,10 @@ BaserelChunk::BaserelChunk(uint32_t Page
}
}
+void LocalImportChunk::writeTo(uint8_t *Buf) {
+ write32le(Buf + FileOff, Sym->getRVA());
+}
+
void BaserelChunk::writeTo(uint8_t *Buf) {
memcpy(Buf + FileOff, Data.data(), Data.size());
}
Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Wed Jun 24 22:31:47 2015
@@ -212,6 +212,18 @@ private:
};
// 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.
class BaserelChunk : public Chunk {
Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Wed Jun 24 22:31:47 2015
@@ -85,7 +85,9 @@ bool SymbolTable::reportRemainingUndefin
// 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;
}
}
Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Wed Jun 24 22:31:47 2015
@@ -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);
Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Wed Jun 24 22:31:47 2015
@@ -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)
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Jun 24 22:31:47 2015
@@ -43,6 +43,7 @@ std::error_code Writer::write(StringRef
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,
Modified: lld/trunk/COFF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.h?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.h (original)
+++ lld/trunk/COFF/Writer.h Wed Jun 24 22:31:47 2015
@@ -81,6 +81,7 @@ private:
void markLive();
void dedupCOMDATs();
void createSections();
+ void createMiscChunks();
void createImportTables();
void createExportTable();
void assignAddresses();
Modified: lld/trunk/test/COFF/locally-imported.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/locally-imported.test?rev=240622&r1=240621&r2=240622&view=diff
==============================================================================
--- lld/trunk/test/COFF/locally-imported.test (original)
+++ lld/trunk/test/COFF/locally-imported.test Wed Jun 24 22:31:47 2015
@@ -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
More information about the llvm-commits
mailing list