From ba7c041f213ce834a556e6645876739a4cb7280f Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 5 Aug 2015 19:40:07 +0000 Subject: [PATCH] COFF: ARM: Implepment BLX23T relocation and fix Branch20T. I fed the same test to MSVC linker and got the same output, so I believe this implementation is correct. llvm-svn: 244102 --- lld/COFF/Chunks.cpp | 32 +++++++++++++------- lld/test/COFF/reloc-arm.test | 71 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 11 deletions(-) create mode 100644 lld/test/COFF/reloc-arm.test diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp index c44b269..b5c6e35 100644 --- a/lld/COFF/Chunks.cpp +++ b/lld/COFF/Chunks.cpp @@ -79,21 +79,30 @@ void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, Defined *Sym, } } +static void applyMOV(uint8_t *Off, uint16_t V) { + or16(Off, ((V & 0x800) >> 1) | ((V >> 12) & 0xf)); + or16(Off + 2, ((V & 0x700) << 4) | (V & 0xff)); +} + static void applyMOV32T(uint8_t *Off, uint32_t V) { - uint16_t X = V; - or16(Off, ((X & 0x800) >> 1) | ((X >> 12) & 0xf)); - or16(Off + 2, ((X & 0x700) << 4) | (X & 0xff)); - X = V >> 16; - or16(Off + 4, ((X & 0x800) >> 1) | ((X >> 12) & 0xf)); - or16(Off + 6, ((X & 0x700) << 4) | (X & 0xff)); + applyMOV(Off, V); // set MOVW operand + applyMOV(Off + 4, V >> 16); // set MOVT operand +} + +static void applyBranch20T(uint8_t *Off, int32_t V) { + uint32_t S = V < 0 ? 1 : 0; + uint32_t J1 = (V >> 19) & 1; + uint32_t J2 = (V >> 18) & 1; + or16(Off, (S << 10) | ((V >> 12) & 0x3f)); + or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); } -static void applyBranchImm(uint8_t *Off, int32_t V) { +static void applyBranch24T(uint8_t *Off, int32_t V) { uint32_t S = V < 0 ? 1 : 0; uint32_t J1 = ((~V >> 23) & 1) ^ S; uint32_t J2 = ((~V >> 22) & 1) ^ S; - or16(Off, ((V >> 12) & 0x3ff) | (S << 10)); - or16(Off + 2, ((V >> 1) & 0x7ff) | (J2 << 11) | (J1 << 13)); + or16(Off, (S << 10) | ((V >> 12) & 0x3ff)); + or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff)); } void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, @@ -106,8 +115,9 @@ void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, Defined *Sym, case IMAGE_REL_ARM_ADDR32: add32(Off, S + Config->ImageBase); break; case IMAGE_REL_ARM_ADDR32NB: add32(Off, S); break; case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, S + Config->ImageBase); break; - case IMAGE_REL_ARM_BRANCH24T: applyBranchImm(Off, S - P - 4); break; - case IMAGE_REL_ARM_BLX23T: applyBranchImm(Off, S - P - 4); break; + case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, S - P - 4); break; + case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, S - P - 4); break; + case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, S - P - 4); break; default: llvm::report_fatal_error("Unsupported relocation type"); } diff --git a/lld/test/COFF/reloc-arm.test b/lld/test/COFF/reloc-arm.test new file mode 100644 index 0000000..568fbe7 --- /dev/null +++ b/lld/test/COFF/reloc-arm.test @@ -0,0 +1,71 @@ +# RUN: yaml2obj < %s > %t.obj +# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj +# RUN: llvm-objdump -s %t.exe | FileCheck %s + +# CHECK: .text: +# CHECK: 402000 01104000 00000000 00000000 00000000 +# CHECK: 402010 01100000 00000000 00000000 00000000 +# CHECK: 402020 01000100 00004000 00000000 00000000 +# CHECK: 402030 fe07e62f 00000000 00000000 00000000 +# CHECK: 402040 3e04de2f 00000000 00000000 00000000 +# CHECK: 402050 fe07d62f 00000000 00000000 00000000 +# CHECK: 402060 00000000 00000000 00000000 00000000 + +--- +header: + Machine: IMAGE_FILE_MACHINE_ARMNT + Characteristics: [] +sections: + - Name: .aaa + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4096 + SectionData: 0000000000000000 + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4096 + SectionData: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + Relocations: + - VirtualAddress: 0 + SymbolName: foo + Type: 1 # IMAGE_REL_ARM_ADDR32 + - VirtualAddress: 16 + SymbolName: foo + Type: 2 # IMAGE_REL_ARM_ADDR32NB + - VirtualAddress: 32 + SymbolName: foo + Type: 17 # IMAGE_REL_AMD64_MOV32T + - VirtualAddress: 48 + SymbolName: foo + Type: 20 # IMAGE_REL_AMD64_BRANCH24T + - VirtualAddress: 64 + SymbolName: foo + Type: 18 # IMAGE_REL_ARM_BRANCH20T + - VirtualAddress: 80 + SymbolName: foo + Type: 21 # IMAGE_REL_AMD64_BLX23T +symbols: + - Name: .aaa + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: .text + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + - Name: main + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: foo + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... -- 2.7.4