[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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user