PECOFF: Fix I386_DIR32 relocation to an absolute symbol

Previously, we incorrectly added the image base address to an absolute
symbol address (that calculation doesn't make any sense) if an
IMAGE_REL_I386_DIR32 relocation is applied to an absolute symbol.

This patch fixes the issue. With this fix, we can link Bochs using LLD.
(Choosing Bochs has no special meaining -- I just picked it up as a
test program and found it didn't work.) This also fixes one of the
issues we currently have to link Chromium using LLD.

llvm-svn: 228279
This commit is contained in:
Rui Ueyama 2015-02-05 07:22:53 +00:00
parent f9ec0d1ea5
commit df7d133cdf
4 changed files with 31 additions and 5 deletions

View File

@ -647,7 +647,8 @@ void AtomChunk::applyRelocationsX86(uint8_t *buffer,
auto relocSite32 = reinterpret_cast<ulittle32_t *>( auto relocSite32 = reinterpret_cast<ulittle32_t *>(
buffer + layout->_fileOffset + ref->offsetInAtom()); buffer + layout->_fileOffset + ref->offsetInAtom());
auto relocSite16 = reinterpret_cast<ulittle16_t *>(relocSite32); auto relocSite16 = reinterpret_cast<ulittle16_t *>(relocSite32);
uint64_t targetAddr = atomRva[ref->target()]; const Atom *target = ref->target();
uint64_t targetAddr = atomRva[target];
// Also account for whatever offset is already stored at the relocation // Also account for whatever offset is already stored at the relocation
// site. // site.
switch (ref->kindValue()) { switch (ref->kindValue()) {
@ -656,7 +657,10 @@ void AtomChunk::applyRelocationsX86(uint8_t *buffer,
break; break;
case llvm::COFF::IMAGE_REL_I386_DIR32: case llvm::COFF::IMAGE_REL_I386_DIR32:
// Set target's 32-bit VA. // Set target's 32-bit VA.
*relocSite32 += targetAddr + imageBaseAddress; if (auto *abs = dyn_cast<AbsoluteAtom>(target))
*relocSite32 += abs->value();
else
*relocSite32 += targetAddr + imageBaseAddress;
break; break;
case llvm::COFF::IMAGE_REL_I386_DIR32NB: case llvm::COFF::IMAGE_REL_I386_DIR32NB:
// Set target's 32-bit RVA. // Set target's 32-bit RVA.

View File

@ -0,0 +1,11 @@
header:
Machine: IMAGE_FILE_MACHINE_I386
Characteristics: []
sections:
symbols:
- Name: _abs_value
Value: 0xDEADBEEF
SectionNumber: -1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL

View File

@ -6,7 +6,7 @@ sections:
- Name: .text - Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16 Alignment: 16
SectionData: 68000000006800000000680000000068000000006800000000 SectionData: 680000000068000000006800000000680000000068000000006800000000
Relocations: Relocations:
- VirtualAddress: 1 - VirtualAddress: 1
SymbolName: _message SymbolName: _message
@ -23,6 +23,9 @@ sections:
- VirtualAddress: 21 - VirtualAddress: 21
SymbolName: __imp__MessageBoxA@16 SymbolName: __imp__MessageBoxA@16
Type: IMAGE_REL_I386_DIR32 Type: IMAGE_REL_I386_DIR32
- VirtualAddress: 26
SymbolName: _abs_value
Type: IMAGE_REL_I386_DIR32
- Name: .data - Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4 Alignment: 4
@ -70,4 +73,10 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: _abs_value
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
... ...

View File

@ -1,9 +1,10 @@
# REQUIRES: x86 # REQUIRES: x86
# RUN: yaml2obj %p/Inputs/reloc.obj.yaml > %t.obj # RUN: yaml2obj %p/Inputs/reloc.obj.yaml > %t1.obj
# RUN: yaml2obj %p/Inputs/abs.obj.yaml > %t2.obj
# #
# RUN: lld -flavor link /out:%t.exe /subsystem:console /force /opt:noref \ # RUN: lld -flavor link /out:%t.exe /subsystem:console /force /opt:noref \
# RUN: -- %t.obj # RUN: -- %t1.obj %t2.obj
# RUN: llvm-objdump -d %t.exe | FileCheck %s # RUN: llvm-objdump -d %t.exe | FileCheck %s
CHECK: .text: CHECK: .text:
@ -12,3 +13,4 @@ CHECK: 3005: 68 05 00 00 00
CHECK: 300a: 68 00 10 40 00 CHECK: 300a: 68 00 10 40 00
CHECK: 300f: 68 00 10 40 00 CHECK: 300f: 68 00 10 40 00
CHECK: 3014: 68 00 20 40 00 CHECK: 3014: 68 00 20 40 00
CHECK: 3019: 68 ef be ad de