Skip to content

Commit 6a61f79

Browse files
committed
[VE] a start with relocations for VE native, for JIT & Julia
1 parent 495c56f commit 6a61f79

File tree

2 files changed

+156
-0
lines changed

2 files changed

+156
-0
lines changed

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,154 @@ void RuntimeDyldELF::resolveBPFRelocation(const SectionEntry &Section,
911911
}
912912
}
913913

914+
void RuntimeDyldELF::resolveVERelocation(const SectionEntry &Section,
915+
uint64_t Offset, uint64_t Value,
916+
uint32_t Type, int64_t Addend,
917+
uint64_t SymOffset) {
918+
switch (Type) {
919+
default:
920+
llvm_unreachable("Relocation type not implemented yet!");
921+
break;
922+
case ELF::R_VE_NONE:
923+
break;
924+
case ELF::R_VE_REFLONG: {
925+
Value += Addend;
926+
assert((Type == ELF::R_VE_REFLONG && (Value <= UINT32_MAX)));
927+
uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
928+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
929+
TruncatedAddr;
930+
LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
931+
<< format("%p\n", Section.getAddressWithOffset(Offset)));
932+
break;
933+
}
934+
case ELF::R_VE_REFQUAD: {
935+
support::ulittle64_t::ref(Section.getAddressWithOffset(Offset)) =
936+
Value + Addend;
937+
LLVM_DEBUG(dbgs() << "Writing " << format("%p", (Value + Addend)) << " at "
938+
<< format("%p\n", Section.getAddressWithOffset(Offset)));
939+
break;
940+
}
941+
case ELF::R_VE_SREL32: {
942+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
943+
int64_t RealOffset = Value + Addend - FinalAddress;
944+
assert(isInt<32>(RealOffset));
945+
int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
946+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
947+
TruncOffset;
948+
break;
949+
}
950+
case ELF::R_VE_HI32: {
951+
Value += Addend;
952+
uint32_t TruncatedAddr = (Value >> 32);
953+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
954+
TruncatedAddr;
955+
LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
956+
<< format("%p\n", Section.getAddressWithOffset(Offset)));
957+
break;
958+
}
959+
case ELF::R_VE_LO32: {
960+
Value += Addend;
961+
uint32_t TruncatedAddr = (Value & 0xFFFFFFFF);
962+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
963+
TruncatedAddr;
964+
LLVM_DEBUG(dbgs() << "Writing " << format("%p", TruncatedAddr) << " at "
965+
<< format("%p\n", Section.getAddressWithOffset(Offset)));
966+
break;
967+
}
968+
case ELF::R_VE_PC_HI32: {
969+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
970+
int64_t RealOffset = Value + Addend - FinalAddress;
971+
int32_t TruncOffset = (RealOffset >> 32);
972+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
973+
TruncOffset;
974+
break;
975+
}
976+
case ELF::R_VE_PC_LO32: {
977+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
978+
int64_t RealOffset = Value + Addend - FinalAddress;
979+
int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
980+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
981+
TruncOffset;
982+
break;
983+
}
984+
case ELF::R_VE_GOT32:
985+
case ELF::R_VE_GOT_HI32:
986+
case ELF::R_VE_GOT_LO32: {
987+
llvm_unreachable("Relocation type not implemented yet!");
988+
}
989+
case ELF::R_VE_GOTOFF32: {
990+
// Compute Value - GOTBase.
991+
uint64_t GOTBase = 0;
992+
for (const auto &Section : Sections) {
993+
if (Section.getName() == ".got") {
994+
GOTBase = Section.getLoadAddressWithOffset(0);
995+
break;
996+
}
997+
}
998+
assert(GOTBase != 0 && "missing GOT");
999+
// add assertion that data segment size is 32bits, only
1000+
int64_t GOTOffset = Value - GOTBase + Addend;
1001+
int32_t TruncOffset = (GOTOffset & 0xFFFFFFFF);
1002+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) = TruncOffset;
1003+
break;
1004+
}
1005+
case ELF::R_VE_GOTOFF_HI32: {
1006+
// Compute Value - GOTBase.
1007+
uint64_t GOTBase = 0;
1008+
for (const auto &Section : Sections) {
1009+
if (Section.getName() == ".got") {
1010+
GOTBase = Section.getLoadAddressWithOffset(0);
1011+
break;
1012+
}
1013+
}
1014+
assert(GOTBase != 0 && "missing GOT");
1015+
int64_t GOTOffset = Value - GOTBase + Addend;
1016+
int32_t TruncOffset = (GOTOffset >> 32);
1017+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) = TruncOffset;
1018+
break;
1019+
}
1020+
case ELF::R_VE_GOTOFF_LO32: {
1021+
// Compute Value - GOTBase.
1022+
uint64_t GOTBase = 0;
1023+
for (const auto &Section : Sections) {
1024+
if (Section.getName() == ".got") {
1025+
GOTBase = Section.getLoadAddressWithOffset(0);
1026+
break;
1027+
}
1028+
}
1029+
assert(GOTBase != 0 && "missing GOT");
1030+
int64_t GOTOffset = Value - GOTBase + Addend;
1031+
int32_t TruncOffset = (GOTOffset & 0xFFFFFFFF);
1032+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) = TruncOffset;
1033+
break;
1034+
}
1035+
case ELF::R_VE_PLT32: {
1036+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1037+
int64_t RealOffset = Value + Addend - FinalAddress;
1038+
int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
1039+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
1040+
TruncOffset;
1041+
break;
1042+
}
1043+
case ELF::R_VE_PLT_HI32: {
1044+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1045+
int64_t RealOffset = Value + Addend - FinalAddress;
1046+
int32_t TruncOffset = (RealOffset >> 32);
1047+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
1048+
TruncOffset;
1049+
break;
1050+
}
1051+
case ELF::R_VE_PLT_LO32: {
1052+
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
1053+
int64_t RealOffset = Value + Addend - FinalAddress;
1054+
int32_t TruncOffset = (RealOffset & 0xFFFFFFFF);
1055+
support::ulittle32_t::ref(Section.getAddressWithOffset(Offset)) =
1056+
TruncOffset;
1057+
break;
1058+
}
1059+
}
1060+
}
1061+
9141062
// The target location for the relocation is described by RE.SectionID and
9151063
// RE.Offset. RE.SectionID can be used to find the SectionEntry. Each
9161064
// SectionEntry has three members describing its location.
@@ -975,6 +1123,9 @@ void RuntimeDyldELF::resolveRelocation(const SectionEntry &Section,
9751123
case Triple::bpfeb:
9761124
resolveBPFRelocation(Section, Offset, Value, Type, Addend);
9771125
break;
1126+
case Triple::ve:
1127+
resolveVERelocation(Section, Offset, Value, Type, Addend, SymOffset);
1128+
break;
9781129
default:
9791130
llvm_unreachable("Unsupported CPU type!");
9801131
}
@@ -1785,6 +1936,7 @@ size_t RuntimeDyldELF::getGOTEntrySize() {
17851936
case Triple::ppc64:
17861937
case Triple::ppc64le:
17871938
case Triple::systemz:
1939+
case Triple::ve:
17881940
Result = sizeof(uint64_t);
17891941
break;
17901942
case Triple::x86:

llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class RuntimeDyldELF : public RuntimeDyldImpl {
6060
void resolveBPFRelocation(const SectionEntry &Section, uint64_t Offset,
6161
uint64_t Value, uint32_t Type, int64_t Addend);
6262

63+
void resolveVERelocation(const SectionEntry &Section, uint64_t Offset,
64+
uint64_t Value, uint32_t Type, int64_t Addend,
65+
uint64_t SymOffset);
66+
6367
unsigned getMaxStubSize() const override {
6468
if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be)
6569
return 20; // movz; movk; movk; movk; br

0 commit comments

Comments
 (0)