[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