[lld] r196262 - [PECOFF] Implement IMAGE_REL_I386_{SECTION, SECREL} relocations.
Rui Ueyama
ruiu at google.com
Tue Dec 3 01:18:31 PST 2013
Author: ruiu
Date: Tue Dec 3 03:18:31 2013
New Revision: 196262
URL: http://llvm.org/viewvc/llvm-project?rev=196262&view=rev
Log:
[PECOFF] Implement IMAGE_REL_I386_{SECTION,SECREL} relocations.
These relocations are used in .debug section.
Modified:
lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
lld/trunk/test/pecoff/Inputs/reloc.obj.yaml
lld/trunk/test/pecoff/reloc.test
Modified: lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/PECOFFLinkingContext.cpp Tue Dec 3 03:18:31 2013
@@ -180,6 +180,8 @@ PECOFFLinkingContext::relocKindFromStrin
LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
LLD_CASE(IMAGE_REL_I386_DIR32)
LLD_CASE(IMAGE_REL_I386_DIR32NB)
+ LLD_CASE(IMAGE_REL_I386_SECTION)
+ LLD_CASE(IMAGE_REL_I386_SECREL)
LLD_CASE(IMAGE_REL_I386_REL32)
.Default(-1);
#undef LLD_CASE
@@ -198,6 +200,8 @@ PECOFFLinkingContext::stringFromRelocKin
LLD_CASE(IMAGE_REL_I386_ABSOLUTE)
LLD_CASE(IMAGE_REL_I386_DIR32)
LLD_CASE(IMAGE_REL_I386_DIR32NB)
+ LLD_CASE(IMAGE_REL_I386_SECTION)
+ LLD_CASE(IMAGE_REL_I386_SECREL)
LLD_CASE(IMAGE_REL_I386_REL32)
#undef LLD_CASE
}
Modified: lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp Tue Dec 3 03:18:31 2013
@@ -195,6 +195,7 @@ public:
void applyRelocations(uint8_t *fileBuffer,
std::map<const Atom *, uint64_t> &atomRva,
+ std::vector<uint64_t> §ionRva,
uint64_t imageBaseAddress);
void printAtomAddresses(uint64_t baseAddr);
void addBaseRelocations(std::vector<uint64_t> &relocSites);
@@ -505,16 +506,18 @@ void AtomChunk::write(uint8_t *fileBuffe
void AtomChunk::applyRelocations(uint8_t *fileBuffer,
std::map<const Atom *, uint64_t> &atomRva,
+ std::vector<uint64_t> §ionRva,
uint64_t imageBaseAddress) {
for (const auto *layout : _atomLayouts) {
const DefinedAtom *atom = cast<DefinedAtom>(layout->_atom);
for (const Reference *ref : *atom) {
- auto relocSite = reinterpret_cast<ulittle32_t *>(
+ auto relocSite32 = reinterpret_cast<ulittle32_t *>(
fileBuffer + layout->_fileOffset + ref->offsetInAtom());
+ auto relocSite16 = reinterpret_cast<ulittle16_t *>(relocSite32);
uint64_t targetAddr = atomRva[ref->target()];
// Also account for whatever offset is already stored at the relocation
// site.
- targetAddr += *relocSite;
+ targetAddr += *relocSite32;
// Skip if this reference is not for relocation.
if (ref->kind() < lld::Reference::kindTargetLow)
@@ -526,19 +529,42 @@ void AtomChunk::applyRelocations(uint8_t
break;
case llvm::COFF::IMAGE_REL_I386_DIR32:
// Set target's 32-bit VA.
- *relocSite = targetAddr + imageBaseAddress;
+ *relocSite32 = targetAddr + imageBaseAddress;
break;
case llvm::COFF::IMAGE_REL_I386_DIR32NB:
// Set target's 32-bit RVA.
- *relocSite = targetAddr;
+ *relocSite32 = targetAddr;
break;
case llvm::COFF::IMAGE_REL_I386_REL32: {
// Set 32-bit relative address of the target. This relocation is
// usually used for relative branch or call instruction.
uint32_t disp = atomRva[atom] + ref->offsetInAtom() + 4;
- *relocSite = targetAddr - disp;
+ *relocSite32 = targetAddr - disp;
break;
}
+ case llvm::COFF::IMAGE_REL_I386_SECTION: {
+ // The 16-bit section index that contains the target symbol.
+ uint16_t i = 1;
+ for (uint64_t rva : sectionRva) {
+ if (targetAddr < rva) {
+ *relocSite16 = i;
+ break;
+ }
+ ++i;
+ }
+ break;
+ }
+ case llvm::COFF::IMAGE_REL_I386_SECREL:
+ // The 32-bit relative address from the beginning of the section that
+ // contains the target symbol.
+ for (int i = 0, e = sectionRva.size(); i < e; ++i) {
+ if (i == e - 1 ||
+ (sectionRva[i] <= targetAddr && targetAddr <= sectionRva[i + 1])) {
+ *relocSite32 = targetAddr - sectionRva[i];
+ break;
+ }
+ }
+ break;
default:
llvm_unreachable("Unsupported relocation kind");
}
@@ -860,6 +886,9 @@ private:
// The map from defined atoms to its RVAs. Will be used for relocation.
std::map<const Atom *, uint64_t> atomRva;
+
+ // List of section RVAs. Will be used for relocation.
+ std::vector<uint64_t> sectionRva;
};
StringRef customSectionName(const DefinedAtom *atom) {
@@ -930,11 +959,13 @@ void ExecutableWriter::build(const File
SectionChunk *text = nullptr;
SectionChunk *data = nullptr;
+ std::vector<SectionChunk *> sectionChunks;
for (auto i : atoms) {
StringRef sectionName = i.first;
std::vector<const DefinedAtom *> &contents = i.second;
auto *section = new GenericSectionChunk(_PECOFFLinkingContext, sectionName,
contents);
+ sectionChunks.push_back(section);
addSectionChunk(section, sectionTable);
if (!text && sectionName == ".text")
@@ -961,6 +992,9 @@ void ExecutableWriter::build(const File
setImageSizeOnDisk();
+ for (SectionChunk *p : sectionChunks)
+ sectionRva.push_back(p->getVirtualAddress());
+
// Now that we know the size and file offset of sections. Set the file
// header accordingly.
peHeader->setSizeOfCode(calcSizeOfCode());
@@ -1005,7 +1039,7 @@ error_code ExecutableWriter::writeFile(c
void ExecutableWriter::applyAllRelocations(uint8_t *bufferStart) {
for (auto &cp : _chunks)
if (AtomChunk *chunk = dyn_cast<AtomChunk>(&*cp))
- chunk->applyRelocations(bufferStart, atomRva,
+ chunk->applyRelocations(bufferStart, atomRva, sectionRva,
_PECOFFLinkingContext.getBaseAddress());
}
Modified: lld/trunk/test/pecoff/Inputs/reloc.obj.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/Inputs/reloc.obj.yaml?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/test/pecoff/Inputs/reloc.obj.yaml (original)
+++ lld/trunk/test/pecoff/Inputs/reloc.obj.yaml Tue Dec 3 03:18:31 2013
@@ -6,15 +6,21 @@ sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 16
- SectionData: 5589E583EC14C745FC00000000C744240C00000000C744240807000000C744240400000000C7042400000000FF150000000083EC1031C083C4145DC3
+ SectionData: 68000000006800000000680000000068000000006800000000
Relocations:
- - VirtualAddress: 25
+ - VirtualAddress: 1
+ SymbolName: _message
+ Type: IMAGE_REL_I386_SECTION
+ - VirtualAddress: 6
+ SymbolName: _message
+ Type: IMAGE_REL_I386_SECREL
+ - VirtualAddress: 11
SymbolName: .data
Type: IMAGE_REL_I386_DIR32
- - VirtualAddress: 33
+ - VirtualAddress: 16
SymbolName: .data
Type: IMAGE_REL_I386_DIR32
- - VirtualAddress: 46
+ - VirtualAddress: 21
SymbolName: __imp__MessageBoxA at 16
Type: IMAGE_REL_I386_DIR32
- Name: .data
@@ -44,6 +50,12 @@ symbols:
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_FUNCTION
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: _message
+ Value: 5
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: __imp__MessageBoxA at 16
Value: 0
SectionNumber: 0
Modified: lld/trunk/test/pecoff/reloc.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/pecoff/reloc.test?rev=196262&r1=196261&r2=196262&view=diff
==============================================================================
--- lld/trunk/test/pecoff/reloc.test (original)
+++ lld/trunk/test/pecoff/reloc.test Tue Dec 3 03:18:31 2013
@@ -1,40 +1,11 @@
# RUN: yaml2obj %p/Inputs/reloc.obj.yaml > %t.obj
#
-# RUN: llvm-objdump -d %t.obj | FileCheck -check-prefix=BEFORE %s
-#
# RUN: lld -flavor link /out:%t1 /subsystem:console /force /opt:noref \
-# RUN: -- %t.obj && llvm-objdump -d %t1 | FileCheck -check-prefix=AFTER %s
-
-BEFORE: Disassembly of section .text:
-BEFORE: _main:
-BEFORE: 0: 55
-BEFORE: 1: 89 e5
-BEFORE: 3: 83 ec 14
-BEFORE: 6: c7 45 fc 00 00 00 00
-BEFORE: d: c7 44 24 0c 00 00 00 00
-BEFORE: 15: c7 44 24 08 07 00 00 00
-BEFORE: 1d: c7 44 24 04 00 00 00 00
-BEFORE: 25: c7 04 24 00 00 00 00
-BEFORE: 2c: ff 15 00 00 00 00
-BEFORE: 32: 83 ec 10
-BEFORE: 35: 31 c0
-BEFORE: 37: 83 c4 14
-BEFORE: 3a: 5d
-BEFORE: 3b: c3
+# RUN: -- %t.obj && llvm-objdump -d %t1 | FileCheck %s
-AFTER: Disassembly of section .text:
-AFTER: .text:
-AFTER: pushl %ebp
-AFTER: movl %esp, %ebp
-AFTER: subl $20, %esp
-AFTER: movl $0, -4(%ebp)
-AFTER: movl $0, 12(%esp)
-AFTER: movl $4198407, 8(%esp)
-AFTER: movl $4198400, 4(%esp)
-AFTER: movl $0, (%esp)
-AFTER: calll *4194304
-AFTER: subl $16, %esp
-AFTER: xorl %eax, %eax
-AFTER: addl $20, %esp
-AFTER: popl %ebp
-AFTER: ret
+CHECK: .text:
+CHECK: 2000: 68 02 00 00 00
+CHECK: 2005: 68 05 00 00 00
+CHECK: 200a: 68 00 10 40 00
+CHECK: 200f: 68 00 10 40 00
+CHECK: 2014: 68 00 00 40 00
More information about the llvm-commits
mailing list