]> granicus.if.org Git - llvm/commitdiff
[mips][ias] R_MIPS_(GOT|HI|LO|PC)16 and R_MIPS_GPREL32 do not need symbols.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 9 May 2016 10:21:14 +0000 (10:21 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 9 May 2016 10:21:14 +0000 (10:21 +0000)
Summary:
In theory, care must be taken to ensure that pairs of R_MIPS_(GOT|HI|LO)16
make the same decision on both relocs in the reloc pair but in practice
this isn't as hard as it sounds and only limits the complexity of the
predicate used. We handle all three with the same code to ensure their
decisions always agree with each other.

Reviewers: sdardis

Subscribers: rafael, dsanders, sdardis, llvm-commits

Differential Revision: http://reviews.llvm.org/D19016

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268900 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
test/MC/Mips/got-rel-expr.s
test/MC/Mips/relocation.s
test/MC/Mips/sort-relocation-table.s

index d8516001b7ea926e4d8932aad0dac934f83fc936..fb184bb3807cc8cece20f69b92185b20c271bbf8 100644 (file)
@@ -476,30 +476,27 @@ void MipsELFObjectWriter::sortRelocs(const MCAssembler &Asm,
 
 bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
                                                   unsigned Type) const {
-  // FIXME: This is extremely conservative. This really needs to use a
-  // whitelist with a clear explanation for why each realocation needs to
-  // point to the symbol, not to the section.
   switch (Type) {
   default:
     return true;
 
+  // On REL ABI's (e.g. O32), these relocations form pairs. The pairing is done
+  // by the static linker by matching the symbol and offset.
+  // We only see one relocation at a time but it's still safe to relocate with
+  // the section so long as both relocations make the same decision.
+  //
+  // Some older linkers may require the symbol for particular cases. Such cases
+  // are not supported yet but can be added as required.
   case ELF::R_MIPS_GOT16:
   case ELF::R_MIPS16_GOT16:
   case ELF::R_MICROMIPS_GOT16:
-    return true;
-
-  // These relocations might be paired with another relocation. The pairing is
-  // done by the static linker by matching the symbol. Since we only see one
-  // relocation at a time, we have to force them to relocate with a symbol to
-  // avoid ending up with a pair where one points to a section and another
-  // points to a symbol.
   case ELF::R_MIPS_HI16:
   case ELF::R_MIPS16_HI16:
   case ELF::R_MICROMIPS_HI16:
   case ELF::R_MIPS_LO16:
   case ELF::R_MIPS16_LO16:
   case ELF::R_MICROMIPS_LO16:
-    return true;
+    return false;
 
   case ELF::R_MIPS_16:
   case ELF::R_MIPS_32:
@@ -509,6 +506,8 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
   case ELF::R_MIPS_26:
   case ELF::R_MIPS_64:
   case ELF::R_MIPS_GPREL16:
+  case ELF::R_MIPS_GPREL32:
+  case ELF::R_MIPS_PC16:
     return false;
   }
 }
index 01c364e5dc35ed9450f9cab6bc54f73d04be1493..8e77658c24ad9faf425fbce950760a71c969eb56 100644 (file)
@@ -8,10 +8,10 @@
 foo:
   lw      $t0,%got($loc+0x10004)($gp)
 # CHECK: 0:       8f 88 00 01     lw      $8, 1($gp)
-# CHECK:                  00000000:  R_MIPS_GOT16 $loc
+# CHECK:                  00000000:  R_MIPS_GOT16 .data
   addi    $t0,$t0,%lo($loc+0x10004)
 # CHECK: 4:       21 08 00 04     addi    $8, $8, 4
-# CHECK:                  00000004:  R_MIPS_LO16  $loc
+# CHECK:                  00000004:  R_MIPS_LO16  .data
 
   .data
 $loc:
index 615b3d51b6d61e517b43c999559764493f29337d..6c74438fc21082bf80362c37160818d1803d0dae 100644 (file)
@@ -4,6 +4,9 @@
 // RUN:     | FileCheck -check-prefix=ENCLE -check-prefix=FIXUP %s
 // RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux < %s \
 // RUN:     | llvm-readobj -r | FileCheck -check-prefix=RELOC %s
+// RUN: llvm-mc -filetype=obj -triple mips-unknown-linux < %s \
+// RUN:     | llvm-readobj -sections -section-data \
+// RUN:     | FileCheck -check-prefix=DATA %s
 
 // Test that we produce the correct relocation.
 // FIXME: move more relocation only tests here.
 //         unknown.
 // FIXME - Placeholder. Generation method is known but doesn't work.
 
+// DATA-LABEL: Name: .text
+// DATA:       SectionData (
+
+// DATA-NEXT:  0000: 00000004 00000000 00000004 0C000000
         .short foo                         // RELOC: R_MIPS_16 foo
 
-        .long foo                          // RELOC: R_MIPS_32 foo
+        .short bar                         // RELOC: R_MIPS_16 .data
+
+baz:    .long foo                          // RELOC: R_MIPS_32 foo
+
+        .long bar                          // RELOC: R_MIPS_32 .data
 
                                            // ?????: R_MIPS_REL32 foo
 
                                            // ENCLE: jal foo # encoding: [A,A,A,0b000011AA]
                                            // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_Mips_26
 
+// The nop from the jal is at 0x0010
+// DATA-NEXT:  0010: 00000000 0C000001 00000000 24620000
+        jal baz                            // RELOC: R_MIPS_26 .text
+                                           // ENCBE: jal baz # encoding: [0b000011AA,A,A,A]
+                                           // ENCLE: jal baz # encoding: [A,A,A,0b000011AA]
+                                           // FIXUP: # fixup A - offset: 0, value: baz, kind: fixup_Mips_26
+
         addiu $2, $3, %hi(foo)             // RELOC: R_MIPS_HI16 foo
                                            // ENCBE: addiu $2, $3, %hi(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %hi(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %hi(foo), kind: fixup_Mips_HI16
 
+// DATA-NEXT:  0020: 24620000 24620000 24620004 24620000
         addiu $2, $3, %lo(foo)             // RELOC: R_MIPS_LO16 foo
                                            // ENCBE: addiu $2, $3, %lo(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %lo(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %lo(foo), kind: fixup_Mips_LO16
 
+        addiu $2, $3, %hi(bar)             // RELOC: R_MIPS_HI16 .data
+                                           // ENCBE: addiu $2, $3, %hi(bar) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %hi(bar) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: %hi(bar), kind: fixup_Mips_HI16
+
+        addiu $2, $3, %lo(bar)             // RELOC: R_MIPS_LO16 .data
+                                           // ENCBE: addiu $2, $3, %lo(bar) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %lo(bar) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: %lo(bar), kind: fixup_Mips_LO16
+
         addiu $2, $3, %gp_rel(foo)         // RELOC: R_MIPS_GPREL16 foo
                                            // ENCBE: addiu $2, $3, %gp_rel(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %gp_rel(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %gp_rel(foo), kind: fixup_Mips_GPREL
 
+// DATA-NEXT:  0030: 24620004 24620000 24420000 24620000
+        addiu $2, $3, %gp_rel(bar)         // RELOC: R_MIPS_GPREL16 .data
+                                           // ENCBE: addiu $2, $3, %gp_rel(bar) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %gp_rel(bar) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: %gp_rel(bar), kind: fixup_Mips_GPREL
+
                                            // ?????: R_MIPS_LITERAL foo
 
         addiu $2, $3, %got(foo)            // RELOC: R_MIPS_GOT16 foo
                                            // ENCBE: addiu $2, $3, %got(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %got(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %got(foo), kind: fixup_Mips_GOT
+        // %got requires a %lo pair
+        addiu $2, $2, %lo(foo)
+
+        addiu $2, $3, %got(bar)            // RELOC: R_MIPS_GOT16 .data
+                                           // ENCBE: addiu $2, $3, %got(bar) # encoding: [0x24,0x62,A,A]
+                                           // ENCLE: addiu $2, $3, %got(bar) # encoding: [A,A,0x62,0x24]
+                                           // FIXUP: # fixup A - offset: 0, value: %got(bar), kind: fixup_Mips_GOT
+// DATA-NEXT:  0040: 24420004 0000FFBE 24620000
+        // %got requires a %lo pair
+        addiu $2, $2, %lo(bar)
 
         .short foo-.                       // RELOC: R_MIPS_PC16 foo
+        .short baz-.                       // RELOC-NOT: R_MIPS_PC16
 
         addiu $2, $3, %call16(foo)         // RELOC: R_MIPS_CALL16 foo
                                            // ENCBE: addiu $2, $3, %call16(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %call16(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %call16(foo), kind: fixup_Mips_CALL16
 
+       .p2align 4
+// DATA-NEXT:  0050: 00000000 00000000 00000000 00000004
         .quad foo                          // RELOC: R_MIPS_64 foo
+        .quad bar                          // RELOC: R_MIPS_64 .data
 
                                            // ?????: R_MIPS_GPREL32 foo
                                            // ?????: R_MIPS_UNUSED1 foo
                                            // ?????: R_MIPS_SHIFT5 foo
                                            // ?????: R_MIPS_SHIFT6 foo
 
+// DATA-NEXT:  0060: 24620000 24620000 24620000 24620000
         addiu $2, $3, %got_disp(foo)       // RELOC: R_MIPS_GOT_DISP foo
                                            // ENCBE: addiu $2, $3, %got_disp(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %got_disp(foo) # encoding: [A,A,0x62,0x24]
                                            // ENCLE: addiu $2, $3, %got_hi(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %got_hi(foo), kind: fixup_Mips_GOT_HI16
 
+// DATA-NEXT:  0070: 24620000 64620000 64620000 24620000
         addiu $2, $3, %got_lo(foo)         // RELOC: R_MIPS_GOT_LO16 foo
                                            // ENCBE: addiu $2, $3, %got_lo(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %got_lo(foo) # encoding: [A,A,0x62,0x24]
                                            // ENCLE: addiu $2, $3, %call_hi(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXUP: # fixup A - offset: 0, value: %call_hi(foo), kind: fixup_Mips_CALL_HI16
 
+// DATA-NEXT:  0080: 24620000 24620000 24620000 24620000
         addiu $2, $3, %call_lo(foo)        // RELOC: R_MIPS_CALL_LO16 foo
                                            // ENCBE: addiu $2, $3, %call_lo(foo) # encoding: [0x24,0x62,A,A]
                                            // ENCLE: addiu $2, $3, %call_lo(foo) # encoding: [A,A,0x62,0x24]
                                            // FIXME: R_MICROMIPS_*
         .long foo-.                        // RELOC: R_MIPS_PC32 foo
 //      .ehword foo                        // FIXME: R_MIPS_EH foo
+
+       .data
+       .word 0
+bar:
+       .word 1
+// DATA-LABEL: Section {
index 017e38cf4fa6d7baa692f8158f9c9e999b5c4c9d..16368c02d7b9408660f10bbd7f29515da8a500f1 100644 (file)
        addiu $2, $2, %lo(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_1 {
-# CHECK-NEXT:    0x0 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_LO16 local1
+# CHECK-NEXT:    0x0 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 2: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_2 {
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 3: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_3 {
-# CHECK-NEXT:    0xC R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local2
-# CHECK-NEXT:    0x8 R_MIPS_LO16 local2
+# CHECK-NEXT:    0xC R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x8 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 3b: Same as 3 but a different starting order.
        lui $2, %got(local2)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_3b {
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
-# CHECK-NEXT:    0xC R_MIPS_GOT16 local2
-# CHECK-NEXT:    0x8 R_MIPS_LO16 local2
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
+# CHECK-NEXT:    0xC R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x8 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 4: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_4 {
-# CHECK-NEXT:    0xC R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x8 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_LO16 local1
+# CHECK-NEXT:    0xC R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x8 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 5: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        addiu $2, $2, %lo(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_5 {
-# CHECK-NEXT:    0x8 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x0 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0xC R_MIPS_LO16 local1
+# CHECK-NEXT:    0x8 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x0 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0xC R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 6: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        addiu $2, $2, %lo(local1+1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_6 {
-# CHECK-NEXT:    0x8 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x0 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0xC R_MIPS_LO16 local1
+# CHECK-NEXT:    0x8 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x0 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0xC R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 7: R_MIPS_GOT16 must be followed by a matching R_MIPS_LO16.
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_7 {
-# CHECK-NEXT:    0xC R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x8 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_LO16 local1
+# CHECK-NEXT:    0xC R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x8 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 8: R_MIPS_LO16's may be orphaned.
        lw $2, %lo(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_8 {
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 8b: Another example of 8. The R_MIPS_LO16 at 0x4 is orphaned.
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_8b {
-# CHECK-NEXT:    0x8 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
-# CHECK-NEXT:    0x4 R_MIPS_LO16 local1
+# CHECK-NEXT:    0x8 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x4 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 9: R_MIPS_GOT16's don't need a matching R_MIPS_LO16 to immediately
        lui $2, %got(local1)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_9 {
-# CHECK-NEXT:    0x4 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x8 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x0 R_MIPS_LO16 local1
+# CHECK-NEXT:    0x4 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x8 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x0 R_MIPS_LO16 .text
 # CHECK-NEXT:  }
 
 # GOTLO 10: R_MIPS_GOT16's must have a matching R_MIPS_LO16 somewhere though.
        lw $2, %lo(local3)
 
 # CHECK-LABEL: Section ({{[0-9]+}}) .rel.mips_gotlo_10 {
-# CHECK-NEXT:    0x0 R_MIPS_GOT16 local1
-# CHECK-NEXT:    0x4 R_MIPS_LO16 local1
-# CHECK-NEXT:    0xC R_MIPS_GOT16 local3
-# CHECK-NEXT:    0x10 R_MIPS_LO16 local3
-# CHECK-NEXT:    0x8 R_MIPS_GOT16 local2
+# CHECK-NEXT:    0x0 R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x4 R_MIPS_LO16 .text
+# CHECK-NEXT:    0xC R_MIPS_GOT16 .text
+# CHECK-NEXT:    0x10 R_MIPS_LO16 .text
+# CHECK-NEXT:    0x8 R_MIPS_GOT16 .text
 # CHECK-NEXT:  }
 
 # Finally, do test 2 for R_MIPS_GOT16 on external symbols to prove they are