summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp21
-rw-r--r--llvm/test/MC/Mips/got-rel-expr.s4
-rw-r--r--llvm/test/MC/Mips/relocation.s60
-rw-r--r--llvm/test/MC/Mips/sort-relocation-table.s80
4 files changed, 111 insertions, 54 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index d8516001b7e..fb184bb3807 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -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;
}
}
diff --git a/llvm/test/MC/Mips/got-rel-expr.s b/llvm/test/MC/Mips/got-rel-expr.s
index 01c364e5dc3..8e77658c24a 100644
--- a/llvm/test/MC/Mips/got-rel-expr.s
+++ b/llvm/test/MC/Mips/got-rel-expr.s
@@ -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:
diff --git a/llvm/test/MC/Mips/relocation.s b/llvm/test/MC/Mips/relocation.s
index 615b3d51b6d..6c74438fc21 100644
--- a/llvm/test/MC/Mips/relocation.s
+++ b/llvm/test/MC/Mips/relocation.s
@@ -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.
@@ -17,9 +20,17 @@
// 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
@@ -28,36 +39,74 @@
// 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
@@ -66,6 +115,7 @@
// ?????: 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]
@@ -86,6 +136,7 @@
// 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]
@@ -113,6 +164,7 @@
// 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]
@@ -207,3 +259,9 @@
// 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 {
diff --git a/llvm/test/MC/Mips/sort-relocation-table.s b/llvm/test/MC/Mips/sort-relocation-table.s
index 017e38cf4fa..16368c02d7b 100644
--- a/llvm/test/MC/Mips/sort-relocation-table.s
+++ b/llvm/test/MC/Mips/sort-relocation-table.s
@@ -206,8 +206,8 @@
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.
@@ -216,8 +216,8 @@
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.
@@ -229,10 +229,10 @@
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.
@@ -243,10 +243,10 @@
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.
@@ -259,10 +259,10 @@
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.
@@ -276,10 +276,10 @@
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.
@@ -293,10 +293,10 @@
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.
@@ -310,10 +310,10 @@
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.
@@ -321,7 +321,7 @@
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.
@@ -331,9 +331,9 @@
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
@@ -347,9 +347,9 @@
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.
@@ -370,11 +370,11 @@
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
OpenPOWER on IntegriCloud