Closed
Description
I find when I test mold in ArchLinux, something wrongs.
1,hi64 calculation error
The [63:32] bits should be PC-relative, too. The current codes seems only return val-relative.
diff --git a/elf/arch-loongarch.cc b/elf/arch-loongarch.cc
index b5bd0878..4bc60f57 100644
--- a/elf/arch-loongarch.cc
+++ b/elf/arch-loongarch.cc
@@ -66,12 +66,11 @@ static u64 hi64(u64 val, u64 pc) {
//
// Compensating all the sign-extensions is a bit complicated.
bool x = val & 0x800;
- bool y = (page(val + 0x800) - page(pc)) & 0x8000'0000;
-
- if (x && !y)
- return val - 0x1'0000'0000;
- if (!x && y)
- return val + 0x1'0000'0000;
+ val = page(val) - page(pc);
+ if (x)
+ val += 0x1000 - 0x1'0000'0000;
+ if (val & 0x8000'0000)
+ val += 0x1'0000'0000;
return val;
}
[1] https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/LoongArch.cpp#L158
[2] https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/elfnn-loongarch.c;#l2304
2, PCALA should set plt if sym is imported
PCALA used for a long call in -mcmodel=extreme mode. The sequence is "la.pcrel $rxx, $ryy, sym; jirl $ra, $rxx, 0"
So if the sym is imported, we also need add NEED_PLT.
@@ -587,6 +586,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
scan_dyn_absrel(ctx, sym, rel);
break;
case R_LARCH_B26:
+ case R_LARCH_PCALA_HI20:
if (sym.is_imported)
sym.flags |= NEEDS_PLT;
break;
@@ -620,7 +620,6 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
case R_LARCH_ABS_LO12:
case R_LARCH_ABS64_LO20:
case R_LARCH_ABS64_HI12:
- case R_LARCH_PCALA_HI20:
case R_LARCH_PCALA_LO12:
case R_LARCH_PCALA64_LO20:
case R_LARCH_PCALA64_HI12:
Metadata
Metadata
Assignees
Labels
No labels