mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[mips][rtdyld] Move MIPS relocation resolution to a subclass and implement N32 relocations
N32 relocations are only correct for individual relocations at the moment. Support for relocation composition will follow in a later patch. Patch By: Daniel Sanders Reviwers: vkalintiris, atanasyan Differential Revision: https://reviews.llvm.org/D27467 llvm-svn: 289532
This commit is contained in:
parent
e28496e7a4
commit
bb27e2f29f
@ -6,6 +6,7 @@ add_llvm_library(LLVMRuntimeDyld
|
|||||||
RuntimeDyldCOFF.cpp
|
RuntimeDyldCOFF.cpp
|
||||||
RuntimeDyldELF.cpp
|
RuntimeDyldELF.cpp
|
||||||
RuntimeDyldMachO.cpp
|
RuntimeDyldMachO.cpp
|
||||||
|
Targets/RuntimeDyldELFMips.cpp
|
||||||
|
|
||||||
DEPENDS
|
DEPENDS
|
||||||
intrinsics_gen
|
intrinsics_gen
|
||||||
|
@ -1023,10 +1023,11 @@ createRuntimeDyldCOFF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<RuntimeDyldELF>
|
static std::unique_ptr<RuntimeDyldELF>
|
||||||
createRuntimeDyldELF(RuntimeDyld::MemoryManager &MM,
|
createRuntimeDyldELF(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MM,
|
||||||
JITSymbolResolver &Resolver, bool ProcessAllSections,
|
JITSymbolResolver &Resolver, bool ProcessAllSections,
|
||||||
RuntimeDyldCheckerImpl *Checker) {
|
RuntimeDyldCheckerImpl *Checker) {
|
||||||
std::unique_ptr<RuntimeDyldELF> Dyld(new RuntimeDyldELF(MM, Resolver));
|
std::unique_ptr<RuntimeDyldELF> Dyld =
|
||||||
|
RuntimeDyldELF::create(Arch, MM, Resolver);
|
||||||
Dyld->setProcessAllSections(ProcessAllSections);
|
Dyld->setProcessAllSections(ProcessAllSections);
|
||||||
Dyld->setRuntimeDyldChecker(Checker);
|
Dyld->setRuntimeDyldChecker(Checker);
|
||||||
return Dyld;
|
return Dyld;
|
||||||
@ -1048,7 +1049,9 @@ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
|||||||
RuntimeDyld::loadObject(const ObjectFile &Obj) {
|
RuntimeDyld::loadObject(const ObjectFile &Obj) {
|
||||||
if (!Dyld) {
|
if (!Dyld) {
|
||||||
if (Obj.isELF())
|
if (Obj.isELF())
|
||||||
Dyld = createRuntimeDyldELF(MemMgr, Resolver, ProcessAllSections, Checker);
|
Dyld =
|
||||||
|
createRuntimeDyldELF(static_cast<Triple::ArchType>(Obj.getArch()),
|
||||||
|
MemMgr, Resolver, ProcessAllSections, Checker);
|
||||||
else if (Obj.isMachO())
|
else if (Obj.isMachO())
|
||||||
Dyld = createRuntimeDyldMachO(
|
Dyld = createRuntimeDyldMachO(
|
||||||
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
|
static_cast<Triple::ArchType>(Obj.getArch()), MemMgr, Resolver,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "RuntimeDyldELF.h"
|
#include "RuntimeDyldELF.h"
|
||||||
#include "RuntimeDyldCheckerImpl.h"
|
#include "RuntimeDyldCheckerImpl.h"
|
||||||
|
#include "Targets/RuntimeDyldELFMips.h"
|
||||||
#include "llvm/ADT/IntervalMap.h"
|
#include "llvm/ADT/IntervalMap.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/StringRef.h"
|
#include "llvm/ADT/StringRef.h"
|
||||||
@ -211,6 +212,21 @@ void RuntimeDyldELF::deregisterEHFrames() {
|
|||||||
RegisteredEHFrameSections.clear();
|
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>
|
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
||||||
RuntimeDyldELF::loadObject(const object::ObjectFile &O) {
|
RuntimeDyldELF::loadObject(const object::ObjectFile &O) {
|
||||||
if (auto ObjSectionToIDOrErr = loadObjectImpl(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) {
|
void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
|
||||||
if (Arch == Triple::UnknownArch ||
|
if (Arch == Triple::UnknownArch ||
|
||||||
!StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
|
!StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
|
||||||
@ -531,254 +529,6 @@ void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
|
|||||||
IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
|
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.
|
// Return the .TOC. section and offset.
|
||||||
Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,
|
Error RuntimeDyldELF::findPPC64TOCSection(const ELFObjectFileBase &Obj,
|
||||||
ObjSectionToIDMap &LocalSections,
|
ObjSectionToIDMap &LocalSections,
|
||||||
@ -1123,22 +873,6 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
|||||||
resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
|
resolveARMRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL), Type,
|
||||||
(uint32_t)(Addend & 0xffffffffL));
|
(uint32_t)(Addend & 0xffffffffL));
|
||||||
break;
|
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:
|
case Triple::ppc:
|
||||||
resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
|
resolvePPC32Relocation(Section, Offset, Value, Type, Addend);
|
||||||
break;
|
break;
|
||||||
|
@ -43,9 +43,6 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
|
void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
uint32_t Value, uint32_t Type, int32_t Addend);
|
uint32_t Value, uint32_t Type, int32_t Addend);
|
||||||
|
|
||||||
void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset,
|
|
||||||
uint32_t Value, uint32_t Type, int32_t Addend);
|
|
||||||
|
|
||||||
void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset,
|
void resolvePPC32Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend);
|
uint64_t Value, uint32_t Type, int64_t Addend);
|
||||||
|
|
||||||
@ -55,23 +52,6 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
|
void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend);
|
uint64_t Value, uint32_t Type, int64_t Addend);
|
||||||
|
|
||||||
void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset,
|
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
|
||||||
uint64_t SymOffset, SID SectionID);
|
|
||||||
void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset,
|
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
|
||||||
uint64_t SymOffset, SID SectionID);
|
|
||||||
|
|
||||||
int64_t evaluateMIPS32Relocation(const SectionEntry &Section, uint64_t Offset,
|
|
||||||
uint64_t Value, uint32_t Type);
|
|
||||||
int64_t evaluateMIPS64Relocation(const SectionEntry &Section,
|
|
||||||
uint64_t Offset, uint64_t Value,
|
|
||||||
uint32_t Type, int64_t Addend,
|
|
||||||
uint64_t SymOffset, SID SectionID);
|
|
||||||
|
|
||||||
void applyMIPSRelocation(uint8_t *TargetPtr, int64_t CalculatedValue,
|
|
||||||
uint32_t Type);
|
|
||||||
|
|
||||||
unsigned getMaxStubSize() override {
|
unsigned getMaxStubSize() override {
|
||||||
if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
|
if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
|
||||||
return 20; // movz; movk; movk; movk; br
|
return 20; // movz; movk; movk; movk; br
|
||||||
@ -104,9 +84,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
Error findOPDEntrySection(const ELFObjectFileBase &Obj,
|
Error findOPDEntrySection(const ELFObjectFileBase &Obj,
|
||||||
ObjSectionToIDMap &LocalSections,
|
ObjSectionToIDMap &LocalSections,
|
||||||
RelocationValueRef &Rel);
|
RelocationValueRef &Rel);
|
||||||
|
protected:
|
||||||
size_t getGOTEntrySize();
|
size_t getGOTEntrySize();
|
||||||
|
|
||||||
|
private:
|
||||||
SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
|
SectionEntry &getSection(unsigned SectionID) { return Sections[SectionID]; }
|
||||||
|
|
||||||
// Allocate no GOT entries for use in the given section.
|
// Allocate no GOT entries for use in the given section.
|
||||||
@ -143,10 +124,12 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
// that consume more than one slot)
|
// that consume more than one slot)
|
||||||
unsigned CurrentGOTIndex;
|
unsigned CurrentGOTIndex;
|
||||||
|
|
||||||
|
protected:
|
||||||
// A map from section to a GOT section that has entries for section's GOT
|
// A map from section to a GOT section that has entries for section's GOT
|
||||||
// relocations. (Mips64 specific)
|
// relocations. (Mips64 specific)
|
||||||
DenseMap<SID, SID> SectionToGOTMap;
|
DenseMap<SID, SID> SectionToGOTMap;
|
||||||
|
|
||||||
|
private:
|
||||||
// A map to avoid duplicate got entries (Mips64 specific)
|
// A map to avoid duplicate got entries (Mips64 specific)
|
||||||
StringMap<uint64_t> GOTSymbolOffsets;
|
StringMap<uint64_t> GOTSymbolOffsets;
|
||||||
|
|
||||||
@ -167,6 +150,10 @@ public:
|
|||||||
JITSymbolResolver &Resolver);
|
JITSymbolResolver &Resolver);
|
||||||
~RuntimeDyldELF() override;
|
~RuntimeDyldELF() override;
|
||||||
|
|
||||||
|
static std::unique_ptr<RuntimeDyldELF>
|
||||||
|
create(Triple::ArchType Arch, RuntimeDyld::MemoryManager &MemMgr,
|
||||||
|
JITSymbolResolver &Resolver);
|
||||||
|
|
||||||
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
std::unique_ptr<RuntimeDyld::LoadedObjectInfo>
|
||||||
loadObject(const object::ObjectFile &O) override;
|
loadObject(const object::ObjectFile &O) override;
|
||||||
|
|
||||||
|
312
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
Normal file
312
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.cpp
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
//===-- RuntimeDyldELFMips.cpp ---- ELF/Mips specific code. -----*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "RuntimeDyldELFMips.h"
|
||||||
|
#include "llvm/Support/ELF.h"
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "dyld"
|
||||||
|
|
||||||
|
void RuntimeDyldELFMips::resolveRelocation(const RelocationEntry &RE,
|
||||||
|
uint64_t Value) {
|
||||||
|
const SectionEntry &Section = Sections[RE.SectionID];
|
||||||
|
if (IsMipsO32ABI)
|
||||||
|
resolveMIPSO32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend);
|
||||||
|
else if (IsMipsN32ABI) {
|
||||||
|
resolveMIPSN32Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
|
||||||
|
RE.SymOffset, RE.SectionID);
|
||||||
|
} else if (IsMipsN64ABI)
|
||||||
|
resolveMIPSN64Relocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
|
||||||
|
RE.SymOffset, RE.SectionID);
|
||||||
|
else
|
||||||
|
llvm_unreachable("Mips ABI not handled");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RuntimeDyldELFMips::evaluateRelocation(const RelocationEntry &RE,
|
||||||
|
uint64_t Value,
|
||||||
|
uint64_t Addend) {
|
||||||
|
if (IsMipsN32ABI) {
|
||||||
|
const SectionEntry &Section = Sections[RE.SectionID];
|
||||||
|
Value = evaluateMIPS64Relocation(Section, RE.Offset, Value, RE.RelType,
|
||||||
|
Addend, RE.SymOffset, RE.SectionID);
|
||||||
|
return Value;
|
||||||
|
}
|
||||||
|
llvm_unreachable("Not reachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELFMips::applyRelocation(const RelocationEntry &RE,
|
||||||
|
uint64_t Value) {
|
||||||
|
if (IsMipsN32ABI) {
|
||||||
|
const SectionEntry &Section = Sections[RE.SectionID];
|
||||||
|
applyMIPSRelocation(Section.getAddressWithOffset(RE.Offset), Value,
|
||||||
|
RE.RelType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
llvm_unreachable("Not reachable");
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
RuntimeDyldELFMips::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 RuntimeDyldELFMips::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 RuntimeDyldELFMips::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELFMips::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 RuntimeDyldELFMips::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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELFMips::resolveMIPSO32Relocation(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() << "resolveMIPSO32Relocation, 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);
|
||||||
|
}
|
68
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h
Normal file
68
lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldELFMips.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
//===-- RuntimeDyldELFMips.h ---- ELF/Mips specific code. -------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDELFMIPS_H
|
||||||
|
#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_TARGETS_RUNTIMEDYLDELFMIPS_H
|
||||||
|
|
||||||
|
#include "../RuntimeDyldELF.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "dyld"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class RuntimeDyldELFMips : public RuntimeDyldELF {
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef uint64_t TargetPtrT;
|
||||||
|
|
||||||
|
RuntimeDyldELFMips(RuntimeDyld::MemoryManager &MM,
|
||||||
|
JITSymbolResolver &Resolver)
|
||||||
|
: RuntimeDyldELF(MM, Resolver) {}
|
||||||
|
|
||||||
|
void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void resolveMIPSO32Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
|
uint32_t Value, uint32_t Type, int32_t Addend);
|
||||||
|
void resolveMIPSN32Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
|
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||||
|
uint64_t SymOffset, SID SectionID);
|
||||||
|
void resolveMIPSN64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
|
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||||
|
uint64_t SymOffset, SID SectionID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// \brief A object file specific relocation resolver
|
||||||
|
/// \param RE The relocation to be resolved
|
||||||
|
/// \param Value Target symbol address to apply the relocation action
|
||||||
|
uint64_t evaluateRelocation(const RelocationEntry &RE, uint64_t Value,
|
||||||
|
uint64_t Addend);
|
||||||
|
|
||||||
|
/// \brief A object file specific relocation resolver
|
||||||
|
/// \param RE The relocation to be resolved
|
||||||
|
/// \param Value Target symbol address to apply the relocation action
|
||||||
|
void applyRelocation(const RelocationEntry &RE, uint64_t Value);
|
||||||
|
|
||||||
|
int64_t evaluateMIPS32Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
|
uint64_t Value, uint32_t Type);
|
||||||
|
int64_t evaluateMIPS64Relocation(const SectionEntry &Section,
|
||||||
|
uint64_t Offset, uint64_t Value,
|
||||||
|
uint32_t Type, int64_t Addend,
|
||||||
|
uint64_t SymOffset, SID SectionID);
|
||||||
|
|
||||||
|
void applyMIPSRelocation(uint8_t *TargetPtr, int64_t CalculatedValue,
|
||||||
|
uint32_t Type);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef DEBUG_TYPE
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user