diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp --- a/lld/ELF/Arch/Hexagon.cpp +++ b/lld/ELF/Arch/Hexagon.cpp @@ -115,6 +115,11 @@ case R_HEX_B22_PCREL_X: case R_HEX_B32_PCREL_X: return R_PLT_PC; + case R_HEX_IE_32_6_X: + case R_HEX_IE_16_X: + case R_HEX_IE_HI16: + case R_HEX_IE_LO16: + return R_GOT; case R_HEX_GOTREL_11_X: case R_HEX_GOTREL_16_X: case R_HEX_GOTREL_32_6_X: @@ -236,6 +241,7 @@ or32le(loc, applyMask(0x000007e0, val)); break; case R_HEX_16_X: // These relocs only have 6 effective bits. + case R_HEX_IE_16_X: case R_HEX_GOT_16_X: case R_HEX_GOTREL_16_X: case R_HEX_TPREL_16_X: @@ -251,6 +257,7 @@ case R_HEX_32_6_X: case R_HEX_GOT_32_6_X: case R_HEX_GOTREL_32_6_X: + case R_HEX_IE_32_6_X: case R_HEX_TPREL_32_6_X: or32le(loc, applyMask(0x0fff3fff, val >> 6)); break; @@ -285,11 +292,13 @@ break; case R_HEX_GOTREL_HI16: case R_HEX_HI16: + case R_HEX_IE_HI16: case R_HEX_TPREL_HI16: or32le(loc, applyMask(0x00c03fff, val >> 16)); break; case R_HEX_GOTREL_LO16: case R_HEX_LO16: + case R_HEX_IE_LO16: case R_HEX_TPREL_LO16: or32le(loc, applyMask(0x00c03fff, val)); break; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -177,7 +177,9 @@ return 1; } - bool canRelax = config->emachine != EM_ARM && config->emachine != EM_RISCV; + bool canRelax = config->emachine != EM_ARM && + config->emachine != EM_HEXAGON && + config->emachine != EM_RISCV; // If we are producing an executable and the symbol is non-preemptable, it // must be defined and the code sequence can be relaxed to use Local-Exec. diff --git a/lld/test/ELF/Inputs/hexagon-tls-ie.s b/lld/test/ELF/Inputs/hexagon-tls-ie.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/Inputs/hexagon-tls-ie.s @@ -0,0 +1,28 @@ + .type a,@object + .section .tdata,"awT",@progbits + .globl a + .p2align 2 +a: + .word 1 + .size a, 4 + + .type b,@object + .globl b + .p2align 2 +b: + .word 2 + .size b, 4 + + .type c,@object + .globl c + .p2align 2 +c: + .word 3 + .size c, 4 + + .type d,@object + .globl d + .p2align 2 +d: + .word 4 + .size d, 4 diff --git a/lld/test/ELF/hexagon-tls-ie.s b/lld/test/ELF/hexagon-tls-ie.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/hexagon-tls-ie.s @@ -0,0 +1,34 @@ +# REQUIRES: hexagon +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %p/Inputs/hexagon-tls-ie.s -o %t2.o +# RUN: ld.lld %t1.o %t2.o -o %t +# RUN: llvm-objdump -d --print-imm-hex %t | FileCheck %s +# RUN: llvm-objdump -d --section=.got %t | FileCheck -check-prefix=CHECK-GOT %s + + .globl _start + .type _start, @function +_start: + +# R_HEX_IE_32_6_X and R_HEX_IE_16_X +# CHECK: { immext(#0x30140) +# CHECK-NEXT: r2 = memw(##0x30154) } + r2 = memw(##a@IE) + +# R_HEX_IE_LO16 +# CHECK: { r2.l = #0x154 } + r2.l = #a@IE +# R_HEX_IE_HI16 +# CHECK: { r2.h = #0x3 } + r2.h = #a@IE + + +# Verify that the .got entries are created. +# CHECK-GOT: 00030154 .got: +# CHECK-GOT-NEXT: 30154: f0 ff ff ff fffffff0 +# CHECK-GOT-NEXT: 30158: f4 ff ff ff fffffff4 +# CHECK-GOT-NEXT: 3015c: f8 ff ff ff fffffff8 +# CHECK-GOT-NEXT: 30160: fc ff ff ff fffffffc + r2 = memw(##a@IE) + r2 = memw(##b@IE) + r2 = memw(##c@IE) + r2 = memw(##d@IE)