mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
[Mips64] Add support for MCJIT for MIPS64r2 and MIPS64r6
Add support for resolving MIPS64r2 and MIPS64r6 relocations in MCJIT. Patch by Vladimir Radosavljevic. Differential Revision: http://reviews.llvm.org/D9667 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -149,6 +149,7 @@ RuntimeDyldImpl::loadObjectImpl(const object::ObjectFile &Obj) {
|
|||||||
// Save information about our target
|
// Save information about our target
|
||||||
Arch = (Triple::ArchType)Obj.getArch();
|
Arch = (Triple::ArchType)Obj.getArch();
|
||||||
IsTargetLittleEndian = Obj.isLittleEndian();
|
IsTargetLittleEndian = Obj.isLittleEndian();
|
||||||
|
setMipsABI(Obj);
|
||||||
|
|
||||||
// Compute the memory size required to load all sections to be loaded
|
// Compute the memory size required to load all sections to be loaded
|
||||||
// and pass this information to the memory manager
|
// and pass this information to the memory manager
|
||||||
@ -689,7 +690,7 @@ uint8_t *RuntimeDyldImpl::createStubFunction(uint8_t *Addr,
|
|||||||
// and stubs for branches Thumb - ARM and ARM - Thumb.
|
// and stubs for branches Thumb - ARM and ARM - Thumb.
|
||||||
writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label>
|
writeBytesUnaligned(0xe51ff004, Addr, 4); // ldr pc,<label>
|
||||||
return Addr + 4;
|
return Addr + 4;
|
||||||
} else if (Arch == Triple::mipsel || Arch == Triple::mips) {
|
} else if (IsMipsO32ABI) {
|
||||||
// 0: 3c190000 lui t9,%hi(addr).
|
// 0: 3c190000 lui t9,%hi(addr).
|
||||||
// 4: 27390000 addiu t9,t9,%lo(addr).
|
// 4: 27390000 addiu t9,t9,%lo(addr).
|
||||||
// 8: 03200008 jr t9.
|
// 8: 03200008 jr t9.
|
||||||
|
@ -507,6 +507,199 @@ void RuntimeDyldELF::resolveMIPSRelocation(const SectionEntry &Section,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELF::setMipsABI(const ObjectFile &Obj) {
|
||||||
|
if (!StringRef(Triple::getArchTypePrefix(Arch)).equals("mips")) {
|
||||||
|
IsMipsO32ABI = false;
|
||||||
|
IsMipsN64ABI = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned AbiVariant;
|
||||||
|
Obj.getPlatformFlags(AbiVariant);
|
||||||
|
IsMipsO32ABI = AbiVariant & ELF::EF_MIPS_ABI_O32;
|
||||||
|
IsMipsN64ABI = Obj.getFileFormatName().equals("ELF64-mips");
|
||||||
|
if (AbiVariant & ELF::EF_MIPS_ABI2)
|
||||||
|
llvm_unreachable("Mips N32 ABI is not supported yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELF::resolveMIPS64Relocation(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);
|
||||||
|
}
|
||||||
|
applyMIPS64Relocation(Section.Address + Offset, CalculatedValue, RelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.Address + Offset)
|
||||||
|
<< " FinalAddress: 0x"
|
||||||
|
<< format("%llx", Section.LoadAddress + 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, 8);
|
||||||
|
|
||||||
|
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, 8);
|
||||||
|
|
||||||
|
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.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - FinalAddress - 4) >> 2) & 0xffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PC18_S3: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - ((FinalAddress | 7) ^ 7)) >> 3) & 0x3ffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PC19_S2: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - FinalAddress) >> 2) & 0x7ffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PC21_S2: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - FinalAddress) >> 2) & 0x1fffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PC26_S2: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - FinalAddress) >> 2) & 0x3ffffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PCHI16: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return ((Value + Addend - FinalAddress + 0x8000) >> 16) & 0xffff;
|
||||||
|
}
|
||||||
|
case ELF::R_MIPS_PCLO16: {
|
||||||
|
uint64_t FinalAddress = (Section.LoadAddress + Offset);
|
||||||
|
return (Value + Addend - FinalAddress) & 0xffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeDyldELF::applyMIPS64Relocation(uint8_t *TargetPtr,
|
||||||
|
int64_t CalculatedValue,
|
||||||
|
uint32_t Type) {
|
||||||
|
uint32_t Insn = readBytesUnaligned(TargetPtr, 4);
|
||||||
|
|
||||||
|
switch (Type) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_32:
|
||||||
|
case ELF::R_MIPS_GPREL32:
|
||||||
|
writeBytesUnaligned(CalculatedValue & 0xffffffff, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_64:
|
||||||
|
case ELF::R_MIPS_SUB:
|
||||||
|
writeBytesUnaligned(CalculatedValue, TargetPtr, 8);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_26:
|
||||||
|
case ELF::R_MIPS_PC26_S2:
|
||||||
|
Insn = (Insn & 0xfc000000) | CalculatedValue;
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_GPREL16:
|
||||||
|
Insn = (Insn & 0xffff0000) | (CalculatedValue & 0xffff);
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_HI16:
|
||||||
|
case ELF::R_MIPS_LO16:
|
||||||
|
case ELF::R_MIPS_PCHI16:
|
||||||
|
case ELF::R_MIPS_PCLO16:
|
||||||
|
case ELF::R_MIPS_PC16:
|
||||||
|
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) | CalculatedValue;
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_PC18_S3:
|
||||||
|
Insn = (Insn & 0xfffc0000) | CalculatedValue;
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_PC19_S2:
|
||||||
|
Insn = (Insn & 0xfff80000) | CalculatedValue;
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
case ELF::R_MIPS_PC21_S2:
|
||||||
|
Insn = (Insn & 0xffe00000) | CalculatedValue;
|
||||||
|
writeBytesUnaligned(Insn, TargetPtr, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return the .TOC. section and offset.
|
// Return the .TOC. section and offset.
|
||||||
void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
|
void RuntimeDyldELF::findPPC64TOCSection(const ObjectFile &Obj,
|
||||||
ObjSectionToIDMap &LocalSections,
|
ObjSectionToIDMap &LocalSections,
|
||||||
@ -784,13 +977,13 @@ void RuntimeDyldELF::resolveRelocation(const RelocationEntry &RE,
|
|||||||
uint64_t Value) {
|
uint64_t Value) {
|
||||||
const SectionEntry &Section = Sections[RE.SectionID];
|
const SectionEntry &Section = Sections[RE.SectionID];
|
||||||
return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
|
return resolveRelocation(Section, RE.Offset, Value, RE.RelType, RE.Addend,
|
||||||
RE.SymOffset);
|
RE.SymOffset, RE.SectionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
||||||
uint64_t Offset, uint64_t Value,
|
uint64_t Offset, uint64_t Value,
|
||||||
uint32_t Type, int64_t Addend,
|
uint32_t Type, int64_t Addend,
|
||||||
uint64_t SymOffset) {
|
uint64_t SymOffset, SID SectionID) {
|
||||||
switch (Arch) {
|
switch (Arch) {
|
||||||
case Triple::x86_64:
|
case Triple::x86_64:
|
||||||
resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
|
resolveX86_64Relocation(Section, Offset, Value, Type, Addend, SymOffset);
|
||||||
@ -812,8 +1005,16 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
|
|||||||
break;
|
break;
|
||||||
case Triple::mips: // Fall through.
|
case Triple::mips: // Fall through.
|
||||||
case Triple::mipsel:
|
case Triple::mipsel:
|
||||||
|
case Triple::mips64:
|
||||||
|
case Triple::mips64el:
|
||||||
|
if (IsMipsO32ABI)
|
||||||
resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
|
resolveMIPSRelocation(Section, Offset, (uint32_t)(Value & 0xffffffffL),
|
||||||
Type, (uint32_t)(Addend & 0xffffffffL));
|
Type, (uint32_t)(Addend & 0xffffffffL));
|
||||||
|
else if (IsMipsN64ABI)
|
||||||
|
resolveMIPS64Relocation(Section, Offset, Value, Type, Addend, SymOffset,
|
||||||
|
SectionID);
|
||||||
|
else
|
||||||
|
llvm_unreachable("Mips ABI not handled");
|
||||||
break;
|
break;
|
||||||
case Triple::ppc64: // Fall through.
|
case Triple::ppc64: // Fall through.
|
||||||
case Triple::ppc64le:
|
case Triple::ppc64le:
|
||||||
@ -999,7 +1200,7 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
|
|||||||
}
|
}
|
||||||
processSimpleRelocation(SectionID, Offset, RelType, Value);
|
processSimpleRelocation(SectionID, Offset, RelType, Value);
|
||||||
}
|
}
|
||||||
} else if ((Arch == Triple::mipsel || Arch == Triple::mips)) {
|
} else if (IsMipsO32ABI) {
|
||||||
uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
|
uint32_t *Placeholder = reinterpret_cast<uint32_t*>(computePlaceholderAddress(SectionID, Offset));
|
||||||
if (RelType == ELF::R_MIPS_26) {
|
if (RelType == ELF::R_MIPS_26) {
|
||||||
// This is an Mips branch relocation, need to use a stub function.
|
// This is an Mips branch relocation, need to use a stub function.
|
||||||
@ -1054,6 +1255,23 @@ relocation_iterator RuntimeDyldELF::processRelocationRef(
|
|||||||
Value.Addend += *Placeholder;
|
Value.Addend += *Placeholder;
|
||||||
processSimpleRelocation(SectionID, Offset, RelType, Value);
|
processSimpleRelocation(SectionID, Offset, RelType, Value);
|
||||||
}
|
}
|
||||||
|
} else if (IsMipsN64ABI) {
|
||||||
|
uint32_t r_type = RelType & 0xff;
|
||||||
|
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);
|
||||||
|
if (r_type == ELF::R_MIPS_CALL16 || r_type == ELF::R_MIPS_GOT_PAGE
|
||||||
|
|| r_type == ELF::R_MIPS_GOT_DISP) {
|
||||||
|
StringMap<uint64_t>::iterator i = GOTSymbolOffsets.find(TargetName);
|
||||||
|
if (i != GOTSymbolOffsets.end())
|
||||||
|
RE.SymOffset = i->second;
|
||||||
|
else {
|
||||||
|
RE.SymOffset = allocateGOTEntries(SectionID, 1);
|
||||||
|
GOTSymbolOffsets[TargetName] = RE.SymOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Value.SymbolName)
|
||||||
|
addRelocationForSymbol(RE, Value.SymbolName);
|
||||||
|
else
|
||||||
|
addRelocationForSection(RE, Value.SectionID);
|
||||||
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
|
} else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) {
|
||||||
if (RelType == ELF::R_PPC64_REL24) {
|
if (RelType == ELF::R_PPC64_REL24) {
|
||||||
// Determine ABI variant in use for this object.
|
// Determine ABI variant in use for this object.
|
||||||
@ -1356,9 +1574,18 @@ size_t RuntimeDyldELF::getGOTEntrySize() {
|
|||||||
case Triple::x86:
|
case Triple::x86:
|
||||||
case Triple::arm:
|
case Triple::arm:
|
||||||
case Triple::thumb:
|
case Triple::thumb:
|
||||||
|
Result = sizeof(uint32_t);
|
||||||
|
break;
|
||||||
case Triple::mips:
|
case Triple::mips:
|
||||||
case Triple::mipsel:
|
case Triple::mipsel:
|
||||||
|
case Triple::mips64:
|
||||||
|
case Triple::mips64el:
|
||||||
|
if (IsMipsO32ABI)
|
||||||
Result = sizeof(uint32_t);
|
Result = sizeof(uint32_t);
|
||||||
|
else if (IsMipsN64ABI)
|
||||||
|
Result = sizeof(uint64_t);
|
||||||
|
else
|
||||||
|
llvm_unreachable("Mips ABI not handled");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
llvm_unreachable("Unsupported CPU type!");
|
llvm_unreachable("Unsupported CPU type!");
|
||||||
@ -1413,6 +1640,20 @@ void RuntimeDyldELF::finalizeLoad(const ObjectFile &Obj,
|
|||||||
// For now, initialize all GOT entries to zero. We'll fill them in as
|
// For now, initialize all GOT entries to zero. We'll fill them in as
|
||||||
// needed when GOT-based relocations are applied.
|
// needed when GOT-based relocations are applied.
|
||||||
memset(Addr, 0, TotalSize);
|
memset(Addr, 0, TotalSize);
|
||||||
|
if (IsMipsN64ABI) {
|
||||||
|
// To correctly resolve Mips GOT relocations, we need a mapping from
|
||||||
|
// object's sections to GOTs.
|
||||||
|
for (section_iterator SI = Obj.section_begin(), SE = Obj.section_end();
|
||||||
|
SI != SE; ++SI) {
|
||||||
|
if (SI->relocation_begin() != SI->relocation_end()) {
|
||||||
|
section_iterator RelocatedSection = SI->getRelocatedSection();
|
||||||
|
ObjSectionToIDMap::iterator i = SectionMap.find(*RelocatedSection);
|
||||||
|
assert (i != SectionMap.end());
|
||||||
|
SectionToGOTMap[i->second] = GOTSectionID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GOTSymbolOffsets.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for and record the EH frame section.
|
// Look for and record the EH frame section.
|
||||||
|
@ -25,7 +25,7 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
|
|
||||||
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
|
void resolveRelocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||||
uint64_t SymOffset = 0);
|
uint64_t SymOffset = 0, SID SectionID = 0);
|
||||||
|
|
||||||
void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
|
void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
uint64_t Value, uint32_t Type, int64_t Addend,
|
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||||
@ -49,12 +49,24 @@ 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 resolveMIPS64Relocation(const SectionEntry &Section, uint64_t Offset,
|
||||||
|
uint64_t Value, uint32_t Type, int64_t Addend,
|
||||||
|
uint64_t SymOffset, SID SectionID);
|
||||||
|
|
||||||
|
int64_t evaluateMIPS64Relocation(const SectionEntry &Section,
|
||||||
|
uint64_t Offset, uint64_t Value,
|
||||||
|
uint32_t Type, int64_t Addend,
|
||||||
|
uint64_t SymOffset, SID SectionID);
|
||||||
|
|
||||||
|
void applyMIPS64Relocation(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
|
||||||
if (Arch == Triple::arm || Arch == Triple::thumb)
|
if (Arch == Triple::arm || Arch == Triple::thumb)
|
||||||
return 8; // 32-bit instruction and 32-bit address
|
return 8; // 32-bit instruction and 32-bit address
|
||||||
else if (Arch == Triple::mipsel || Arch == Triple::mips)
|
else if (IsMipsO32ABI)
|
||||||
return 16;
|
return 16;
|
||||||
else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
|
else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le)
|
||||||
return 44;
|
return 44;
|
||||||
@ -73,6 +85,8 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMipsABI(const ObjectFile &Obj) override;
|
||||||
|
|
||||||
void findPPC64TOCSection(const ObjectFile &Obj,
|
void findPPC64TOCSection(const ObjectFile &Obj,
|
||||||
ObjSectionToIDMap &LocalSections,
|
ObjSectionToIDMap &LocalSections,
|
||||||
RelocationValueRef &Rel);
|
RelocationValueRef &Rel);
|
||||||
@ -114,6 +128,13 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
|
|||||||
// that consume more than one slot)
|
// that consume more than one slot)
|
||||||
unsigned CurrentGOTIndex;
|
unsigned CurrentGOTIndex;
|
||||||
|
|
||||||
|
// A map from section to a GOT section that has entries for section's GOT
|
||||||
|
// relocations. (Mips64 specific)
|
||||||
|
DenseMap<SID, SID> SectionToGOTMap;
|
||||||
|
|
||||||
|
// A map to avoid duplicate got entries (Mips64 specific)
|
||||||
|
StringMap<uint64_t> GOTSymbolOffsets;
|
||||||
|
|
||||||
// When a module is loaded we save the SectionID of the EH frame section
|
// When a module is loaded we save the SectionID of the EH frame section
|
||||||
// in a table until we receive a request to register all unregistered
|
// in a table until we receive a request to register all unregistered
|
||||||
// EH frame sections with the memory manager.
|
// EH frame sections with the memory manager.
|
||||||
|
@ -236,6 +236,8 @@ protected:
|
|||||||
|
|
||||||
Triple::ArchType Arch;
|
Triple::ArchType Arch;
|
||||||
bool IsTargetLittleEndian;
|
bool IsTargetLittleEndian;
|
||||||
|
bool IsMipsO32ABI;
|
||||||
|
bool IsMipsN64ABI;
|
||||||
|
|
||||||
// True if all sections should be passed to the memory manager, false if only
|
// True if all sections should be passed to the memory manager, false if only
|
||||||
// sections containing relocations should be. Defaults to 'false'.
|
// sections containing relocations should be. Defaults to 'false'.
|
||||||
@ -303,6 +305,11 @@ protected:
|
|||||||
*(Addr + 7) = Value & 0xFF;
|
*(Addr + 7) = Value & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setMipsABI(const ObjectFile &Obj) {
|
||||||
|
IsMipsO32ABI = false;
|
||||||
|
IsMipsN64ABI = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Endian-aware read Read the least significant Size bytes from Src.
|
/// Endian-aware read Read the least significant Size bytes from Src.
|
||||||
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const;
|
uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const;
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ extern "C" void LLVMInitializeMipsTargetInfo() {
|
|||||||
/*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel");
|
/*HasJIT=*/true> Y(TheMipselTarget, "mipsel", "Mipsel");
|
||||||
|
|
||||||
RegisterTarget<Triple::mips64,
|
RegisterTarget<Triple::mips64,
|
||||||
/*HasJIT=*/false> A(TheMips64Target, "mips64", "Mips64 [experimental]");
|
/*HasJIT=*/true> A(TheMips64Target, "mips64", "Mips64 [experimental]");
|
||||||
|
|
||||||
RegisterTarget<Triple::mips64el,
|
RegisterTarget<Triple::mips64el,
|
||||||
/*HasJIT=*/false> B(TheMips64elTarget,
|
/*HasJIT=*/true> B(TheMips64elTarget,
|
||||||
"mips64el", "Mips64el [experimental]");
|
"mips64el", "Mips64el [experimental]");
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386
|
; XFAIL: mips-, mipsel-, i686, i386
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -relocation-model=pic -code-model=large %s
|
; RUN: %lli -relocation-model=pic -code-model=large %s
|
||||||
; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan
|
; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan
|
||||||
declare i8* @__cxa_allocate_exception(i64)
|
declare i8* @__cxa_allocate_exception(i64)
|
||||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
declare void @__cxa_throw(i8*, i8*, i8*)
|
||||||
declare i32 @__gxx_personality_v0(...)
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -relocation-model=pic -code-model=small %s
|
; RUN: %lli -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan
|
; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan
|
||||||
declare i8* @__cxa_allocate_exception(i64)
|
declare i8* @__cxa_allocate_exception(i64)
|
||||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
declare void @__cxa_throw(i8*, i8*, i8*)
|
||||||
declare i32 @__gxx_personality_v0(...)
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386
|
; XFAIL: mips-, mipsel-, i686, i386
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386, arm
|
; XFAIL: mips-, mipsel-, i686, i386, arm
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386, arm
|
; XFAIL: mips-, mipsel-, i686, i386, arm
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@count = global i32 1, align 4
|
@count = global i32 1, align 4
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
|
; RUN: %lli -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
||||||
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
|
; RUN: %lli -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, i686, i386, aarch64, arm
|
; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm
|
||||||
|
|
||||||
define i32 @main() nounwind {
|
define i32 @main() nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@count = global i32 1, align 4
|
@count = global i32 1, align 4
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -O0 -relocation-model=pic -code-model=small %s
|
; RUN: %lli -O0 -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
||||||
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386
|
; XFAIL: mips-, mipsel-, i686, i386
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=large %s
|
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=large %s
|
||||||
; XFAIL: cygwin, win32, mingw, mips, i686, i386, aarch64, arm, asan, msan
|
; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, aarch64, arm, asan, msan
|
||||||
declare i8* @__cxa_allocate_exception(i64)
|
declare i8* @__cxa_allocate_exception(i64)
|
||||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
declare void @__cxa_throw(i8*, i8*, i8*)
|
||||||
declare i32 @__gxx_personality_v0(...)
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s
|
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: cygwin, win32, mingw, mips, i686, i386, darwin, aarch64, arm, asan, msan
|
; XFAIL: cygwin, win32, mingw, mips-, mipsel-, i686, i386, darwin, aarch64, arm, asan, msan
|
||||||
declare i8* @__cxa_allocate_exception(i64)
|
declare i8* @__cxa_allocate_exception(i64)
|
||||||
declare void @__cxa_throw(i8*, i8*, i8*)
|
declare void @__cxa_throw(i8*, i8*, i8*)
|
||||||
declare i32 @__gxx_personality_v0(...)
|
declare i32 @__gxx_personality_v0(...)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386
|
; XFAIL: mips-, mipsel-, i686, i386
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386, arm
|
; XFAIL: mips-, mipsel-, i686, i386, arm
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target%exeext -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, i686, i386, arm
|
; XFAIL: mips-, mipsel-, i686, i386, arm
|
||||||
|
|
||||||
declare i32 @FB()
|
declare i32 @FB()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@count = global i32 1, align 4
|
@count = global i32 1, align 4
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
|
; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
||||||
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
|
; RUN: %lli -jit-kind=orc-mcjit -disable-lazy-compilation=false -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, i686, i386, aarch64, arm
|
; XFAIL: mips-, mipsel-, i686, i386, aarch64, arm
|
||||||
|
|
||||||
define i32 @main() nounwind {
|
define i32 @main() nounwind {
|
||||||
entry:
|
entry:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
; RUN: %lli -jit-kind=orc-mcjit -relocation-model=pic -code-model=small %s > /dev/null
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@count = global i32 1, align 4
|
@count = global i32 1, align 4
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: %lli -jit-kind=orc-mcjit -O0 -relocation-model=pic -code-model=small %s
|
; RUN: %lli -jit-kind=orc-mcjit -O0 -relocation-model=pic -code-model=small %s
|
||||||
; XFAIL: mips, aarch64, arm, i686, i386
|
; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386
|
||||||
|
|
||||||
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
@.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
|
||||||
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
@ptr = global i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0), align 4
|
||||||
|
@ -0,0 +1,155 @@
|
|||||||
|
# RUN: llvm-mc -triple=mips64el-unknown-linux -relocation-model=pic -code-model=small -filetype=obj -o %T/test_ELF_Mips64N64.o %s
|
||||||
|
# RUN: llc -mtriple=mips64el-unknown-linux -relocation-model=pic -filetype=obj -o %T/test_ELF_ExternalFunction_Mips64N64.o %S/Inputs/ExternalFunction.ll
|
||||||
|
# RUN: llvm-rtdyld -triple=mips64el-unknown-linux -verify -map-section test_ELF_Mips64N64.o,.text=0x1000 -map-section test_ELF_ExternalFunction_Mips64N64.o,.text=0x10000 -check=%s %/T/test_ELF_Mips64N64.o %T/test_ELF_ExternalFunction_Mips64N64.o
|
||||||
|
|
||||||
|
.text
|
||||||
|
.abicalls
|
||||||
|
.section .mdebug.abi64,"",@progbits
|
||||||
|
.nan legacy
|
||||||
|
.file "ELF_Mips64N64_PIC_relocations.ll"
|
||||||
|
.text
|
||||||
|
.globl bar
|
||||||
|
.align 3
|
||||||
|
.type bar,@function
|
||||||
|
.set nomicromips
|
||||||
|
.set nomips16
|
||||||
|
.ent bar
|
||||||
|
bar:
|
||||||
|
.frame $fp,40,$ra
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
.set noat
|
||||||
|
daddiu $sp, $sp, -40
|
||||||
|
sd $ra, 32($sp)
|
||||||
|
sd $fp, 24($sp)
|
||||||
|
move $fp, $sp
|
||||||
|
sd $4, 16($fp)
|
||||||
|
lb $2, 0($4)
|
||||||
|
sd $4, 8($fp)
|
||||||
|
|
||||||
|
# Test R_MIPS_26 relocation.
|
||||||
|
# rtdyld-check: decode_operand(insn1, 0)[25:0] = foo
|
||||||
|
insn1:
|
||||||
|
jal foo
|
||||||
|
nop
|
||||||
|
|
||||||
|
# Test R_MIPS_PC16 relocation.
|
||||||
|
# rtdyld-check: decode_operand(insn2, 1)[15:0] = foo - insn2
|
||||||
|
insn2:
|
||||||
|
bal foo
|
||||||
|
nop
|
||||||
|
|
||||||
|
move $sp, $fp
|
||||||
|
ld $ra, 32($sp)
|
||||||
|
ld $fp, 24($sp)
|
||||||
|
daddiu $sp, $sp, 32
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
|
.set at
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
.end bar
|
||||||
|
$func_end0:
|
||||||
|
.size bar, ($func_end0)-bar
|
||||||
|
|
||||||
|
.globl main
|
||||||
|
.align 3
|
||||||
|
.type main,@function
|
||||||
|
.set nomicromips
|
||||||
|
.set nomips16
|
||||||
|
.ent main
|
||||||
|
main:
|
||||||
|
.frame $fp,32,$ra
|
||||||
|
.mask 0x00000000,0
|
||||||
|
.fmask 0x00000000,0
|
||||||
|
.set noreorder
|
||||||
|
.set nomacro
|
||||||
|
.set noat
|
||||||
|
daddiu $sp, $sp, -32
|
||||||
|
sd $ra, 24($sp)
|
||||||
|
sd $fp, 16($sp)
|
||||||
|
sd $gp, 8($sp)
|
||||||
|
move $fp, $sp
|
||||||
|
|
||||||
|
# Check upper 16-bits of offset between the address of main function
|
||||||
|
# and the global offset table.
|
||||||
|
# rtdyld-check: decode_operand(insn3, 1)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main + 0x8000)[31:16]
|
||||||
|
insn3:
|
||||||
|
lui $1, %hi(%neg(%gp_rel(main)))
|
||||||
|
daddu $1, $1, $25
|
||||||
|
|
||||||
|
# Check lower 16-bits of offset between the address of main function
|
||||||
|
# and the global offset table.
|
||||||
|
# rtdyld-check: decode_operand(insn4, 2)[15:0] = ((section_addr(test_ELF_Mips64N64.o, .got) + 0x7ff0) - main)[15:0]
|
||||||
|
insn4:
|
||||||
|
daddiu $1, $1, %lo(%neg(%gp_rel(main)))
|
||||||
|
sw $zero, 4($fp)
|
||||||
|
|
||||||
|
# $gp register contains address of the .got section + 0x7FF0. 0x7FF0 is
|
||||||
|
# the offset of $gp from the beginning of the .got section. Check that we are
|
||||||
|
# loading address of the page pointer from correct offset. In this case
|
||||||
|
# the page pointer is the first entry in the .got section, so offset will be
|
||||||
|
# 0 - 0x7FF0.
|
||||||
|
# rtdyld-check: decode_operand(insn5, 2)[15:0] = 0x8010
|
||||||
|
#
|
||||||
|
# Check that the global offset table contains the page pointer.
|
||||||
|
# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got)) = (_str + 0x8000) & 0xffffffffffff0000
|
||||||
|
insn5:
|
||||||
|
ld $25, %got_page(_str)($1)
|
||||||
|
|
||||||
|
# Check the offset of _str from the page pointer.
|
||||||
|
# rtdyld-check: decode_operand(insn6, 2)[15:0] = _str[15:0]
|
||||||
|
insn6:
|
||||||
|
daddiu $25, $25, %got_ofst(_str)
|
||||||
|
|
||||||
|
# Check that we are loading address of var from correct offset. In this case
|
||||||
|
# var is the second entry in the .got section, so offset will be 8 - 0x7FF0.
|
||||||
|
# rtdyld-check: decode_operand(insn7, 2)[15:0] = 0x8018
|
||||||
|
#
|
||||||
|
# Check that the global offset table contains the address of the var.
|
||||||
|
# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got) + 8) = var
|
||||||
|
insn7:
|
||||||
|
ld $2, %got_disp(var)($1)
|
||||||
|
sd $25, 0($2)
|
||||||
|
|
||||||
|
# Check that we are loading address of bar from correct offset. In this case
|
||||||
|
# bar is the third entry in the .got section, so offset will be 16 - 0x7FF0.
|
||||||
|
# rtdyld-check: decode_operand(insn8, 2)[15:0] = 0x8020
|
||||||
|
#
|
||||||
|
# Check that the global offset table contains the address of the bar.
|
||||||
|
# rtdyld-check: *{8}(section_addr(test_ELF_Mips64N64.o, .got) + 16) = bar
|
||||||
|
insn8:
|
||||||
|
ld $2, %call16(bar)($1)
|
||||||
|
|
||||||
|
move $4, $25
|
||||||
|
move $gp, $1
|
||||||
|
move $25, $2
|
||||||
|
jalr $25
|
||||||
|
nop
|
||||||
|
move $sp, $fp
|
||||||
|
ld $gp, 8($sp)
|
||||||
|
ld $fp, 16($sp)
|
||||||
|
ld $ra, 24($sp)
|
||||||
|
daddiu $sp, $sp, 32
|
||||||
|
jr $ra
|
||||||
|
nop
|
||||||
|
.set at
|
||||||
|
.set macro
|
||||||
|
.set reorder
|
||||||
|
.end main
|
||||||
|
$func_end1:
|
||||||
|
.size main, ($func_end1)-main
|
||||||
|
|
||||||
|
.type _str,@object
|
||||||
|
.section .rodata.str1.1,"aMS",@progbits,1
|
||||||
|
_str:
|
||||||
|
.asciz "test"
|
||||||
|
.size _str, 5
|
||||||
|
|
||||||
|
.type var,@object
|
||||||
|
.comm var,8,8
|
||||||
|
|
||||||
|
.section ".note.GNU-stack","",@progbits
|
||||||
|
.text
|
@ -0,0 +1,4 @@
|
|||||||
|
define void @foo() {
|
||||||
|
entry:
|
||||||
|
ret void
|
||||||
|
}
|
3
test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg
Normal file
3
test/ExecutionEngine/RuntimeDyld/Mips/lit.local.cfg
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
if not 'Mips' in config.root.targets:
|
||||||
|
config.unsupported = True
|
||||||
|
|
@ -127,6 +127,8 @@ protected:
|
|||||||
SupportedArchs.push_back(Triple::aarch64);
|
SupportedArchs.push_back(Triple::aarch64);
|
||||||
SupportedArchs.push_back(Triple::arm);
|
SupportedArchs.push_back(Triple::arm);
|
||||||
SupportedArchs.push_back(Triple::mips);
|
SupportedArchs.push_back(Triple::mips);
|
||||||
|
SupportedArchs.push_back(Triple::mips64);
|
||||||
|
SupportedArchs.push_back(Triple::mips64el);
|
||||||
SupportedArchs.push_back(Triple::x86);
|
SupportedArchs.push_back(Triple::x86);
|
||||||
SupportedArchs.push_back(Triple::x86_64);
|
SupportedArchs.push_back(Triple::x86_64);
|
||||||
|
|
||||||
|
@ -298,6 +298,8 @@ protected:
|
|||||||
SupportedArchs.push_back(Triple::arm);
|
SupportedArchs.push_back(Triple::arm);
|
||||||
SupportedArchs.push_back(Triple::mips);
|
SupportedArchs.push_back(Triple::mips);
|
||||||
SupportedArchs.push_back(Triple::mipsel);
|
SupportedArchs.push_back(Triple::mipsel);
|
||||||
|
SupportedArchs.push_back(Triple::mips64);
|
||||||
|
SupportedArchs.push_back(Triple::mips64el);
|
||||||
SupportedArchs.push_back(Triple::x86);
|
SupportedArchs.push_back(Triple::x86);
|
||||||
SupportedArchs.push_back(Triple::x86_64);
|
SupportedArchs.push_back(Triple::x86_64);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user