diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 298 |
1 files changed, 16 insertions, 282 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 3b3a03fedf7..c70e81a759f 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -13,6 +13,7 @@ #include "RuntimeDyldELF.h" #include "RuntimeDyldCheckerImpl.h" +#include "Targets/RuntimeDyldELFMips.h" #include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" @@ -211,6 +212,21 @@ void RuntimeDyldELF::deregisterEHFrames() { RegisteredEHFrameSections.clear(); } +std::unique_ptr<RuntimeDyldELF> +llvm::RuntimeDyldELF::create(Triple::ArchType Arch, + RuntimeDyld::MemoryManager &MemMgr, + JITSymbolResolver &Resolver) { + switch (Arch) { + default: + return make_unique<RuntimeDyldELF>(MemMgr, Resolver); + case Triple::mips: + case Triple::mipsel: + case Triple::mips64: + case Triple::mips64el: + return make_unique<RuntimeDyldELFMips>(MemMgr, Resolver); + } +} + std::unique_ptr<RuntimeDyld::LoadedObjectInfo> RuntimeDyldELF::loadObject(const object::ObjectFile &O) { if (auto ObjSectionToIDOrErr = loadObjectImpl(O)) @@ -498,24 +514,6 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section, } } -void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section, - uint64_t Offset, uint32_t Value, - uint32_t Type, int32_t Addend) { - uint8_t *TargetPtr = Section.getAddressWithOffset(Offset); - Value += Addend; - - DEBUG(dbgs() << "resolveMIPSRelocation, LocalAddress: " - << Section.getAddressWithOffset(Offset) << " FinalAddress: " - << format("%p", Section.getLoadAddressWithOffset(Offset)) - << " Value: " << format("%x", Value) - << " Type: " << format("%x", Type) - << " Addend: " << format("%x", Addend) << "\n"); - - Value = evaluateMIPS32Relocation(Section, Offset, Value, Type); - - applyMIPSRelocation(TargetPtr, Value, Type); -} - void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { if (Arch == Triple::UnknownArch || !StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) { @@ -531,254 +529,6 @@ void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) { IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips"); } -void RuntimeDyldELF::resolveMIPSN32Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, - SID SectionID) { - int64_t CalculatedValue = evaluateMIPS64Relocation( - Section, Offset, Value, Type, Addend, SymOffset, SectionID); - applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue, - Type); -} - -void RuntimeDyldELF::resolveMIPSN64Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, - SID SectionID) { - uint32_t r_type = Type & 0xff; - uint32_t r_type2 = (Type >> 8) & 0xff; - uint32_t r_type3 = (Type >> 16) & 0xff; - - // RelType is used to keep information for which relocation type we are - // applying relocation. - uint32_t RelType = r_type; - int64_t CalculatedValue = evaluateMIPS64Relocation(Section, Offset, Value, - RelType, Addend, - SymOffset, SectionID); - if (r_type2 != ELF::R_MIPS_NONE) { - RelType = r_type2; - CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, - CalculatedValue, SymOffset, - SectionID); - } - if (r_type3 != ELF::R_MIPS_NONE) { - RelType = r_type3; - CalculatedValue = evaluateMIPS64Relocation(Section, Offset, 0, RelType, - CalculatedValue, SymOffset, - SectionID); - } - applyMIPSRelocation(Section.getAddressWithOffset(Offset), CalculatedValue, - RelType); -} - -int64_t RuntimeDyldELF::evaluateMIPS32Relocation(const SectionEntry &Section, - uint64_t Offset, - uint64_t Value, - uint32_t Type) { - - DEBUG(dbgs() << "evaluateMIPS32Relocation, LocalAddress: 0x" - << format("%llx", Section.getAddressWithOffset(Offset)) - << " FinalAddress: 0x" - << format("%llx", Section.getLoadAddressWithOffset(Offset)) - << " Value: 0x" << format("%llx", Value) << " Type: 0x" - << format("%x", Type) << "\n"); - - switch (Type) { - default: - llvm_unreachable("Unknown relocation type!"); - return Value; - case ELF::R_MIPS_32: - return Value; - case ELF::R_MIPS_26: - return Value >> 2; - case ELF::R_MIPS_HI16: - // Get the higher 16-bits. Also add 1 if bit 15 is 1. - return (Value + 0x8000) >> 16; - case ELF::R_MIPS_LO16: - return Value; - case ELF::R_MIPS_PC32: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return Value - FinalAddress; - } - case ELF::R_MIPS_PC16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value - FinalAddress) >> 2; - } - case ELF::R_MIPS_PC19_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value - (FinalAddress & ~0x3)) >> 2; - } - case ELF::R_MIPS_PC21_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value - FinalAddress) >> 2; - } - case ELF::R_MIPS_PC26_S2: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value - FinalAddress) >> 2; - } - case ELF::R_MIPS_PCHI16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value - FinalAddress + 0x8000) >> 16; - } - case ELF::R_MIPS_PCLO16: { - uint32_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return Value - FinalAddress; - } - } -} - -int64_t -RuntimeDyldELF::evaluateMIPS64Relocation(const SectionEntry &Section, - uint64_t Offset, uint64_t Value, - uint32_t Type, int64_t Addend, - uint64_t SymOffset, SID SectionID) { - - DEBUG(dbgs() << "evaluateMIPS64Relocation, LocalAddress: 0x" - << format("%llx", Section.getAddressWithOffset(Offset)) - << " FinalAddress: 0x" - << format("%llx", Section.getLoadAddressWithOffset(Offset)) - << " Value: 0x" << format("%llx", Value) << " Type: 0x" - << format("%x", Type) << " Addend: 0x" << format("%llx", Addend) - << " SymOffset: " << format("%x", SymOffset) << "\n"); - - switch (Type) { - default: - llvm_unreachable("Not implemented relocation type!"); - break; - case ELF::R_MIPS_JALR: - case ELF::R_MIPS_NONE: - break; - case ELF::R_MIPS_32: - case ELF::R_MIPS_64: - return Value + Addend; - case ELF::R_MIPS_26: - return ((Value + Addend) >> 2) & 0x3ffffff; - case ELF::R_MIPS_GPREL16: { - uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); - return Value + Addend - (GOTAddr + 0x7ff0); - } - case ELF::R_MIPS_SUB: - return Value - Addend; - case ELF::R_MIPS_HI16: - // Get the higher 16-bits. Also add 1 if bit 15 is 1. - return ((Value + Addend + 0x8000) >> 16) & 0xffff; - case ELF::R_MIPS_LO16: - return (Value + Addend) & 0xffff; - case ELF::R_MIPS_CALL16: - case ELF::R_MIPS_GOT_DISP: - case ELF::R_MIPS_GOT_PAGE: { - uint8_t *LocalGOTAddr = - getSectionAddress(SectionToGOTMap[SectionID]) + SymOffset; - uint64_t GOTEntry = readBytesUnaligned(LocalGOTAddr, getGOTEntrySize()); - - Value += Addend; - if (Type == ELF::R_MIPS_GOT_PAGE) - Value = (Value + 0x8000) & ~0xffff; - - if (GOTEntry) - assert(GOTEntry == Value && - "GOT entry has two different addresses."); - else - writeBytesUnaligned(Value, LocalGOTAddr, getGOTEntrySize()); - - return (SymOffset - 0x7ff0) & 0xffff; - } - case ELF::R_MIPS_GOT_OFST: { - int64_t page = (Value + Addend + 0x8000) & ~0xffff; - return (Value + Addend - page) & 0xffff; - } - case ELF::R_MIPS_GPREL32: { - uint64_t GOTAddr = getSectionLoadAddress(SectionToGOTMap[SectionID]); - return Value + Addend - (GOTAddr + 0x7ff0); - } - case ELF::R_MIPS_PC16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0xffff; - } - case ELF::R_MIPS_PC32: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return Value + Addend - FinalAddress; - } - case ELF::R_MIPS_PC18_S3: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - (FinalAddress & ~0x7)) >> 3) & 0x3ffff; - } - case ELF::R_MIPS_PC19_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - (FinalAddress & ~0x3)) >> 2) & 0x7ffff; - } - case ELF::R_MIPS_PC21_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff; - } - case ELF::R_MIPS_PC26_S2: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff; - } - case ELF::R_MIPS_PCHI16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff; - } - case ELF::R_MIPS_PCLO16: { - uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset); - return (Value + Addend - FinalAddress) & 0xffff; - } - } - return 0; -} - -void RuntimeDyldELF::applyMIPSRelocation(uint8_t *TargetPtr, int64_t Value, - uint32_t Type) { - uint32_t Insn = readBytesUnaligned(TargetPtr, 4); - - switch (Type) { - default: - llvm_unreachable("Unknown relocation type!"); - break; - case ELF::R_MIPS_GPREL16: - case ELF::R_MIPS_HI16: - case ELF::R_MIPS_LO16: - case ELF::R_MIPS_PC16: - case ELF::R_MIPS_PCHI16: - case ELF::R_MIPS_PCLO16: - case ELF::R_MIPS_CALL16: - case ELF::R_MIPS_GOT_DISP: - case ELF::R_MIPS_GOT_PAGE: - case ELF::R_MIPS_GOT_OFST: - Insn = (Insn & 0xffff0000) | (Value & 0x0000ffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC18_S3: - Insn = (Insn & 0xfffc0000) | (Value & 0x0003ffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC19_S2: - Insn = (Insn & 0xfff80000) | (Value & 0x0007ffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_PC21_S2: - Insn = (Insn & 0xffe00000) | (Value & 0x001fffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_26: - case ELF::R_MIPS_PC26_S2: - Insn = (Insn & 0xfc000000) | (Value & 0x03ffffff); - writeBytesUnaligned(Insn, TargetPtr, 4); - break; - case ELF::R_MIPS_32: - case ELF::R_MIPS_GPREL32: - case ELF::R_MIPS_PC32: - writeBytesUnaligned(Value & 0xffffffff, TargetPtr, 4); - break; - case ELF::R_MIPS_64: - case ELF::R_MIPS_SUB: - writeBytesUnaligned(Value, TargetPtr, 8); - break; - } -} - // Return the .TOC. section and offset. Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj, ObjSectionToIDMap &LocalSections, @@ -1123,22 +873,6 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section, resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type, (uint32_t)(Addend & 0xffffffffL)); break; - case Triple::mips: // Fall through. - case Triple::mipsel: - case Triple::mips64: - case Triple::mips64el: - if (IsMipsO32ABI) - resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), - Type, (uint32_t)(Addend & 0xffffffffL)); - else if (IsMipsN32ABI) - resolveMIPSN32Relocation(Section, Offset, Value, Type, Addend, SymOffset, - SectionID); - else if (IsMipsN64ABI) - resolveMIPSN64Relocation(Section, Offset, Value, Type, Addend, SymOffset, - SectionID); - else - llvm_unreachable("Mips ABI not handled"); - break; case Triple::ppc: resolvePPC32Relocation(Section, Offset, Value, Type, Addend); break; |