[llvm] [RuntimeDyld] Add LoongArch support (PR #114741)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 7 04:54:18 PST 2024
================
@@ -645,6 +645,203 @@ void RuntimeDyldELF::resolveARMRelocation(const SectionEntry &Section,
}
}
+bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
+ unsigned SectionID, relocation_iterator RelI,
+ const RelocationValueRef &Value) {
+ uint64_t Address;
+ if (Value.SymbolName) {
+ auto Loc = GlobalSymbolTable.find(Value.SymbolName);
+ // Don't create direct branch for external symbols.
+ if (Loc == GlobalSymbolTable.end())
+ return false;
+ const auto &SymInfo = Loc->second;
+ Address =
+ uint64_t(Sections[SymInfo.getSectionID()].getLoadAddressWithOffset(
+ SymInfo.getOffset()));
+ } else {
+ Address = uint64_t(Sections[Value.SectionID].getLoadAddress());
+ }
+ uint64_t Offset = RelI->getOffset();
+ uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
+ if (!isInt<28>(Address + Value.Addend - SourceAddress))
+ return false;
+ resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
+ Value.Addend);
+ return true;
+}
+
+void RuntimeDyldELF::resolveLoongArch64Branch(unsigned SectionID,
+ const RelocationValueRef &Value,
+ relocation_iterator RelI,
+ StubMap &Stubs) {
+ LLVM_DEBUG(dbgs() << "\t\tThis is an LoongArch64 branch relocation.\n");
+ SectionEntry &Section = Sections[SectionID];
+ uint64_t Offset = RelI->getOffset();
+ unsigned RelType = RelI->getType();
+ // Look for an existing stub.
+ StubMap::const_iterator i = Stubs.find(Value);
+ if (i != Stubs.end()) {
+ resolveRelocation(Section, Offset,
+ (uint64_t)Section.getAddressWithOffset(i->second),
+ RelType, 0);
+ LLVM_DEBUG(dbgs() << " Stub function found\n");
+ } else if (!resolveLoongArch64ShortBranch(SectionID, RelI, Value)) {
+ // Create a new stub function.
+ LLVM_DEBUG(dbgs() << " Create a new stub function\n");
+ Stubs[Value] = Section.getStubOffset();
+ uint8_t *StubTargetAddr = createStubFunction(
+ Section.getAddressWithOffset(Section.getStubOffset()));
+ RelocationEntry LU12I_W(SectionID, StubTargetAddr - Section.getAddress(),
+ ELF::R_LARCH_ABS_HI20, Value.Addend);
+ RelocationEntry ORI(SectionID, StubTargetAddr - Section.getAddress() + 4,
+ ELF::R_LARCH_ABS_LO12, Value.Addend);
+ RelocationEntry LU32I_D(SectionID,
+ StubTargetAddr - Section.getAddress() + 8,
+ ELF::R_LARCH_ABS64_LO20, Value.Addend);
+ RelocationEntry LU52I_D(SectionID,
+ StubTargetAddr - Section.getAddress() + 12,
+ ELF::R_LARCH_ABS64_HI12, Value.Addend);
+ if (Value.SymbolName) {
+ addRelocationForSymbol(LU12I_W, Value.SymbolName);
+ addRelocationForSymbol(ORI, Value.SymbolName);
+ addRelocationForSymbol(LU32I_D, Value.SymbolName);
+ addRelocationForSymbol(LU52I_D, Value.SymbolName);
+ } else {
+ addRelocationForSection(LU12I_W, Value.SectionID);
+ addRelocationForSection(ORI, Value.SectionID);
+ addRelocationForSection(LU32I_D, Value.SectionID);
+ addRelocationForSection(LU52I_D, Value.SectionID);
+ }
+ resolveRelocation(Section, Offset,
+ reinterpret_cast<uint64_t>(Section.getAddressWithOffset(
+ Section.getStubOffset())),
+ RelType, 0);
+ Section.advanceStubOffset(getMaxStubSize());
+ }
+}
+
+// Returns extract bits Val[Hi:Lo].
+static inline uint32_t extractBits(uint64_t Val, uint32_t Hi, uint32_t Lo) {
+ return Hi == 63 ? Val >> Lo : (Val & (((1ULL << (Hi + 1)) - 1))) >> Lo;
+}
----------------
wangleiat wrote:
Yes, it needs to support extracting the entire 64-bit number.
https://github.com/llvm/llvm-project/pull/114741
More information about the llvm-commits
mailing list