Index: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -476,30 +476,27 @@ 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 @@ 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: llvm/trunk/test/MC/Mips/got-rel-expr.s =================================================================== --- llvm/trunk/test/MC/Mips/got-rel-expr.s +++ llvm/trunk/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: Index: llvm/trunk/test/MC/Mips/relocation.s =================================================================== --- llvm/trunk/test/MC/Mips/relocation.s +++ llvm/trunk/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 { Index: llvm/trunk/test/MC/Mips/sort-relocation-table.s =================================================================== --- llvm/trunk/test/MC/Mips/sort-relocation-table.s +++ llvm/trunk/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