AArch64: implement first relocation required for MCJIT

R_AARCH64_PCREL32 is present in even trivial .eh_frame sections and so
is required to compile any function without the "nounwind" attribute.

This change implements very basic infrastructure in the RuntimeDyldELF
file and allows (for example) the test-shift.ll MCJIT test to pass
on AArch64.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181131 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Tim Northover 2013-05-04 20:13:59 +00:00
parent bd121f5b3a
commit 85829bb98a
3 changed files with 45 additions and 0 deletions

View File

@ -269,6 +269,36 @@ void RuntimeDyldELF::resolveX86Relocation(const SectionEntry &Section,
}
}
void RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &Section,
uint64_t Offset,
uint64_t Value,
uint32_t Type,
int64_t Addend) {
uint32_t *TargetPtr = reinterpret_cast<uint32_t*>(Section.Address + Offset);
uint64_t FinalAddress = Section.LoadAddress + Offset;
DEBUG(dbgs() << "resolveAArch64Relocation, LocalAddress: 0x"
<< format("%llx", Section.Address + Offset)
<< " FinalAddress: 0x" << format("%llx",FinalAddress)
<< " Value: 0x" << format("%llx",Value)
<< " Type: 0x" << format("%x",Type)
<< " Addend: 0x" << format("%llx",Addend)
<< "\n");
switch (Type) {
default:
llvm_unreachable("Relocation type not implemented yet!");
break;
case ELF::R_AARCH64_PREL32: { // test-shift.ll (.eh_frame)
uint64_t Result = Value + Addend - FinalAddress;
assert(static_cast<int64_t>(Result) >= INT32_MIN &&
static_cast<int64_t>(Result) <= UINT32_MAX);
*TargetPtr = static_cast<uint32_t>(Result & 0xffffffffU);
break;
}
}
}
void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
uint64_t Offset,
uint32_t Value,
@ -616,6 +646,9 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
(uint32_t)(Value & 0xffffffffL), Type,
(uint32_t)(Addend & 0xffffffffL));
break;
case Triple::aarch64:
resolveAArch64Relocation(Section, Offset, Value, Type, Addend);
break;
case Triple::arm: // Fall through.
case Triple::thumb:
resolveARMRelocation(Section, Offset,

View File

@ -49,6 +49,12 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
uint32_t Type,
int32_t Addend);
void resolveAArch64Relocation(const SectionEntry &Section,
uint64_t Offset,
uint64_t Value,
uint32_t Type,
int64_t Addend);
void resolveARMRelocation(const SectionEntry &Section,
uint64_t Offset,
uint32_t Value,

View File

@ -81,6 +81,12 @@ static MCCodeGenInfo *createAArch64MCCodeGenInfo(StringRef TT, Reloc::Model RM,
if (CM == CodeModel::Default)
CM = CodeModel::Small;
else if (CM == CodeModel::JITDefault) {
// The default MCJIT memory managers make no guarantees about where they can
// find an executable page; JITed code needs to be able to refer to globals
// no matter how far away they are.
CM = CodeModel::Large;
}
X->InitMCCodeGenInfo(RM, CM, OL);
return X;