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 @@ -120,6 +120,8 @@ case R_HEX_B22_PCREL_X: case R_HEX_B32_PCREL_X: case R_HEX_GD_PLT_B22_PCREL: + case R_HEX_GD_PLT_B22_PCREL_X: + case R_HEX_GD_PLT_B32_PCREL_X: return R_PLT_PC; case R_HEX_IE_32_6_X: case R_HEX_IE_16_X: @@ -311,16 +313,18 @@ case R_HEX_B15_PCREL_X: or32le(loc, applyMask(0x00df20fe, val & 0x3f)); break; - case R_HEX_GD_PLT_B22_PCREL: case R_HEX_B22_PCREL: + case R_HEX_GD_PLT_B22_PCREL: case R_HEX_PLT_B22_PCREL: checkInt(loc, val, 22, rel); or32le(loc, applyMask(0x1ff3ffe, val >> 2)); break; case R_HEX_B22_PCREL_X: + case R_HEX_GD_PLT_B22_PCREL_X: or32le(loc, applyMask(0x1ff3ffe, val & 0x3f)); break; case R_HEX_B32_PCREL_X: + case R_HEX_GD_PLT_B32_PCREL_X: or32le(loc, applyMask(0x0fff3fff, val >> 6)); break; case R_HEX_GOTREL_HI16: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1336,8 +1336,11 @@ addend &= ~0x8000; // R_HEX_GD_PLT_B22_PCREL (call a@GDPLT) is transformed into // call __tls_get_addr even if the symbol is non-preemptible. - if (!(config->emachine == EM_HEXAGON && type == R_HEX_GD_PLT_B22_PCREL)) - expr = fromPlt(expr); + if (!(config->emachine == EM_HEXAGON && + (type == R_HEX_GD_PLT_B22_PCREL || + type == R_HEX_GD_PLT_B22_PCREL_X || + type == R_HEX_GD_PLT_B32_PCREL_X))) + expr = fromPlt(expr); } } diff --git a/lld/test/ELF/hexagon-tls-gd-nonpreemptible.s b/lld/test/ELF/hexagon-tls-gd-nonpreemptible.s --- a/lld/test/ELF/hexagon-tls-gd-nonpreemptible.s +++ b/lld/test/ELF/hexagon-tls-gd-nonpreemptible.s @@ -3,6 +3,7 @@ # RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t.o # RUN: ld.lld -shared %t.o -o %t.so # RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=RELOC %s +# RUN: llvm-readobj -r %t.o | FileCheck -check-prefix=REL %s # RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t.so | FileCheck %s ## Prior to D77021 lld would error "relocation R_HEX_GD_PLT_B22_PCREL cannot refer to absolute symbol". @@ -17,17 +18,28 @@ # RELOC-NEXT: R_HEX_JMP_SLOT __tls_get_addr 0x0 # RELOC-NEXT: } +# REL: R_HEX_B32_PCREL_X _GLOBAL_OFFSET_TABLE_ 0x0 +# REL-NEXT: R_HEX_6_PCREL_X _GLOBAL_OFFSET_TABLE_ 0x4 +# REL-NEXT: R_HEX_GD_GOT_32_6_X a 0x0 +# REL-NEXT: R_HEX_GD_GOT_16_X a 0x0 +# REL-NEXT: R_HEX_GD_PLT_B22_PCREL a 0x0 +# REL-NEXT: R_HEX_GD_PLT_B32_PCREL_X a 0x0 +# REL-NEXT: R_HEX_GD_PLT_B22_PCREL_X a 0x4 + # CHECK: { immext(#{{.*}}) # CHECK-NEXT: r2 = add(pc,##{{.*}}) } # CHECK-NEXT: { immext(#{{.*}}) # CHECK-NEXT: r0 = add(r2,##-{{.*}}) } # CHECK-NEXT: { call {{.*}} } +# CHECK-NEXT: { immext({{.*}}) +# CHECK-NEXT: call {{.*}} } # CHECK-NEXT: { r0 = memw(r0+#0x0) } _start: r2 = add(pc,##_GLOBAL_OFFSET_TABLE_@PCREL) r0 = add(r2,##a@GDGOT) call a@GDPLT + call ##a@GDPLT r0 = memw(r0+#0) ## a is non-preemptible due to STV_HIDDEN visibility.