diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-01-01 03:11:53 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2015-01-01 03:11:53 +0000 |
commit | 0d01e4be2a89e7a14f75d8d5fb25f0411b936c7d (patch) | |
tree | dbdb2b0724d3c71a09235465555d998263a94075 | |
parent | d533ac69d6832315ab80e3bf23575582d1306f3e (diff) |
ReaderWriter: teach the writer about IMAGE_REL_ARM_ADDR32
This implements the IMAGE_REL_ARM_ADDR32 relocation. There are still a few more
relocation types that need to resolved before lld can even attempt to link a
trivial program for Windows on ARM.
git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@225057 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 29 | ||||
-rw-r--r-- | test/pecoff/Inputs/armnt-addr32.obj.yaml | 39 | ||||
-rw-r--r-- | test/pecoff/Inputs/armnt-addr32.s | 18 | ||||
-rw-r--r-- | test/pecoff/armnt-addr32.test | 11 |
4 files changed, 93 insertions, 4 deletions
diff --git a/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index 06d1c030b..0df42314e 100644 --- a/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -547,10 +547,31 @@ static uint32_t getSectionStartAddr(uint64_t targetAddr, llvm_unreachable("Section missing"); } -void AtomChunk::applyRelocationsARM(uint8_t *buffer, - std::map<const Atom *, uint64_t> &atomRva, - std::vector<uint64_t> §ionRva, - uint64_t imageBaseAddress) { +void AtomChunk::applyRelocationsARM(uint8_t *Buffer, + std::map<const Atom *, uint64_t> &AtomRVA, + std::vector<uint64_t> &SectionRVA, + uint64_t ImageBase) { + Buffer = Buffer + _fileOffset; + for (const auto *Layout : _atomLayouts) { + const DefinedAtom *Atom = cast<DefinedAtom>(Layout->_atom); + for (const Reference *R : *Atom) { + if (R->kindNamespace() != Reference::KindNamespace::COFF) + continue; + + const auto AtomOffset = R->offsetInAtom(); + const auto FileOffset = Layout->_fileOffset; + const auto TargetAddr = AtomRVA[R->target()]; + auto RelocSite32 = + reinterpret_cast<ulittle32_t *>(Buffer + FileOffset + AtomOffset); + + switch (R->kindValue()) { + default: llvm_unreachable("unsupported relocation type"); + case llvm::COFF::IMAGE_REL_ARM_ADDR32: + *RelocSite32 = *RelocSite32 + TargetAddr + ImageBase; + break; + } + } + } } void AtomChunk::applyRelocationsX86(uint8_t *buffer, diff --git a/test/pecoff/Inputs/armnt-addr32.obj.yaml b/test/pecoff/Inputs/armnt-addr32.obj.yaml new file mode 100644 index 000000000..b13026308 --- /dev/null +++ b/test/pecoff/Inputs/armnt-addr32.obj.yaml @@ -0,0 +1,39 @@ +--- +header: + Machine: IMAGE_FILE_MACHINE_ARMNT + Characteristics: [ ] +sections: + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: '0000000000000000' + Relocations: + - VirtualAddress: 4 + SymbolName: i + Type: 1 +symbols: + - Name: .rdata + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 8 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 + - Name: i + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: is + Value: 4 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... diff --git a/test/pecoff/Inputs/armnt-addr32.s b/test/pecoff/Inputs/armnt-addr32.s new file mode 100644 index 000000000..c718e9518 --- /dev/null +++ b/test/pecoff/Inputs/armnt-addr32.s @@ -0,0 +1,18 @@ + +@ static const int i = 0; +@ const int * const is[] = { &i, }; + + .syntax unified + .thumb + .text + + .section .rdata,"rd" + .align 2 # @i +i: + .long 0 # 0x0 + + .global is # @is + .align 2 +is: + .long i + diff --git a/test/pecoff/armnt-addr32.test b/test/pecoff/armnt-addr32.test new file mode 100644 index 000000000..b586bebb2 --- /dev/null +++ b/test/pecoff/armnt-addr32.test @@ -0,0 +1,11 @@ +# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-addr32.obj.yaml +# RUN: llvm-objdump -s %t.obj | FileCheck %s -check-prefix BEFORE +# RUN: lld -flavor link /entry:is /subsystem:console /out:%t.exe %t.obj +# RUN: llvm-objdump -s %t.exe | FileCheck %s -check-prefix AFTER + +BEFORE: Contents of section .rdata: +BEFORE: 0000 00000000 00000000 + +AFTER: Contents of section .rdata: +AFTER: 1000 00000000 00104000 + |