aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaleem Abdulrasool <compnerd@compnerd.org>2015-01-01 03:11:53 +0000
committerSaleem Abdulrasool <compnerd@compnerd.org>2015-01-01 03:11:53 +0000
commit0d01e4be2a89e7a14f75d8d5fb25f0411b936c7d (patch)
treedbdb2b0724d3c71a09235465555d998263a94075
parentd533ac69d6832315ab80e3bf23575582d1306f3e (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.cpp29
-rw-r--r--test/pecoff/Inputs/armnt-addr32.obj.yaml39
-rw-r--r--test/pecoff/Inputs/armnt-addr32.s18
-rw-r--r--test/pecoff/armnt-addr32.test11
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> &sectionRva,
- 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
+