Index: lld/ELF/Arch/ARM.cpp =================================================================== --- lld/ELF/Arch/ARM.cpp +++ lld/ELF/Arch/ARM.cpp @@ -132,6 +132,13 @@ case R_ARM_THM_MOVW_PREL_NC: case R_ARM_THM_MOVT_PREL: return R_PC; + case R_ARM_MOVW_BREL_NC: + case R_ARM_MOVW_BREL: + case R_ARM_MOVT_BREL: + case R_ARM_THM_MOVW_BREL_NC: + case R_ARM_THM_MOVW_BREL: + case R_ARM_THM_MOVT_BREL: + return R_ARM_SBREL; case R_ARM_NONE: return R_NONE; case R_ARM_TLS_LE32: @@ -527,16 +534,19 @@ break; case R_ARM_MOVW_ABS_NC: case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVW_BREL_NC: write32le(loc, (read32le(loc) & ~0x000f0fff) | ((val & 0xf000) << 4) | (val & 0x0fff)); break; case R_ARM_MOVT_ABS: case R_ARM_MOVT_PREL: + case R_ARM_MOVT_BREL: write32le(loc, (read32le(loc) & ~0x000f0fff) | (((val >> 16) & 0xf000) << 4) | ((val >> 16) & 0xfff)); break; case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_MOVT_BREL: // Encoding T1: A = imm4:i:imm3:imm8 write16le(loc, 0xf2c0 | // opcode @@ -549,6 +559,7 @@ break; case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVW_BREL_NC: // Encoding T3: A = imm4:i:imm3:imm8 write16le(loc, 0xf240 | // opcode @@ -629,14 +640,18 @@ case R_ARM_MOVW_ABS_NC: case R_ARM_MOVT_ABS: case R_ARM_MOVW_PREL_NC: - case R_ARM_MOVT_PREL: { + case R_ARM_MOVT_PREL: + case R_ARM_MOVW_BREL_NC: + case R_ARM_MOVT_BREL: { uint64_t val = read32le(buf) & 0x000f0fff; return SignExtend64<16>(((val & 0x000f0000) >> 4) | (val & 0x00fff)); } case R_ARM_THM_MOVW_ABS_NC: case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVW_PREL_NC: - case R_ARM_THM_MOVT_PREL: { + case R_ARM_THM_MOVT_PREL: + case R_ARM_THM_MOVW_BREL_NC: + case R_ARM_THM_MOVT_BREL: { // Encoding T3: A = imm4:i:imm3:imm8 uint16_t hi = read16le(buf); uint16_t lo = read16le(buf + 2); Index: lld/test/ELF/arm-mov-relocs.s =================================================================== --- lld/test/ELF/arm-mov-relocs.s +++ lld/test/ELF/arm-mov-relocs.s @@ -6,12 +6,21 @@ // RUN: ld.lld %t3 -o %t4 // RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi --no-show-raw-insn | FileCheck %s -// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as -// the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations. +// Test the following relocations pairs: +// * R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS +// * R_ARM_MOVW_PREL_NC and R_ARM_MOVT_PREL +// * R_ARM_MOVW_BREL_NC and R_ARM_MOVT_BREL +// +// * R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS +// * R_ARM_THM_MOVW_PREL_NC and R_ARM_THM_MOVT_PREL +// * R_ARM_THM_MOVW_BREL_NC and R_ARM_THM_MOVT_BREL + .syntax unified .globl _start + .align 12 _start: .section .R_ARM_MOVW_ABS_NC, "ax",%progbits + .align 8 movw r0, :lower16:label movw r1, :lower16:label1 movw r2, :lower16:label2 + 4 @@ -19,12 +28,14 @@ movw r4, :lower16:label3 + 4 // CHECK: Disassembly of section .R_ARM_MOVW_ABS_NC // CHECK-EMPTY: -// CHECK: movw r0, #0 -// CHECK: movw r1, #4 -// CHECK: movw r2, #12 -// CHECK: movw r3, #65532 -// CHECK: movw r4, #0 +// CHECK: 12000: movw r0, #0 +// CHECK: 12004: movw r1, #4 +// CHECK: 12008: movw r2, #12 +// CHECK: 1200c: movw r3, #65532 +// CHECK: 12010: movw r4, #0 + .section .R_ARM_MOVT_ABS, "ax",%progbits + .align 8 movt r0, :upper16:label movt r1, :upper16:label1 movt r2, :upper16:label2 + 4 @@ -32,45 +43,206 @@ movt r4, :upper16:label3 + 4 // CHECK: Disassembly of section .R_ARM_MOVT_ABS // CHECK-EMPTY: -// CHECK: movt r0, #2 -// CHECK: movt r1, #2 -// CHECK: movt r2, #2 -// CHECK: movt r3, #2 -// CHECK: movt r4, #3 +// CHECK: 12100: movt r0, #2 +// CHECK: 12104: movt r1, #2 +// CHECK: 12108: movt r2, #2 +// CHECK: 1210c: movt r3, #2 +// CHECK: 12110: movt r4, #3 .section .R_ARM_MOVW_PREL_NC, "ax",%progbits +.align 8 movw r0, :lower16:label - . movw r1, :lower16:label1 - . movw r2, :lower16:label2 + 4 - . movw r3, :lower16:label3 - . - movw r4, :lower16:label3 + 0x103c - . -// 0x20000 - . = 61188 -// CHECK: 110fc: movw r0, #61188 -// 0x20004 - . = 61188 -// CHECK: 11100: movw r1, #61188 -// 0x20008 - . + 4 = 61192 -// CHECK: 11104: movw r2, #61192 -// 0x2fffc - . = 61172 -// CHECK: 11108: movw r3, #61172 -// 0x2fffc - . +0x103c = 65324 -// CHECK: 1110c: movw r4, #65324 + movw r4, :lower16:label3 + 0x2214 - . +// CHECK: Disassembly of section .R_ARM_MOVW_PREL_NC +// CHECK-EMPTY: +// 0x20000 - . = 56832 +// CHECK: 12200: movw r0, #56832 +// 0x20004 - . = 56832 +// CHECK: 12204: movw r1, #56832 +// 0x20008 - . + 4 = 56836 +// CHECK: 12208: movw r2, #56836 +// 0x2fffc - . = 56816 +// CHECK: 1220c: movw r3, #56816 +// 0x2fffc - . + 0x2214 = 0x20000 +// CHECK: 12210: movw r4, #0 .section .R_ARM_MOVT_PREL, "ax",%progbits +.align 8 movt r0, :upper16:label - . movt r1, :upper16:label1 - . movt r2, :upper16:label2 + 0x4 - . movt r3, :upper16:label3 - . - movt r4, :upper16:label3 + 0x1120 - . -// 0x20000 - . = :upper16:0xeef0 = 0 -// CHECK: 11110: movt r0, #0 -// 0x20004 - . = :upper16:0xeef0 = 0 -// CHECK: 11114: movt r1, #0 -// 0x20008 - . + 4 = :upper16:0xeef4 = 0 -// CHECK: 11118: movt r2, #0 -// 0x2fffc - . = :upper16:0x1eee0 = 1 -// CHECK: 1111c: movt r3, #1 -// 0x2fffc - . + 0x1120 = :upper16:0x20000 = 2 -// CHECK: 11120: movt r4, #1 + movt r4, :upper16:label3 + 0x2314 - . +// CHECK: Disassembly of section .R_ARM_MOVT_PREL +// CHECK-EMPTY: +// 0x20000 - . = :upper16:0xdd00 = 0 +// CHECK: 12300: movt r0, #0 +// 0x20004 - . = :upper16:0xdd00 = 0 +// CHECK: 12304: movt r1, #0 +// 0x20008 - . + 4 = :upper16:0xdd04 = 0 +// CHECK: 12308: movt r2, #0 +// 0x2fffc - . = :upper16:0x1dcf0 = 1 +// CHECK: 1230c: movt r3, #1 +// 0x2fffc - . + 0x2314 = :upper16:0x20000 = 2 +// CHECK: 12310: movt r4, #2 + +.section .R_ARM_MOVW_BREL_NC, "ax",%progbits +.align 8 + movw r0, :lower16:label(sbrel) + movw r1, :lower16:label1(sbrel) + movw r2, :lower16:label2(sbrel) + movw r3, :lower16:label3(sbrel) + movw r4, :lower16:label3.4(sbrel) +// CHECK: Disassembly of section .R_ARM_MOVW_BREL_NC +// CHECK-EMPTY: +// SB = 0x20000 +// :lower16:(0x20000 - SB) = 0 +// CHECK: 12400: movw r0, #0 +// :lower16:(0x20004 - SB) = 4 +// CHECK: 12404: movw r1, #4 +// :lower16:(0x20008 - SB) = 8 +// CHECK: 12408: movw r2, #8 +// :lower16:(0x2fffc - SB) = 0xfffc +// CHECK: 1240c: movw r3, #65532 +// :lower16:(0x2fffc + 4 - SB) = 0x0 +// CHECK: 12410: movw r4, #0 + +.section .R_ARM_MOVT_BREL, "ax",%progbits +.align 8 + movt r0, :upper16:label(sbrel) + movt r1, :upper16:label1(sbrel) + movt r2, :upper16:label2(sbrel) + movt r3, :upper16:label3(sbrel) + movt r4, :upper16:label3.4(sbrel) +// CHECK: Disassembly of section .R_ARM_MOVT_BREL +// CHECK-EMPTY: +// SB = 0x20000 +// :upper16:(0x20000 - SB) = 0 +// CHECK: 12500: movt r0, #0 +// :upper16:(0x20004 - SB) = 0 +// CHECK: 12504: movt r1, #0 +// :upper16:(0x20008 - SB) = 0 +// CHECK: 12508: movt r2, #0 +// :upper16:(0x2fffc - SB) = 0 +// CHECK: 1250c: movt r3, #0 +// :upper16:(0x2fffc + 4 - SB) = 1 +// CHECK: 12510: movt r4, #1 + +.section .R_ARM_THM_MOVW_ABS_NC, "ax",%progbits +.align 8 + movw r0, :lower16:label + movw r1, :lower16:label1 + movw r2, :lower16:label2 + 4 + movw r3, :lower16:label3 + movw r4, :lower16:label3 + 4 +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVW_ABS_NC +// CHECK-THM-EMPTY: +// CHECK-THM: 12600: movw r0, #0 +// CHECK-THM: 12604: movw r1, #4 +// CHECK-THM: 12608: movw r2, #12 +// CHECK-THM: 1260c: movw r3, #65532 +// CHECK-THM: 12610: movw r4, #0 + +.section .R_ARM_THM_MOVT_ABS, "ax",%progbits +.align 8 + movt r0, :upper16:label + movt r1, :upper16:label1 + movt r2, :upper16:label2 + 4 + movt r3, :upper16:label3 + movt r4, :upper16:label3 + 4 +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVT_ABS +// CHECK-THM-EMPTY: +// CHECK-THM: 12700: movt r0, #2 +// CHECK-THM: 12704: movt r1, #2 +// CHECK-THM: 12708: movt r2, #2 +// CHECK-THM: 1270c: movt r3, #2 +// CHECK-THM: 12710: movt r4, #3 + +.section .R_ARM_THM_MOVW_PREL_NC, "ax",%progbits +.align 8 + movw r0, :lower16:label - . + movw r1, :lower16:label1 - . + movw r2, :lower16:label2 + 4 - . + movw r3, :lower16:label3 - . + movw r4, :lower16:label3 + 0x2814 - . +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVW_PREL_NC +// CHECK-THM-EMPTY: +// 0x20000 - . = 55296 +// CHECK-THM: 12800: movw r0, #55296 +// 0x20004 - . = 55296 +// CHECK-THM: 12804: movw r1, #55296 +// 0x20008 - . + 4 = 55300 +// CHECK-THM: 12808: movw r2, #55300 +// 0x2fffc - . = 55280 +// CHECK-THM: 1280c: movw r3, #55280 +// 0x2fffc - . + 0x2814 = 0x20000 +// CHECK-THM: 12810: movw r4, #0 + +.section .R_ARM_THM_MOVT_PREL, "ax",%progbits +.align 8 + movt r0, :upper16:label - . + movt r1, :upper16:label1 - . + movt r2, :upper16:label2 + 0x4 - . + movt r3, :upper16:label3 - . + movt r4, :upper16:label3 + 0x2914 - . +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVT_PREL +// CHECK-THM-EMPTY: +// 0x20000 - . = :upper16:0xd700 = 0 +// CHECK-THM: 12900: movt r0, #0 +// 0x20004 - . = :upper16:0xd700 = 0 +// CHECK-THM: 12904: movt r1, #0 +// 0x20008 - . + 4 = :upper16:0xd704 = 0 +// CHECK-THM: 12908: movt r2, #0 +// 0x2fffc - . = :upper16:0x1d6f0 = 1 +// CHECK-THM: 1290c: movt r3, #1 +// 0x2fffc - . + 0x2914 = :upper16:0x20000 = 2 +// CHECK-THM: 12910: movt r4, #2 + +.section .R_ARM_THM_MOVW_BREL_NC, "ax",%progbits +.align 8 + movw r0, :lower16:label(sbrel) + movw r1, :lower16:label1(sbrel) + movw r2, :lower16:label2(sbrel) + movw r3, :lower16:label3(sbrel) + movw r4, :lower16:label3.4(sbrel) +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVW_BREL_NC +// CHECK-THM-EMPTY: +// SB = 0x20000 +// :lower16:(0x20000 - SB) = 0 +// CHECK-THM: 12a00: movw r0, #0 +// :lower16:(0x20004 - SB) = 4 +// CHECK-THM: 12a04: movw r1, #4 +// :lower16:(0x20008 - SB) = 8 +// CHECK-THM: 12a08: movw r2, #8 +// :lower16:(0x2fffc - SB) = 0xfffc +// CHECK-THM: 12a0c: movw r3, #65532 +// :lower16:(0x2fffc + 4 - SB) = 0x0 +// CHECK-THM: 12a10: movw r4, #0 + +.section .R_ARM_THM_MOVT_BREL, "ax",%progbits +.align 8 + movt r0, :upper16:label(sbrel) + movt r1, :upper16:label1(sbrel) + movt r2, :upper16:label2(sbrel) + movt r3, :upper16:label3(sbrel) + movt r4, :upper16:label3.4(sbrel) +// CHECK-THM: Disassembly of section .R_ARM_THM_MOVT_BREL +// CHECK-THM-EMPTY: +// SB = 0x20000 +// :upper16:(0x20000 - SB) = 0 +// CHECK-THM: 12b00: movt r0, #0 +// :upper16:(0x20004 - SB) = 0 +// CHECK-THM: 12b04: movt r1, #0 +// :upper16:(0x20008 - SB) = 0 +// CHECK-THM: 12b08: movt r2, #0 +// :upper16:(0x2fffc - SB) = 0 +// CHECK-THM: 12b0c: movt r3, #0 +// :upper16:(0x2fffc + 4 - SB) = 1 +// CHECK-THM: 12b10: movt r4, #1 + .section .destination, "aw",%progbits .balign 65536 // 0x20000 @@ -88,4 +260,5 @@ label3: .word 3 // label3 + 4 is on a 2^16 alignment boundary +label3.4: .word 4