[lldb][LoongArch] Fix expression function call failure

After upgrading the default code model from small to medium on
LoongArch, function calls using expression may fail. This is because the
function call instruction has changed from `bl` to `pcalau18i + jirl`,
but `RuntimeDyld` does not handle out-of-range jumps for this
instruction sequence.

This patch fixes: #136561

Reviewed By: SixWeining

Pull Request: https://github.com/llvm/llvm-project/pull/136563
This commit is contained in:
wanglei
2025-04-23 16:15:29 +08:00
committed by GitHub
parent d0cd6f3b93
commit 91edbe2231

View File

@@ -662,7 +662,18 @@ bool RuntimeDyldELF::resolveLoongArch64ShortBranch(
}
uint64_t Offset = RelI->getOffset();
uint64_t SourceAddress = Sections[SectionID].getLoadAddressWithOffset(Offset);
if (!isInt<28>(Address + Value.Addend - SourceAddress))
uint64_t Delta = Address + Value.Addend - SourceAddress;
// Normal call
if (RelI->getType() == ELF::R_LARCH_B26) {
if (!isInt<28>(Delta))
return false;
resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
Value.Addend);
return true;
}
// Medium call: R_LARCH_CALL36
// Range: [-128G - 0x20000, +128G - 0x20000)
if (((int64_t)Delta + 0x20000) != llvm::SignExtend64(Delta + 0x20000, 38))
return false;
resolveRelocation(Sections[SectionID], Offset, Address, RelI->getType(),
Value.Addend);
@@ -1743,7 +1754,8 @@ RuntimeDyldELF::processRelocationRef(
processSimpleRelocation(SectionID, Offset, RelType, Value);
}
} else if (Arch == Triple::loongarch64) {
if (RelType == ELF::R_LARCH_B26 && MemMgr.allowStubAllocation()) {
if ((RelType == ELF::R_LARCH_B26 || RelType == ELF::R_LARCH_CALL36) &&
MemMgr.allowStubAllocation()) {
resolveLoongArch64Branch(SectionID, Value, RelI, Stubs);
} else if (RelType == ELF::R_LARCH_GOT_PC_HI20 ||
RelType == ELF::R_LARCH_GOT_PC_LO12) {