Index: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -64,13 +64,47 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { - // determine the type of the relocation + // Determine the type of the relocation. unsigned Kind = (unsigned)Fixup.getKind(); switch (Kind) { + case Mips::fixup_Mips_16: + case FK_Data_2: + return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16; case Mips::fixup_Mips_32: case FK_Data_4: return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32; + } + + if (IsPCRel) { + switch (Kind) { + case Mips::fixup_Mips_Branch_PCRel: + case Mips::fixup_Mips_PC16: + return ELF::R_MIPS_PC16; + case Mips::fixup_MICROMIPS_PC7_S1: + return ELF::R_MICROMIPS_PC7_S1; + case Mips::fixup_MICROMIPS_PC10_S1: + return ELF::R_MICROMIPS_PC10_S1; + case Mips::fixup_MICROMIPS_PC16_S1: + return ELF::R_MICROMIPS_PC16_S1; + case Mips::fixup_MIPS_PC19_S2: + return ELF::R_MIPS_PC19_S2; + case Mips::fixup_MIPS_PC18_S3: + return ELF::R_MIPS_PC18_S3; + case Mips::fixup_MIPS_PC21_S2: + return ELF::R_MIPS_PC21_S2; + case Mips::fixup_MIPS_PC26_S2: + return ELF::R_MIPS_PC26_S2; + case Mips::fixup_MIPS_PCHI16: + return ELF::R_MIPS_PCHI16; + case Mips::fixup_MIPS_PCLO16: + return ELF::R_MIPS_PCLO16; + } + + llvm_unreachable("invalid PC-relative fixup kind!"); + } + + switch (Kind) { case Mips::fixup_Mips_64: case FK_Data_8: return ELF::R_MIPS_64; @@ -110,9 +144,6 @@ return ELF::R_MIPS_TLS_DTPREL_HI16; case Mips::fixup_Mips_DTPREL_LO: return ELF::R_MIPS_TLS_DTPREL_LO16; - case Mips::fixup_Mips_Branch_PCRel: - case Mips::fixup_Mips_PC16: - return ELF::R_MIPS_PC16; case Mips::fixup_Mips_GOT_PAGE: return ELF::R_MIPS_GOT_PAGE; case Mips::fixup_Mips_GOT_OFST: @@ -153,12 +184,6 @@ return ELF::R_MICROMIPS_LO16; case Mips::fixup_MICROMIPS_GOT16: return ELF::R_MICROMIPS_GOT16; - case Mips::fixup_MICROMIPS_PC7_S1: - return ELF::R_MICROMIPS_PC7_S1; - case Mips::fixup_MICROMIPS_PC10_S1: - return ELF::R_MICROMIPS_PC10_S1; - case Mips::fixup_MICROMIPS_PC16_S1: - return ELF::R_MICROMIPS_PC16_S1; case Mips::fixup_MICROMIPS_CALL16: return ELF::R_MICROMIPS_CALL16; case Mips::fixup_MICROMIPS_GOT_DISP: @@ -179,19 +204,8 @@ return ELF::R_MICROMIPS_TLS_TPREL_HI16; case Mips::fixup_MICROMIPS_TLS_TPREL_LO16: return ELF::R_MICROMIPS_TLS_TPREL_LO16; - case Mips::fixup_MIPS_PC19_S2: - return ELF::R_MIPS_PC19_S2; - case Mips::fixup_MIPS_PC18_S3: - return ELF::R_MIPS_PC18_S3; - case Mips::fixup_MIPS_PC21_S2: - return ELF::R_MIPS_PC21_S2; - case Mips::fixup_MIPS_PC26_S2: - return ELF::R_MIPS_PC26_S2; - case Mips::fixup_MIPS_PCHI16: - return ELF::R_MIPS_PCHI16; - case Mips::fixup_MIPS_PCLO16: - return ELF::R_MIPS_PCLO16; } + llvm_unreachable("invalid fixup kind!"); } Index: test/MC/Mips/mips-relocations.s =================================================================== --- test/MC/Mips/mips-relocations.s +++ /dev/null @@ -1,40 +0,0 @@ -# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | FileCheck %s -# Check that the assembler can handle the documented syntax -# for relocations. -# CHECK: lui $2, %hi(_gp_disp) # encoding: [A,A,0x02,0x3c] -# CHECK: # fixup A - offset: 0, value: _gp_disp@ABS_HI, kind: fixup_Mips_HI16 -# CHECK: addiu $2, $2, %lo(_gp_disp) # encoding: [A,A,0x42,0x24] -# CHECK: # fixup A - offset: 0, value: _gp_disp@ABS_LO, kind: fixup_Mips_LO16 -# CHECK: lw $25, %call16(strchr)($gp) # encoding: [A,A,0x99,0x8f] -# CHECK: # fixup A - offset: 0, value: strchr@GOT_CALL, kind: fixup_Mips_CALL16 -# CHECK: lw $3, %got(loop_1)($2) # encoding: [A,A,0x43,0x8c] -# CHECK: # fixup A - offset: 0, value: loop_1@GOT, kind: fixup_Mips_GOT_Local -# CHECK: lui $2, %dtprel_hi(_gp_disp) # encoding: [A,A,0x02,0x3c] -# CHECK: # fixup A - offset: 0, value: _gp_disp@DTPREL_HI, kind: fixup_Mips_DTPREL_HI -# CHECK: addiu $2, $2, %dtprel_lo(_gp_disp) # encoding: [A,A,0x42,0x24] -# CHECK: # fixup A - offset: 0, value: _gp_disp@DTPREL_LO, kind: fixup_Mips_DTPREL_LO -# CHECK: lw $3, %got(loop_1)($2) # encoding: [A,A,0x43,0x8c] -# CHECK: # fixup A - offset: 0, value: loop_1@GOT, kind: fixup_Mips_GOT_Local -# CHECK: lw $4, %got_disp(loop_2)($3) # encoding: [A,A,0x64,0x8c] -# CHECK: # fixup A - offset: 0, value: loop_2@GOT_DISP, kind: fixup_Mips_GOT_DISP -# CHECK: lw $5, %got_page(loop_3)($4) # encoding: [A,A,0x85,0x8c] -# CHECK: # fixup A - offset: 0, value: loop_3@GOT_PAGE, kind: fixup_Mips_GOT_PAGE -# CHECK: lw $6, %got_ofst(loop_4)($5) # encoding: [A,A,0xa6,0x8c] -# CHECK: # fixup A - offset: 0, value: loop_4@GOT_OFST, kind: fixup_Mips_GOT_OFST -# CHECK: lui $2, %tprel_hi(_gp_disp) # encoding: [A,A,0x02,0x3c] -# CHECK: # fixup A - offset: 0, value: _gp_disp@TPREL_HI, kind: fixup_Mips_TPREL_HI -# CHECK: addiu $2, $2, %tprel_lo(_gp_disp) # encoding: [A,A,0x42,0x24] -# CHECK: # fixup A - offset: 0, value: _gp_disp@TPREL_LO, kind: fixup_Mips_TPREL_LO - - lui $2, %hi(_gp_disp) - addiu $2, $2, %lo(_gp_disp) - lw $25, %call16(strchr)($gp) - lw $3, %got(loop_1)($2) - lui $2, %dtprel_hi(_gp_disp) - addiu $2, $2, %dtprel_lo(_gp_disp) - lw $3, %got(loop_1)($2) - lw $4, %got_disp(loop_2)($3) - lw $5, %got_page(loop_3)($4) - lw $6, %got_ofst(loop_4)($5) - lui $2, %tprel_hi(_gp_disp) - addiu $2, $2, %tprel_lo(_gp_disp) Index: test/MC/Mips/relocation.s =================================================================== --- test/MC/Mips/relocation.s +++ test/MC/Mips/relocation.s @@ -1,10 +1,209 @@ -// RUN: llvm-mc -filetype=obj -triple mipsel-unknown-linux < %s | llvm-readobj -r | FileCheck %s +// RUN: llvm-mc -triple mips-unknown-linux < %s -show-encoding \ +// RUN: | FileCheck -check-prefix=ENCBE -check-prefix=FIXUP %s +// RUN: llvm-mc -triple mipsel-unknown-linux < %s -show-encoding \ +// 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 // Test that we produce the correct relocation. // FIXME: move more relocation only tests here. - .long foo -// CHECK: R_MIPS_32 foo +// Check prefixes: +// RELOC - Check the relocation in the object. +// FIXUP - Check the fixup on the instruction. +// ENCBE - Check the big-endian encoding on the instruction. +// ENCLE - Check the little-endian encoding on the instruction. +// ????? - Placeholder. Relocation is defined but the way of generating it is +// unknown. +// FIXME - Placeholder. Generation method is known but doesn't work. - .long foo-. -// CHECK: R_MIPS_PC32 foo + .short foo // RELOC: R_MIPS_16 foo + + .long foo // RELOC: R_MIPS_32 foo + + // ?????: R_MIPS_REL32 foo + + jal foo // RELOC: R_MIPS_26 foo + // ENCBE: jal foo # encoding: [0b000011AA,A,A,A] + // ENCLE: jal foo # encoding: [A,A,A,0b000011AA] + // FIXUP: # fixup A - offset: 0, value: foo, 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: foo@ABS_HI, kind: fixup_Mips_HI16 + + 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: foo@ABS_LO, 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: foo@GPREL, 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: foo@GOT, kind: fixup_Mips_GOT_Local + + .short foo-. // RELOC: R_MIPS_PC16 foo + + 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: foo@GOT_CALL, kind: fixup_Mips_CALL16 + + .quad foo // RELOC: R_MIPS_64 foo + + // ?????: R_MIPS_GPREL32 foo + // ?????: R_MIPS_UNUSED1 foo + // ?????: R_MIPS_UNUSED2 foo + // ?????: R_MIPS_UNUSED3 foo + // ?????: R_MIPS_SHIFT5 foo + // ?????: R_MIPS_SHIFT6 foo + + 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] + // FIXUP: # fixup A - offset: 0, value: foo@GOT_DISP, kind: fixup_Mips_GOT_DISP + + addiu $2, $3, %got_page(foo) // RELOC: R_MIPS_GOT_PAGE foo + // ENCBE: addiu $2, $3, %got_page(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %got_page(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@GOT_PAGE, kind: fixup_Mips_GOT_PAGE + + addiu $2, $3, %got_ofst(foo) // RELOC: R_MIPS_GOT_OFST foo + // ENCBE: addiu $2, $3, %got_ofst(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %got_ofst(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@GOT_OFST, kind: fixup_Mips_GOT_OFST + + addiu $2, $3, %got_hi(foo) // RELOC: R_MIPS_GOT_HI16 foo + // ENCBE: addiu $2, $3, %got_hi(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %got_hi(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@GOT_HI16, kind: fixup_Mips_GOT_HI16 + + 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] + // FIXUP: # fixup A - offset: 0, value: foo@GOT_LO16, kind: fixup_Mips_GOT_LO16 + +// addiu $2, $3, %neg(foo) // FIXME: R_MIPS_SUB foo + // ?????: R_MIPS_INSERT_A + // ?????: R_MIPS_INSERT_B + // ?????: R_MIPS_DELETE + + .set mips64 + daddiu $2, $3, %higher(foo) // RELOC: R_MIPS_HIGHER foo + // ENCBE: daddiu $2, $3, %higher(foo) # encoding: [0x64,0x62,A,A] + // ENCLE: daddiu $2, $3, %higher(foo) # encoding: [A,A,0x62,0x64] + // FIXUP: # fixup A - offset: 0, value: foo@HIGHER, kind: fixup_Mips_HIGHER + + daddiu $2, $3, %highest(foo) // RELOC: R_MIPS_HIGHEST foo + // ENCBE: daddiu $2, $3, %highest(foo) # encoding: [0x64,0x62,A,A] + // ENCLE: daddiu $2, $3, %highest(foo) # encoding: [A,A,0x62,0x64] + // FIXUP: # fixup A - offset: 0, value: foo@HIGHEST, kind: fixup_Mips_HIGHEST + + .set mips0 + addiu $2, $3, %call_hi(foo) // RELOC: R_MIPS_CALL_HI16 foo + // ENCBE: addiu $2, $3, %call_hi(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %call_hi(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@CALL_HI16, kind: fixup_Mips_CALL_HI16 + + 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] + // FIXUP: # fixup A - offset: 0, value: foo@CALL_LO16, kind: fixup_Mips_CALL_LO16 + + // ?????: R_MIPS_SCN_DISP foo + // ?????: R_MIPS_REL16 foo + // ?????: R_MIPS_ADD_IMMEDIATE foo + // ?????: R_MIPS_PJUMP foo + // ?????: R_MIPS_RELGOT foo +// jalr $25 // ?????: R_MIPS_JALR foo + + // ?????: R_MIPS_TLS_DTPMOD32 foo +// .dtprelword foo // FIXME: R_MIPS_TLS_DTPREL32 foo + // ?????: R_MIPS_TLS_DTPMOD64 foo +// .dtpreldword foo // FIXME: R_MIPS_TLS_DTPREL64 foo + addiu $2, $3, %tlsgd(foo) // RELOC: R_MIPS_TLS_GD foo + // ENCBE: addiu $2, $3, %tlsgd(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %tlsgd(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@TLSGD, kind: fixup_Mips_TLSGD + + addiu $2, $3, %tlsldm(foo) // RELOC: R_MIPS_TLS_LDM foo + // ENCBE: addiu $2, $3, %tlsldm(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %tlsldm(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@TLSLDM, kind: fixup_Mips_TLSLDM + + addiu $2, $3, %dtprel_hi(foo) // RELOC: R_MIPS_TLS_DTPREL_HI16 foo + // ENCBE: addiu $2, $3, %dtprel_hi(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %dtprel_hi(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@DTPREL_HI, kind: fixup_Mips_DTPREL_HI + + addiu $2, $3, %dtprel_lo(foo) // RELOC: R_MIPS_TLS_DTPREL_LO16 foo + // ENCBE: addiu $2, $3, %dtprel_lo(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %dtprel_lo(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@DTPREL_LO, kind: fixup_Mips_DTPREL_LO + + addiu $2, $3, %gottprel(foo) // RELOC: R_MIPS_TLS_GOTTPREL foo + // ENCBE: addiu $2, $3, %gottprel(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %gottprel(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@GOTTPREL, kind: fixup_Mips_GOTTPREL + +// .tprelword foo // FIXME: R_MIPS_TLS_TPREL32 foo +// .tpreldword foo // FIXME: R_MIPS_TLS_TPREL64 foo + addiu $2, $3, %tprel_hi(foo) // RELOC: R_MIPS_TLS_TPREL_HI16 foo + // ENCBE: addiu $2, $3, %tprel_hi(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %tprel_hi(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@TPREL_HI, kind: fixup_Mips_TPREL_HI + + addiu $2, $3, %tprel_lo(foo) // RELOC: R_MIPS_TLS_TPREL_LO16 foo + // ENCBE: addiu $2, $3, %tprel_lo(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %tprel_lo(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@TPREL_LO, kind: fixup_Mips_TPREL_LO + + // ?????: R_MIPS_GLOB_DAT foo + .set mips32r6 + beqzc $2, foo // RELOC: R_MIPS_PC21_S2 foo + // ENCBE: beqzc $2, foo # encoding: [0xd8,0b010AAAAA,A,A] + // ENCLE: beqzc $2, foo # encoding: [A,A,0b010AAAAA,0xd8] + // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC21_S2 + + bc foo // RELOC: R_MIPS_PC26_S2 foo + // ENCBE: bc foo # encoding: [0b110010AA,A,A,A] + // ENCLE: bc foo # encoding: [A,A,A,0b110010AA] + // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC26_S2 + + .set mips64r6 + ldpc $2, foo // RELOC: R_MIPS_PC18_S3 foo + // ENCBE: ldpc $2, foo # encoding: [0xec,0b010110AA,A,A] + // ENCLE: ldpc $2, foo # encoding: [A,A,0b010110AA,0xec] + // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_Mips_PC18_S3 + + .set mips32r6 + lwpc $2, foo // RELOC: R_MIPS_PC19_S2 foo + // ENCBE: lwpc $2, foo # encoding: [0xec,0b01001AAA,A,A] + // ENCLE: lwpc $2, foo # encoding: [A,A,0b01001AAA,0xec] + // FIXUP: # fixup A - offset: 0, value: foo, kind: fixup_MIPS_PC19_S2 + + addiu $2, $3, %pcrel_hi(foo) // RELOC: R_MIPS_PCHI16 foo + // ENCBE: addiu $2, $3, %pcrel_hi(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %pcrel_hi(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@PCREL_HI16, kind: fixup_MIPS_PCHI16 + + addiu $2, $3, %pcrel_lo(foo) // RELOC: R_MIPS_PCLO16 foo + // ENCBE: addiu $2, $3, %pcrel_lo(foo) # encoding: [0x24,0x62,A,A] + // ENCLE: addiu $2, $3, %pcrel_lo(foo) # encoding: [A,A,0x62,0x24] + // FIXUP: # fixup A - offset: 0, value: foo@PCREL_LO16, kind: fixup_MIPS_PCLO16 + + .set mips0 + // FIXME: R_MIPS16_* + // ?????: R_MIPS_COPY foo + // ?????: R_MIPS_JUMP_SLOT foo + // FIXME: R_MICROMIPS_* + .long foo-. // RELOC: R_MIPS_PC32 foo +// .ehword foo // FIXME: R_MIPS_EH foo