From 434fedb8d8eec0d5d9e904fcb9a9f1c8d2a8513b Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 2 Jan 2015 18:51:59 +0000 Subject: [PATCH] ReaderWriter: teach the writer about IMAGE_REL_ARM_BRANCH24T This adds support for IMAGE_REL_ARM_BRANCH24T relocations. Similar to the IMAGE_REL_ARM_BLX32T relocation, this relocation requires munging an instruction. The instruction encoding is quite similar, allowing us to reuse the same munging implementation. This is needed by the entry point stubs for modules provided by MSVCRT. llvm-svn: 225082 --- lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 8 ++++- lld/test/pecoff/Inputs/armnt-branch24t.obj.yaml | 39 +++++++++++++++++++++++++ lld/test/pecoff/Inputs/armnt-branch24t.s | 27 +++++++++++++++++ lld/test/pecoff/armnt-branch24t.test | 18 ++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 lld/test/pecoff/Inputs/armnt-branch24t.obj.yaml create mode 100644 lld/test/pecoff/Inputs/armnt-branch24t.s create mode 100644 lld/test/pecoff/armnt-branch24t.test diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index ec8a83b..5cd892f 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -561,10 +561,12 @@ static void applyThumbMoveImmediate(ulittle16_t *mov, uint16_t imm) { static void applyThumbBranchImmediate(ulittle16_t *bl, int32_t imm) { // BL(T1): |11110|S|imm10|11|J1|1|J2|imm11| // imm32 = sext S:I1:I2:imm10:imm11:'0' + // B.W(T4): |11110|S|imm10|10|J1|1|J2|imm11| + // imm32 = sext S:I1:I2:imm10:imm11:'0' // // I1 = ~(J1 ^ S), I2 = ~(J2 ^ S) - assert((~abs(imm) & (-1 << 24)) && "bl out of range"); + assert((~abs(imm) & (-1 << 24)) && "bl/b.w out of range"); uint32_t S = (imm < 0 ? 1 : 0); uint32_t J1 = ((~imm & 0x00800000) >> 23) ^ S; @@ -602,6 +604,10 @@ void AtomChunk::applyRelocationsARM(uint8_t *Buffer, applyThumbMoveImmediate(&RelocSite16[0], (TargetAddr + ImageBase) >> 0); applyThumbMoveImmediate(&RelocSite16[2], (TargetAddr + ImageBase) >> 16); break; + case llvm::COFF::IMAGE_REL_ARM_BRANCH24T: + applyThumbBranchImmediate(RelocSite16, + TargetAddr - AtomRVA[Atom] - AtomOffset - 4); + break; case llvm::COFF::IMAGE_REL_ARM_BLX23T: applyThumbBranchImmediate(RelocSite16, TargetAddr - AtomRVA[Atom] - AtomOffset - 4); diff --git a/lld/test/pecoff/Inputs/armnt-branch24t.obj.yaml b/lld/test/pecoff/Inputs/armnt-branch24t.obj.yaml new file mode 100644 index 0000000..02815a49 --- /dev/null +++ b/lld/test/pecoff/Inputs/armnt-branch24t.obj.yaml @@ -0,0 +1,39 @@ +--- +header: + Machine: IMAGE_FILE_MACHINE_ARMNT + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: 704700BF202000F000B8 + Relocations: + - VirtualAddress: 6 + SymbolName: identity + Type: 20 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 10 + NumberOfRelocations: 1 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 1 + - Name: identity + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: function + Value: 4 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/lld/test/pecoff/Inputs/armnt-branch24t.s b/lld/test/pecoff/Inputs/armnt-branch24t.s new file mode 100644 index 0000000..5fcd1a4 --- /dev/null +++ b/lld/test/pecoff/Inputs/armnt-branch24t.s @@ -0,0 +1,27 @@ + +@ int ___declspec(noinline) identity(int i) { return i; } +@ int function(void) { return identity(32); } + + .syntax unified + .thumb + .text + + .def identity + .scl 2 + .type 32 + .endef + .global identity + .align 2 + .code16 + .thumb_func +identity: + bx lr + + .def function + .scl 2 + .type 32 + .endef +function: + movs r0, #32 + b identity + diff --git a/lld/test/pecoff/armnt-branch24t.test b/lld/test/pecoff/armnt-branch24t.test new file mode 100644 index 0000000..bcb0a51 --- /dev/null +++ b/lld/test/pecoff/armnt-branch24t.test @@ -0,0 +1,18 @@ +# RUN: yaml2obj -format coff -o %t.obj %p/Inputs/armnt-branch24t.obj.yaml +# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE +# RUN: lld -flavor link /entry:function /subsystem:console /out:%t.exe %t.obj +# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER + +BEFORE: Disassembly of section .text: +BEFORE: 0: 70 47 bx lr +BEFORE: 2: 00 bf nop +BEFORE: 4: 20 20 movs r0, #32 +BEFORE: 6: 00 f0 00 b8 b.w #0 + +AFTER: Disassembly of section .text: +AFTER: .text: +AFTER: 1000: 70 47 bx lr +AFTER: 1002: 00 bf nop +AFTER: 1004: 20 20 movs r0, #32 +AFTER: 1006: ff f7 fb bf b.w #-10 + -- 2.7.4