From d095a756cce714b51e5d3de6c511b2c4e5c4ddce Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Mon, 6 Jul 2015 12:50:55 +0000 Subject: [PATCH] [Mips] Add support for MCJIT for MIPS32r6 Add support for resolving MIPS32r6 relocations in MCJIT. Patch by Vladimir Radosavljevic. Differential Revision: http://reviews.llvm.org/D10687 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241442 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../RuntimeDyld/RuntimeDyldELF.cpp | 61 ++++++++++++++++++- .../RuntimeDyld/Mips/ELF_O32R6_relocations.s | 49 +++++++++++++++ .../Mips/ELF_O32_PIC_relocations.s | 5 ++ 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index f5069c00585..3787950b3b0 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -511,11 +511,54 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, Insn |= Value & 0xffff; writeBytesUnaligned(Insn, TargetPtr, 4); break; - case ELF::R_MIPS_PC32: + case ELF::R_MIPS_PC32: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + writeBytesUnaligned(Value - FinalAddress, (uint8_t *)TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC16: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffff0000; + Insn |= ((Value - FinalAddress) >> 2) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC19_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xfff80000; + Insn |= ((Value - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC21_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffe00000; + Insn |= ((Value - FinalAddress) >> 2) & 0x1fffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PC26_S2: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xfc000000; + Insn |= ((Value - FinalAddress) >> 2) & 0x3ffffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + case ELF::R_MIPS_PCHI16: { uint32_t FinalAddress = (Section.LoadAddress + Offset); - writeBytesUnaligned(Value + Addend - FinalAddress, (uint8_t *)TargetPtr, 4); + Insn &= 0xffff0000; + Insn |= ((Value - FinalAddress + 0x8000) >> 16) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); break; } + case ELF::R_MIPS_PCLO16: { + uint32_t FinalAddress = (Section.LoadAddress + Offset); + Insn &= 0xffff0000; + Insn |= (Value - FinalAddress) & 0xffff; + writeBytesUnaligned(Insn, TargetPtr, 4); + break; + } + } } void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { @@ -1263,12 +1306,24 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( Section.StubOffset += getMaxStubSize(); } } else { - if (RelType == ELF::R_MIPS_HI16) + // FIXME: Calculate correct addends for R_MIPS_HI16, R_MIPS_LO16, + // R_MIPS_PCHI16 and R_MIPS_PCLO16 relocations. + if (RelType == ELF::R_MIPS_HI16 || RelType == ELF::R_MIPS_PCHI16) Value.Addend += (Opcode & 0x0000ffff) << 16; else if (RelType == ELF::R_MIPS_LO16) Value.Addend += (Opcode & 0x0000ffff); else if (RelType == ELF::R_MIPS_32) Value.Addend += Opcode; + else if (RelType == ELF::R_MIPS_PCLO16) + Value.Addend += SignExtend32<16>((Opcode & 0x0000ffff)); + else if (RelType == ELF::R_MIPS_PC16) + Value.Addend += SignExtend32<18>((Opcode & 0x0000ffff) << 2); + else if (RelType == ELF::R_MIPS_PC19_S2) + Value.Addend += SignExtend32<21>((Opcode & 0x0007ffff) << 2); + else if (RelType == ELF::R_MIPS_PC21_S2) + Value.Addend += SignExtend32<23>((Opcode & 0x001fffff) << 2); + else if (RelType == ELF::R_MIPS_PC26_S2) + Value.Addend += SignExtend32<28>((Opcode & 0x03ffffff) << 2); processSimpleRelocation(SectionID, Offset, RelType, Value); } } else if (IsMipsN64ABI) { diff --git a/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s b/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s new file mode 100644 index 00000000000..3d20db21964 --- /dev/null +++ b/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32R6_relocations.s @@ -0,0 +1,49 @@ +# RUN: llvm-mc -triple=mipsel-unknown-linux -mcpu=mips32r6 -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32R6.o %s +# RUN: llc -mtriple=mipsel-unknown-linux -mcpu=mips32r6 -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_O32R6.o %S/Inputs/ExternalFunction.ll +# RUN: llvm-rtdyld -triple=mipsel-unknown-linux -mcpu=mips32r6 -verify -map-section test_ELF_O32R6.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32R6.o,.text=0x10000 -check=%s %/T/test_ELF_O32R6.o %T/test_ELF_ExternalFunction_O32R6.o + +# RUN: llvm-mc -triple=mips-unknown-linux -mcpu=mips32r6 -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_O32R6.o %s +# RUN: llc -mtriple=mips-unknown-linux -mcpu=mips32r6 -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_O32R6.o %S/Inputs/ExternalFunction.ll +# RUN: llvm-rtdyld -triple=mips-unknown-linux -mcpu=mips32r6 -verify -map-section test_ELF_O32R6.o,.text=0x1000 -map-section test_ELF_ExternalFunction_O32R6.o,.text=0x10000 -check=%s %/T/test_ELF_O32R6.o %T/test_ELF_ExternalFunction_O32R6.o + + .text + .abicalls + .nan 2008 + .text + .set nomicromips + .set nomips16 + .set noreorder + .set nomacro + .set noat + + .align 3 + .globl bar + .type bar,@function + +bar: +# Test R_MIPS_PC19_S2 relocation. +# rtdyld-check: decode_operand(R_MIPS_PC19_S2, 1)[20:0] = (foo - R_MIPS_PC19_S2)[20:0] +R_MIPS_PC19_S2: + lwpc $6,foo + +# Test R_MIPS_PC21_S2 relocation. +# rtdyld-check: decode_operand(R_MIPS_PC21_S2, 1)[22:0] = (foo - next_pc(R_MIPS_PC21_S2))[22:0] +R_MIPS_PC21_S2: + bnezc $5,foo + +# Test R_MIPS_PC26_S2 relocation. +# rtdyld-check: decode_operand(R_MIPS_PC26_S2, 0)[27:0] = (foo - next_pc(R_MIPS_PC26_S2))[27:0] +R_MIPS_PC26_S2: + balc foo + +# Test R_MIPS_PCHI16 relocation. +# rtdyld-check: decode_operand(R_MIPS_PCHI16, 1)[15:0] = (foo - R_MIPS_PCHI16 + 0x8000)[31:16] +R_MIPS_PCHI16: + aluipc $5, %pcrel_hi(foo) + +# Test R_MIPS_PCLO16 relocation. +# rtdyld-check: decode_operand(R_MIPS_PCLO16, 2)[15:0] = (foo - R_MIPS_PCLO16)[15:0] +R_MIPS_PCLO16: + addiu $5, $5, %pcrel_lo(foo) + + .size bar, .-bar diff --git a/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s b/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s index a4b145ab517..6c47262246a 100644 --- a/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s +++ b/test/ExecutionEngine/RuntimeDyld/Mips/ELF_O32_PIC_relocations.s @@ -39,6 +39,11 @@ R_MIPS_26: j foo nop +# rtdyld-check: decode_operand(R_MIPS_PC16, 1)[17:0] = (foo - R_MIPS_PC16)[17:0] +R_MIPS_PC16: + bal foo + nop + # rtdyld-check: decode_operand(R_MIPS_HI16, 1)[15:0] = foo[31:16] R_MIPS_HI16: lui $1, %hi(foo) -- 2.34.1