[lld] r232464 - [ARM] Implement relocations: R_ARM_REL32, R_ARM_THM_JUMP11, R_ARM_PREL31
Denis Protivensky
dprotivensky at accesssoftek.com
Tue Mar 17 02:18:24 PDT 2015
Author: denis-protivensky
Date: Tue Mar 17 04:18:24 2015
New Revision: 232464
URL: http://llvm.org/viewvc/llvm-project?rev=232464&view=rev
Log:
[ARM] Implement relocations: R_ARM_REL32, R_ARM_THM_JUMP11, R_ARM_PREL31
Test case for every relocation is added.
Differential Revision: http://reviews.llvm.org/D7565
Added:
lld/trunk/test/elf/ARM/rel-arm-prel31.test
lld/trunk/test/elf/ARM/rel-rel32.test
lld/trunk/test/elf/ARM/rel-thm-jump11.test
Modified:
lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
Modified: lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp?rev=232464&r1=232463&r2=232464&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.cpp Tue Mar 17 04:18:24 2015
@@ -70,6 +70,13 @@ static Reference::Addend readAddend_ARM_
return llvm::SignExtend64<26>(result);
}
+static Reference::Addend readAddend_THM_JUMP11(const uint8_t *location) {
+ const auto value = read16le(location);
+ const uint16_t imm11 = value & 0x7FF;
+
+ return llvm::SignExtend32<12>(imm11 << 1);
+}
+
static Reference::Addend readAddend(const uint8_t *location,
Reference::KindValue kindValue) {
switch (kindValue) {
@@ -78,6 +85,8 @@ static Reference::Addend readAddend(cons
case R_ARM_THM_CALL:
case R_ARM_THM_JUMP24:
return readAddend_THM_CALL(location);
+ case R_ARM_THM_JUMP11:
+ return readAddend_THM_JUMP11(location);
case R_ARM_CALL:
case R_ARM_JUMP24:
return readAddend_ARM_CALL(location);
@@ -107,6 +116,12 @@ static inline void applyThmReloc(uint8_t
write16le(location, (read16le(location) & ~maskLo) | (resLo & maskLo));
}
+static inline void applyThumb16Reloc(uint8_t *location, uint16_t result,
+ uint16_t mask = 0xFFFF) {
+ assert(!(result & ~mask));
+ write16le(location, (read16le(location) & ~mask) | (result & mask));
+}
+
/// \brief R_ARM_ABS32 - (S + A) | T
static void relocR_ARM_ABS32(uint8_t *location, uint64_t P, uint64_t S,
int64_t A, bool addressesThumb) {
@@ -123,6 +138,42 @@ static void relocR_ARM_ABS32(uint8_t *lo
applyArmReloc(location, result);
}
+/// \brief R_ARM_REL32 - ((S + A) | T) - P
+static void relocR_ARM_REL32(uint8_t *location, uint64_t P, uint64_t S,
+ int64_t A, bool addressesThumb) {
+ uint64_t T = addressesThumb;
+ uint32_t result = (uint32_t)(((S + A) | T) - P);
+
+ DEBUG_WITH_TYPE(
+ "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+ llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+ llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+ llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+ llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+ llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+ applyArmReloc(location, result);
+}
+
+/// \brief R_ARM_PREL31 - ((S + A) | T) - P
+static void relocR_ARM_PREL31(uint8_t *location, uint64_t P, uint64_t S,
+ int64_t A, bool addressesThumb) {
+ uint64_t T = addressesThumb;
+ uint32_t result = (uint32_t)(((S + A) | T) - P);
+ const uint32_t mask = 0x7FFFFFFF;
+ uint32_t rel31 = result & mask;
+
+ DEBUG_WITH_TYPE(
+ "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+ llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+ llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+ llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+ llvm::dbgs() << " T: 0x" << Twine::utohexstr(T);
+ llvm::dbgs() << " result: 0x" << Twine::utohexstr(result);
+ llvm::dbgs() << " rel31: 0x" << Twine::utohexstr(rel31) << "\n");
+
+ applyArmReloc(location, rel31, mask);
+}
+
/// \brief Relocate B/BL instructions. useJs defines whether J1 & J2 are used
static void relocR_ARM_THM_B_L(uint8_t *location, uint32_t result, bool useJs) {
result = (result & 0x01FFFFFE) >> 1;
@@ -183,6 +234,24 @@ static void relocR_ARM_THM_JUMP24(uint8_
relocR_ARM_THM_B_L(location, result, true);
}
+/// \brief R_ARM_THM_JUMP11 - S + A - P
+static void relocR_ARM_THM_JUMP11(uint8_t *location, uint64_t P, uint64_t S,
+ int64_t A) {
+ uint32_t result = (uint32_t)(S + A - P);
+
+ DEBUG_WITH_TYPE(
+ "ARM", llvm::dbgs() << "\t\tHandle " << LLVM_FUNCTION_NAME << " -";
+ llvm::dbgs() << " S: 0x" << Twine::utohexstr(S);
+ llvm::dbgs() << " A: 0x" << Twine::utohexstr(A);
+ llvm::dbgs() << " P: 0x" << Twine::utohexstr(P);
+ llvm::dbgs() << " result: 0x" << Twine::utohexstr(result) << "\n");
+
+ //we cut off first bit because it is always 1 according to p. 4.5.3
+ result = (result & 0x0FFE) >> 1;
+
+ applyThumb16Reloc(location, result, 0x7FF);
+}
+
/// \brief R_ARM_CALL - ((S + A) | T) - P
static void relocR_ARM_CALL(uint8_t *location, uint64_t P, uint64_t S,
int64_t A, bool addressesThumb) {
@@ -274,7 +343,7 @@ static void relocR_ARM_THM_MOV(uint8_t *
const uint16_t bitI = (result >> 11) & 0x1;
const uint16_t resHi = (bitI << 10) | imm4;
- applyThmReloc(location, resHi, resLo, 0x40F, 0x70FF);
+ applyThmReloc(location, resHi, resLo, 0x40F, 0x70FF);
}
/// \brief R_ARM_THM_MOVW_ABS_NC - (S + A) | T
@@ -340,6 +409,10 @@ std::error_code ARMTargetRelocationHandl
relocR_ARM_ABS32(location, relocVAddress, targetVAddress, addend,
addressesThumb);
break;
+ case R_ARM_REL32:
+ relocR_ARM_REL32(location, relocVAddress, targetVAddress, addend,
+ addressesThumb);
+ break;
case R_ARM_THM_CALL:
// TODO: consider adding bool variable to disable J1 & J2 for archs
// before ARMv6
@@ -358,6 +431,9 @@ std::error_code ARMTargetRelocationHandl
relocR_ARM_THM_JUMP24(location, relocVAddress, targetVAddress, addend,
addressesThumb);
break;
+ case R_ARM_THM_JUMP11:
+ relocR_ARM_THM_JUMP11(location, relocVAddress, targetVAddress, addend);
+ break;
case R_ARM_MOVW_ABS_NC:
relocR_ARM_MOVW_ABS_NC(location, relocVAddress, targetVAddress, addend,
addressesThumb);
@@ -372,6 +448,10 @@ std::error_code ARMTargetRelocationHandl
case R_ARM_THM_MOVT_ABS:
relocR_ARM_THM_MOVT_ABS(location, relocVAddress, targetVAddress, addend);
break;
+ case R_ARM_PREL31:
+ relocR_ARM_PREL31(location, relocVAddress, targetVAddress, addend,
+ addressesThumb);
+ break;
default:
return make_unhandled_reloc_error();
}
Added: lld/trunk/test/elf/ARM/rel-arm-prel31.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-arm-prel31.test?rev=232464&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-arm-prel31.test (added)
+++ lld/trunk/test/elf/ARM/rel-arm-prel31.test Tue Mar 17 04:18:24 2015
@@ -0,0 +1,48 @@
+# Check handling of R_ARM_PREL31 relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .ARM.extab:
+# CHECK: 4000a4 b1ffff7f
+# CHECK: SYMBOL TABLE:
+# CHECK: 00000000 *UND* 00000000
+# CHECK: 00400054 g F .text 00000050 __gxx_personality_v0
+
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_ARM
+ Flags: [ EF_ARM_EABI_VER5 ]
+Sections:
+ - Name: .ARM.extab
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ AddressAlign: 0x4
+ Content: 0000000084019701B0B0B008FFFF01080E2432003A040000
+ - Name: .rel.ARM.extab
+ Type: SHT_REL
+ Link: .symtab
+ AddressAlign: 0x4
+ Info: .ARM.extab
+ Relocations:
+ - Offset: 0
+ Symbol: __gxx_personality_v0
+ Type: R_ARM_PREL31
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x4
+ Content: 80B400AF00231846BD465DF8047B704780B582B000AF3B1D1846FFF7FEFFFFF7FEFFFFF7FEFF0420FFF7FEFF0346184601230360002240F20001C0F20001FFF7FEFF3B1D1846FFF7FEFFFFF7FEFF00BF
+Symbols:
+ Local:
+ Global:
+ - Name: __gxx_personality_v0
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x1
+...
+
Added: lld/trunk/test/elf/ARM/rel-rel32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-rel32.test?rev=232464&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-rel32.test (added)
+++ lld/trunk/test/elf/ARM/rel-rel32.test Tue Mar 17 04:18:24 2015
@@ -0,0 +1,97 @@
+# Check handling of R_ARM_REL32 relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK-NEXT: 400074 80b400af 880f0000
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400074 g F .text 00000004 main
+# CHECK: 00401000 g .bss 00000004 _myref
+
+---
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_ARM
+ Flags: [ EF_ARM_EABI_VER5 ]
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: 80B400AF0000000000231846BD465DF8047B7047
+ - Name: .rel.text
+ Type: SHT_REL
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: .text
+ Relocations:
+ - Offset: 0x0000000000000004
+ Symbol: _myref
+ Type: R_ARM_REL32
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000004
+ Content: '00474343'
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 004743433A202863726F7373746F6F6C2D4E47206C696E61726F2D312E31332E312D342E392D323031342E3039202D204C696E61726F2047434320342E392D323031342E30392920342E392E32203230313430393034202870726572656C656173652900
+ - Name: .note.GNU-stack
+ Type: SHT_PROGBITS
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .ARM.attributes
+ Type: SHT_ARM_ATTRIBUTES
+ AddressAlign: 0x0000000000000001
+ Content: 4134000000616561626900012A00000005372D4100060A0741080109020A041204140115011703180119011A021B031C011E062201
+Symbols:
+ Local:
+ - Name: test.c
+ Type: STT_FILE
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: '$d'
+ Section: .text
+ Value: 0x0000000000000004
+ - Name: '$t'
+ Section: .text
+ Value: 0x0000000000000008
+ - Name: .note.GNU-stack
+ Type: STT_SECTION
+ Section: .note.GNU-stack
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .ARM.attributes
+ Type: STT_SECTION
+ Section: .ARM.attributes
+ Global:
+ - Name: _myref
+ Type: STT_OBJECT
+ Section: .bss
+ Size: 0x0000000000000004
+ - Name: main
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000001
+ Size: 0x0000000000000014
+...
Added: lld/trunk/test/elf/ARM/rel-thm-jump11.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/ARM/rel-thm-jump11.test?rev=232464&view=auto
==============================================================================
--- lld/trunk/test/elf/ARM/rel-thm-jump11.test (added)
+++ lld/trunk/test/elf/ARM/rel-thm-jump11.test Tue Mar 17 04:18:24 2015
@@ -0,0 +1,141 @@
+# Check handling of R_ARM_THM_JUMP11 relocation.
+# RUN: yaml2obj -format=elf %s > %t-o.o
+# RUN: lld -flavor gnu -target arm -m armelf_linux_eabi -Bstatic \
+# RUN: --noinhibit-exec %t-o.o -o %t
+# RUN: llvm-objdump -s -t %t | FileCheck %s
+
+# CHECK: Contents of section .text:
+# CHECK: 4001a4 0021c7e7
+# CHECK: SYMBOL TABLE:
+# CHECK: 00400138 g F .text 00000060 __gnu_h2f_internal
+# CHECK: 004001a4 g F .text 00000004 __gnu_h2f_alternative
+
+---
+FileHeader:
+ Class: ELFCLASS32
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_ARM
+ Flags: [ EF_ARM_EABI_VER5 ]
+Sections:
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: 70B4020CC0F3C754FF2CC0F3160302F4004080B241D0002C08BF002B3BD0A4F17F0543F4000315F10E0FA8BF41F6FF7209DA15F1190FA3BFA4F166066FF07F42F2406FF07F4212EA03060CD001325208964208BF03EA42021344B3F1807F24BF5B08A4F17E0501B30F2D26DC15F1180F11DB15F10E0FB5BF4FF6F2710E35CFF6FF71AD02B7BF491BAAB2CB40002202EB5333034398B270BC70470029FBD040EA533370BC43F4FC407047102DDEDD6FEAD0336FEAC33398B2EDE740F4F84398B2E9E700BFC0F3842310B4A3F11F040029B4FA84F400F400424FEA541408BF0024C0F309002146140481B943B14203703302EBC35343EA04005DF8044B704760B1B0FA80F3153B98405B42EFE744EA40305DF8044B40F0FF40704720465DF8044B704700BF01216BE70121FEE7002167E70021FEE7
+ - Name: .rel.text
+ Type: SHT_REL
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: .text
+ Relocations:
+ - Offset: 0x000000000000012A
+ Symbol: __gnu_h2f_internal
+ Type: R_ARM_THM_JUMP11
+ - Offset: 0x0000000000000132
+ Symbol: __gnu_h2f_internal
+ Type: R_ARM_THM_JUMP11
+ - Name: .text.startup
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ AddressAlign: 0x0000000000000004
+ Content: 0020FFF7FEBF00BF
+ - Name: .rel.text.startup
+ Type: SHT_REL
+ Link: .symtab
+ AddressAlign: 0x0000000000000004
+ Info: .text.startup
+ Relocations:
+ - Offset: 0x0000000000000002
+ Symbol: __gnu_h2f_alternative
+ Type: R_ARM_THM_JUMP24
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x0000000000000001
+ Content: 004743433A202863726F7373746F6F6C2D4E47206C696E61726F2D312E31332E312D342E392D323031342E3039202D204C696E61726F2047434320342E392D323031342E30392920342E392E32203230313430393034202870726572656C656173652900
+ - Name: .note.GNU-stack
+ Type: SHT_PROGBITS
+ AddressAlign: 0x0000000000000001
+ Content: ''
+ - Name: .ARM.attributes
+ Type: SHT_ARM_ATTRIBUTES
+ AddressAlign: 0x0000000000000001
+ Content: 4134000000616561626900012A00000005372D4100060A0741080109020A041204140115011703180119011A021B031C011E022201
+Symbols:
+ Local:
+ - Name: .text
+ Type: STT_SECTION
+ Section: .text
+ - Name: .text.startup
+ Type: STT_SECTION
+ Section: .text.startup
+ - Name: .data
+ Type: STT_SECTION
+ Section: .data
+ - Name: .bss
+ Type: STT_SECTION
+ Section: .bss
+ - Name: .comment
+ Type: STT_SECTION
+ Section: .comment
+ - Name: .note.GNU-stack
+ Type: STT_SECTION
+ Section: .note.GNU-stack
+ - Name: .ARM.attributes
+ Type: STT_SECTION
+ Section: .ARM.attributes
+ - Name: '$t'
+ Section: .text
+ - Name: __gnu_f2h_internal
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000001
+ Size: 0x00000000000000C2
+ Global:
+ - Name: __gnu_f2h_alternative
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x000000000000012D
+ Size: 0x0000000000000004
+ Visibility: STV_HIDDEN
+ - Name: __gnu_h2f_alternative
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000131
+ Size: 0x0000000000000004
+ Visibility: STV_HIDDEN
+ - Name: __gnu_h2f_ieee
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000129
+ Size: 0x0000000000000004
+ Visibility: STV_HIDDEN
+ - Name: main
+ Type: STT_FUNC
+ Section: .text.startup
+ Value: 0x0000000000000001
+ Size: 0x0000000000000006
+ - Name: __gnu_f2h_ieee
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000000125
+ Size: 0x0000000000000004
+ Visibility: STV_HIDDEN
+ - Name: __gnu_h2f_internal
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x00000000000000C5
+ Size: 0x000000000000005E
+ Visibility: STV_HIDDEN
+...
More information about the llvm-commits
mailing list