[lld] 0d7e5da - [lld][Hexagon] Add checks for instructions that can have TLS relocations
Sid Manning via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 1 13:17:06 PDT 2021
Author: Sid Manning
Date: 2021-09-01T13:15:18-07:00
New Revision: 0d7e5daedcc6faf3247f7b3a7ed84f601efedf0e
URL: https://github.com/llvm/llvm-project/commit/0d7e5daedcc6faf3247f7b3a7ed84f601efedf0e
DIFF: https://github.com/llvm/llvm-project/commit/0d7e5daedcc6faf3247f7b3a7ed84f601efedf0e.diff
LOG: [lld][Hexagon] Add checks for instructions that can have TLS relocations
Several instructions with potential TLS relocations were missing. This
issue was found when building the Canadian LLVM toolchain.
Added:
lld/test/ELF/hexagon-tls-tprel.s
Modified:
lld/ELF/Arch/Hexagon.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Arch/Hexagon.cpp b/lld/ELF/Arch/Hexagon.cpp
index 02d872d58caf2..1ffb097f2769b 100644
--- a/lld/ELF/Arch/Hexagon.cpp
+++ b/lld/ELF/Arch/Hexagon.cpp
@@ -162,6 +162,28 @@ RelExpr Hexagon::getRelExpr(RelType type, const Symbol &s,
}
}
+// There are (arguably too) many relocation masks for the DSP's
+// R_HEX_6_X type. The table below is used to select the correct mask
+// for the given instruction.
+struct InstructionMask {
+ uint32_t cmpMask;
+ uint32_t relocMask;
+};
+static const InstructionMask r6[] = {
+ {0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
+ {0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
+ {0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
+ {0x42000000, 0x000020f8}, {0x43000000, 0x000007e0},
+ {0x44000000, 0x000020f8}, {0x45000000, 0x000007e0},
+ {0x46000000, 0x000020f8}, {0x47000000, 0x000007e0},
+ {0x6a000000, 0x00001f80}, {0x7c000000, 0x001f2000},
+ {0x9a000000, 0x00000f60}, {0x9b000000, 0x00000f60},
+ {0x9c000000, 0x00000f60}, {0x9d000000, 0x00000f60},
+ {0x9f000000, 0x001f0100}, {0xab000000, 0x0000003f},
+ {0xad000000, 0x0000003f}, {0xaf000000, 0x00030078},
+ {0xd7000000, 0x006020e0}, {0xd8000000, 0x006020e0},
+ {0xdb000000, 0x006020e0}, {0xdf000000, 0x006020e0}};
+
static bool isDuplex(uint32_t insn) {
// Duplex forms have a fixed mask and parse bits 15:14 are always
// zero. Non-duplex insns will always have at least one bit set in the
@@ -170,29 +192,6 @@ static bool isDuplex(uint32_t insn) {
}
static uint32_t findMaskR6(uint32_t insn) {
- // There are (arguably too) many relocation masks for the DSP's
- // R_HEX_6_X type. The table below is used to select the correct mask
- // for the given instruction.
- struct InstructionMask {
- uint32_t cmpMask;
- uint32_t relocMask;
- };
-
- static const InstructionMask r6[] = {
- {0x38000000, 0x0000201f}, {0x39000000, 0x0000201f},
- {0x3e000000, 0x00001f80}, {0x3f000000, 0x00001f80},
- {0x40000000, 0x000020f8}, {0x41000000, 0x000007e0},
- {0x42000000, 0x000020f8}, {0x43000000, 0x000007e0},
- {0x44000000, 0x000020f8}, {0x45000000, 0x000007e0},
- {0x46000000, 0x000020f8}, {0x47000000, 0x000007e0},
- {0x6a000000, 0x00001f80}, {0x7c000000, 0x001f2000},
- {0x9a000000, 0x00000f60}, {0x9b000000, 0x00000f60},
- {0x9c000000, 0x00000f60}, {0x9d000000, 0x00000f60},
- {0x9f000000, 0x001f0100}, {0xab000000, 0x0000003f},
- {0xad000000, 0x0000003f}, {0xaf000000, 0x00030078},
- {0xd7000000, 0x006020e0}, {0xd8000000, 0x006020e0},
- {0xdb000000, 0x006020e0}, {0xdf000000, 0x006020e0}};
-
if (isDuplex(insn))
return 0x03f00000;
@@ -200,7 +199,7 @@ static uint32_t findMaskR6(uint32_t insn) {
if ((0xff000000 & insn) == i.cmpMask)
return i.relocMask;
- error("unrecognized instruction for R_HEX_6 relocation: 0x" +
+ error("unrecognized instruction for 6_X relocation: 0x" +
utohexstr(insn));
return 0;
}
@@ -232,7 +231,11 @@ static uint32_t findMaskR16(uint32_t insn) {
if (isDuplex(insn))
return 0x03f00000;
- error("unrecognized instruction for R_HEX_16_X relocation: 0x" +
+ for (InstructionMask i : r6)
+ if ((0xff000000 & insn) == i.cmpMask)
+ return i.relocMask;
+
+ error("unrecognized instruction for 16_X type: 0x" +
utohexstr(insn));
return 0;
}
diff --git a/lld/test/ELF/hexagon-tls-tprel.s b/lld/test/ELF/hexagon-tls-tprel.s
new file mode 100644
index 0000000000000..b99465bc1df6b
--- /dev/null
+++ b/lld/test/ELF/hexagon-tls-tprel.s
@@ -0,0 +1,221 @@
+# REQUIRES: hexagon
+# RUN: llvm-mc -filetype=obj -triple=hexagon-unknown-elf %s -o %t.o
+# RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELOC %s
+# RUN: ld.lld %t.o -o %t
+# RUN: llvm-objdump -d --print-imm-hex %t | FileCheck %s
+
+# R_HEX_6_X at TPREL tests:
+# One test for each mask in the lookup table.
+
+#0x38000000
+if (!P0) memw(r0+#8)=##a at TPREL
+# RELOC: 0x0 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x4 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0) memw(r0+#0x8) = ##-0x4 }
+
+#0x39000000
+{ p0 = p1
+ if (!P0.new) memw(r0+#0)=##a at TPREL }
+# RELOC-NEXT: 0xC R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x10 R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0.new) memw(r0+#0x0) = ##-0x4 }
+
+#0x3e000000
+memw(r0+##a at TPREL)+=r1
+# RELOC-NEXT: 0x14 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x18 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: memw(r0+##0xfffffffc) += r1 }
+
+#0x3f000000
+memw(r0+##a at TPREL)+=#4
+# RELOC-NEXT: 0x1C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x20 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: memw(r0+##0xfffffffc) += #0x4 }
+
+
+#0x40000000
+{ r0 = r1
+ if (p0) memb(r0+##a at TPREL)=r0.new }
+# RELOC-NEXT: 0x28 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x2C R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (p0) memb(r0+##0xfffffffc) = r0.new }
+
+#0x41000000
+if (p0) r0=memb(r1+##a at TPREL)
+# RELOC-NEXT: 0x30 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x34 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (p0) r0 = memb(r1+##0xfffffffc) }
+
+#0x42000000
+{ r0 = r1
+ p0 = p1
+ if (p0.new) memb(r0+##a at TPREL)=r0.new }
+# RELOC-NEXT: 0x40 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x44 R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (p0.new) memb(r0+##0xfffffffc) = r0.new }
+
+#0x43000000
+{ p0 = p1
+ if (P0.new) r0=memb(r0+##a at TPREL) }
+# RELOC-NEXT: 0x4C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x50 R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (p0.new) r0 = memb(r0+##0xfffffffc) }
+
+#0x44000000
+if (!p0) memb(r0+##a at TPREL)=r1
+# RELOC-NEXT: 0x54 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x58 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0) memb(r0+##0xfffffffc) = r1 }
+
+#0x45000000
+if (!p0) r0=memb(r1+##a at TPREL)
+# RELOC-NEXT: 0x5C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x60 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0) r0 = memb(r1+##0xfffffffc) }
+
+
+#0x46000000
+{ p0 = p1
+ if (!p0.new) memb(r0+##a at TPREL)=r1 }
+# RELOC-NEXT: 0x68 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x6C R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0.new) memb(r0+##0xfffffffc) = r1 }
+
+#0x47000000
+{ p0 = p1
+ if (!p0.new) r0=memb(r1+##a at TPREL) }
+# RELOC-NEXT: 0x74 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x78 R_HEX_TPREL_16_X a 0x0
+# CHECK: immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0.new) r0 = memb(r1+##0xfffffffc) }
+
+#0x7c000000
+r1:0=combine(#8,##a at TPREL)
+# RELOC-NEXT: 0x7C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x80 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r1:0 = combine(#0x8,##0xfffffffc) }
+
+
+#0x9a000000
+r1:0=memb_fifo(r2=##a at TPREL)
+# RELOC-NEXT: 0x84 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x88 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r1:0 = memb_fifo(r2=##0xfffffffc) }
+
+
+#0x9b000000
+r0=memb(r1=##a at TPREL)
+# RELOC-NEXT: 0x8C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x90 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = memb(r1=##0xfffffffc) }
+
+
+#0x9c000000
+r1:0=memb_fifo(r2<<#2+##a at TPREL)
+# RELOC-NEXT: 0x94 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0x98 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r1:0 = memb_fifo(r2<<#0x2+##0xfffffffc) }
+
+
+#0x9d000000
+r0=memb(r1<<#2+##a at TPREL)
+# RELOC-NEXT: 0x9C R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xA0 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = memb(r1<<#0x2+##0xfffffffc) }
+
+
+#0x9f000000
+if (!p0) r0=memb(##a at TPREL)
+# RELOC-NEXT: 0xA4 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xA8 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0) r0 = memb(##0xfffffffc) }
+
+
+#0xab000000
+memb(r0=##a at TPREL)=r1
+# RELOC-NEXT: 0xAC R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xB0 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: memb(r0=##0xfffffffc) = r1 }
+
+
+#0xad000000
+memb(r0<<#2+##a at TPREL)=r1
+# RELOC-NEXT: 0xB4 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xB8 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: memb(r0<<#0x2+##0xfffffffc) = r1 }
+
+
+#0xaf000000
+if (!p0) memb(##a at TPREL)=r1
+# RELOC-NEXT: 0xBC R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xC0 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: if (!p0) memb(##0xfffffffc) = r1 }
+
+
+#0xd7000000
+r0=add(##a at TPREL,mpyi(r1,r2))
+# RELOC-NEXT: 0xC4 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xC8 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = add(##0xfffffffc,mpyi(r1,r2)) }
+
+
+#0xd8000000
+R0=add(##a at TPREL,mpyi(r0,#2))
+# RELOC-NEXT: 0xCC R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xD0 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = add(##0xfffffffc,mpyi(r0,#0x2)) }
+
+
+#0xdb000000
+r0=add(r1,add(r2,##a at TPREL))
+# RELOC-NEXT: 0xD4 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xD8 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = add(r1,add(r2,##-0x4)) }
+
+
+#0xdf000000
+r0=add(r1,mpyi(r2,##a at TPREL))
+# RELOC-NEXT: 0xDC R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xE0 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = add(r1,mpyi(r2,##0xfffffffc)) }
+
+
+# Duplex form of R_HEX_6_X
+# R_HEX_32_6_X
+# R_HEX_6_X
+{ r0 = ##a at TPREL; r2 = r16 }
+# RELOC-NEXT: 0xE4 R_HEX_TPREL_32_6_X a 0x0
+# RELOC-NEXT: 0xE8 R_HEX_TPREL_16_X a 0x0
+# CHECK: { immext(#0xffffffc0)
+# CHECK-NEXT: r0 = ##0xfffffffc; r2 = r16 }
+
+ .section .tdata,"awT", at progbits
+ .globl a
+ .p2align 2
+a:
+ .word 1
+ .size a, 4
More information about the llvm-commits
mailing list