summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2015-02-20 03:35:59 +0000
committerRui Ueyama <ruiu@google.com>2015-02-20 03:35:59 +0000
commit11f42aa2854bf27a7eb38e3fbfe1fe0f5a24a24a (patch)
tree843036343eb477d73efd4705e76ec69ee8673b95
parentad6eb127c9e4c48cfdff1f47e5efe83255b15565 (diff)
downloadbcm5719-llvm-11f42aa2854bf27a7eb38e3fbfe1fe0f5a24a24a.tar.gz
bcm5719-llvm-11f42aa2854bf27a7eb38e3fbfe1fe0f5a24a24a.zip
PECOFF: Fix base relocation for ImageBase.
This is yet another edge case of base relocation for symbols. Absolute symbols are in general not target of base relocation because absolute atom is a way to point to a specific memory location. In r229816, I removed entries for absolute atoms from the base relocation table (so that they won't be fixed by the loader). However, there was one exception -- ImageBase. ImageBase points to the start address of the current image in memory. That needs to be fixed up at load time. This patch is to treat the symbol in a special manner. llvm-svn: 229961
-rw-r--r--lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp8
-rw-r--r--lld/test/pecoff/Inputs/basereloc.obj.yaml11
-rw-r--r--lld/test/pecoff/base-reloc.test12
3 files changed, 27 insertions, 4 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index 8dcfcc142a9..6459084d9e5 100644
--- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -784,7 +784,13 @@ void AtomChunk::addBaseRelocations(BaseRelocationList &relocSites) const {
for (const Reference *ref : *atom) {
if (ref->kindNamespace() != Reference::KindNamespace::COFF)
continue;
- if (isa<AbsoluteAtom>(ref->target()))
+
+ // An absolute symbol points to a fixed location in memory. Their
+ // address should not be fixed at load time. One exception is ImageBase
+ // because that's relative to run-time image base address.
+ if (auto *abs = dyn_cast<AbsoluteAtom>(ref->target()))
+ if (!abs->name().equals("__ImageBase") &&
+ !abs->name().equals("___ImageBase"))
continue;
uint64_t address = layout->_virtualAddr + ref->offsetInAtom();
diff --git a/lld/test/pecoff/Inputs/basereloc.obj.yaml b/lld/test/pecoff/Inputs/basereloc.obj.yaml
index 088e9c83878..34312e5d75b 100644
--- a/lld/test/pecoff/Inputs/basereloc.obj.yaml
+++ b/lld/test/pecoff/Inputs/basereloc.obj.yaml
@@ -6,7 +6,7 @@ sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
- SectionData: B800000000506800000000680000000050E80000000050E800000000
+ SectionData: B800000000506800000000680000000050E80000000050E80000000050E800000000
Relocations:
- VirtualAddress: 0
SymbolName: abs_symbol
@@ -23,6 +23,9 @@ sections:
- VirtualAddress: 24
SymbolName: _ExitProcess@4
Type: IMAGE_REL_I386_REL32
+ - VirtualAddress: 30
+ SymbolName: ___ImageBase
+ Type: IMAGE_REL_I386_DIR32
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
@@ -117,4 +120,10 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: ___ImageBase
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...
diff --git a/lld/test/pecoff/base-reloc.test b/lld/test/pecoff/base-reloc.test
index 867cbcb38bf..54c47a1b59c 100644
--- a/lld/test/pecoff/base-reloc.test
+++ b/lld/test/pecoff/base-reloc.test
@@ -17,6 +17,14 @@ BASEREL-NEXT: Entry {
BASEREL-NEXT: Type: HIGHLOW
BASEREL-NEXT: Address: 0x200C
BASEREL-NEXT: }
+BASEREL-NEXT: Entry {
+BASEREL-NEXT: Type: HIGHLOW
+BASEREL-NEXT: Address: 0x201E
+BASEREL-NEXT: }
+BASEREL-NEXT: Entry {
+BASEREL-NEXT: Type: ABSOLUTE
+BASEREL-NEXT: Address: 0x2000
+BASEREL-NEXT: }
BASEREL-NEXT: ]
NOBASEREL: BaseReloc [
@@ -37,9 +45,9 @@ BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
NOBASEREL-HEADER: IMAGE_FILE_RELOCS_STRIPPED
BASEREL-HEADER: BaseRelocationTableRVA: 0x3000
-BASEREL-HEADER: BaseRelocationTableSize: 0xC
+BASEREL-HEADER: BaseRelocationTableSize: 0x10
BASEREL-HEADER: Name: .reloc (2E 72 65 6C 6F 63 00 00)
-BASEREL-HEADER-NEXT: VirtualSize: 0xC
+BASEREL-HEADER-NEXT: VirtualSize: 0x10
BASEREL-HEADER-NEXT: VirtualAddress: 0x3000
BASEREL-HEADER-NEXT: RawDataSize: 512
BASEREL-HEADER-NEXT: PointerToRawData: 0x600
OpenPOWER on IntegriCloud