-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lld][LoongArch] Handle extreme code model relocs according to psABI v2.30 #73387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Defer the compution of `negativeB` because adding 0x1000 to original `result` may yield a different `negativeB` value. Actually this issue was first reported by @rui314 at https://reviews.llvm.org/D138135#4568594. Note that even with this patch, the handling of R_LARCH_PCALA64_* relocs are NOT totally correct, because current approach assumes those four instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same 4K-page which is not always true. It is possible to document this assumption as a constraint in psABI in future. But at least this patch is necessary. See llvm#71907 and loongson-community/discussions#17 for details.
@llvm/pr-subscribers-lld-elf @llvm/pr-subscribers-lld Author: Lu Weining (SixWeining) ChangesDefer the compution of Note that even with this patch, the handling of R_LARCH_PCALA64_* relocs are NOT totally correct, because current approach assumes those four instructions (pcalau12i/addi.d/lu32i.d/lu52i.d) are in the same 4K-page which is not always true. It is possible to document this assumption as a constraint in psABI in future. But at least this patch is necessary. See #71907 and loongson-community/discussions#17 for details. Full diff: https://github.com/llvm/llvm-project/pull/73387.diff 2 Files Affected:
diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp
index 1c3e015efc1649a..9291ff14d674b64 100644
--- a/lld/ELF/Arch/LoongArch.cpp
+++ b/lld/ELF/Arch/LoongArch.cpp
@@ -157,10 +157,9 @@ uint64_t elf::getLoongArchPageDelta(uint64_t dest, uint64_t pc) {
// result = page(dest) - page(pc) + 0x1000
uint64_t result = getLoongArchPage(dest) - getLoongArchPage(pc);
bool negativeA = lo12(dest) > 0x7ff;
- bool negativeB = (result & 0x8000'0000) != 0;
-
if (negativeA)
result += 0x1000;
+ bool negativeB = (result & 0x8000'0000) != 0;
if (negativeA && !negativeB)
result -= 0x10000'0000;
else if (!negativeA && negativeB)
diff --git a/lld/test/ELF/loongarch-pc-aligned.s b/lld/test/ELF/loongarch-pc-aligned.s
index e7950400a5c8c45..742ac502e799804 100644
--- a/lld/test/ELF/loongarch-pc-aligned.s
+++ b/lld/test/ELF/loongarch-pc-aligned.s
@@ -260,31 +260,29 @@
# EXTREME15-NEXT: lu32i.d $t0, -349526
# EXTREME15-NEXT: lu52i.d $t0, $t0, -1093
-## FIXME: Correct %pc64_lo20 should be 0xfffff (-1) and %pc64_hi12 should be 0xfff (-1), but current values are:
-## page delta = 0x0000000000000000, page offset = 0x888
+## page delta = 0xffffffff00000000, page offset = 0x888
## %pc_lo12 = 0x888 = -1912
## %pc_hi20 = 0x00000 = 0
-## %pc64_lo20 = 0x00000 = 0
-## %pc64_hi12 = 0x00000 = 0
+## %pc64_lo20 = 0xfffff = -1
+## %pc64_hi12 = 0xfff = -1
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x0000000012344888 --section-start=.text=0x0000000012345678 -o %t/extreme16
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme16 | FileCheck %s --check-prefix=EXTREME16
# EXTREME16: addi.d $t0, $zero, -1912
# EXTREME16-NEXT: pcalau12i $t1, 0
-# EXTREME16-NEXT: lu32i.d $t0, 0
-# EXTREME16-NEXT: lu52i.d $t0, $t0, 0
+# EXTREME16-NEXT: lu32i.d $t0, -1
+# EXTREME16-NEXT: lu52i.d $t0, $t0, -1
-## FIXME: Correct %pc64_lo20 should be 0x00000 (0) and %pc64_hi12 should be 0x000 (0), but current values are:
-## page delta = 0xffffffff80000000, page offset = 0x888
+## page delta = 0x0000000080000000, page offset = 0x888
## %pc_lo12 = 0x888 = -1912
## %pc_hi20 = 0x80000 = -524288
-## %pc64_lo20 = 0xfffff = -1
-## %pc64_hi12 = 0xfff = -1
+## %pc64_lo20 = 0xfffff = 0
+## %pc64_hi12 = 0xfff = 0
# RUN: ld.lld %t/extreme.o --section-start=.rodata=0x000071238ffff888 --section-start=.text=0x0000712310000678 -o %t/extreme17
# RUN: llvm-objdump -d --no-show-raw-insn %t/extreme17 | FileCheck %s --check-prefix=EXTREME17
# EXTREME17: addi.d $t0, $zero, -1912
# EXTREME17-NEXT: pcalau12i $t1, -524288
-# EXTREME17-NEXT: lu32i.d $t0, -1
-# EXTREME17-NEXT: lu52i.d $t0, $t0, -1
+# EXTREME17-NEXT: lu32i.d $t0, 0
+# EXTREME17-NEXT: lu52i.d $t0, $t0, 0
#--- a.s
.rodata
|
With this PR, lld works the same as bfd and mold on those edge cases. See the test here https://gist.github.com/SixWeining/c5df38a2a21e18a32a82f199645ea5ab. |
It looks like bfd and mold use essentially the same logic. If you believe their logic is correct, why don't you just copy that logic too? Doing that eliminates the need to check the code to see if the new code would produce the same output as the others for all possible inputs. |
IMO we should document the "recommended practice" for R_LARCH_PCALA64_* in the ABI doc and use the same algorithm everywhere. |
@xry111 Agreed. That'd be very useful. |
Thanks, just now I update the PR to use the same logic as bfd and mold. |
Yes, I think that will happen in next psABI update. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's take a step forward?
Why is this fix partial? Can it be complete? I agree that psABI documenting the recommended algorithm will be great. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
The wording |
…u32i.d and lu52i.d are not in the same 4k-page
…n the same 4k-page
Ping. |
… psABI v2.30 In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12) should be applied on PC for these reloc types to avoid wrong relocation when the instruction sequence crosses a page boundary. The lld linker has already adapted the change. Make it for the bfd linker too. Link: https://github.com/loongson/la-abi-specs/releases/v2.30 Link: loongson-community/discussions#17 Link: llvm/llvm-project#73387 Signed-off-by: Xi Ruoyao <[email protected]>
… psABI v2.30 In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12) should be applied on PC for these reloc types to avoid wrong relocation when the instruction sequence crosses a page boundary. The lld linker has already adapted the change. Make it for the bfd linker too. Link: https://github.com/loongson/la-abi-specs/releases/v2.30 Link: loongson-community/discussions#17 Link: llvm/llvm-project#73387 Signed-off-by: Xi Ruoyao <[email protected]>
…v2.30 (llvm#73387) psABI v2.30 requires the extreme code model instructions sequence (pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent. See llvm#71907 and loongson-community/discussions#17 for details.
… psABI v2.30 In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12) should be applied on PC for these reloc types to avoid wrong relocation when the instruction sequence crosses a page boundary. The lld linker has already adapted the change. Make it for the bfd linker too. Link: https://github.com/loongson/la-abi-specs/releases/v2.30 Link: loongson-community/discussions#17 Link: llvm/llvm-project#73387 Signed-off-by: Xi Ruoyao <[email protected]>
…v2.30 (llvm#73387) psABI v2.30 requires the extreme code model instructions sequence (pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent. See llvm#71907 and loongson-community/discussions#17 for details. (cherry picked from commit 38394a3) Change-Id: I6ece8fdb9f9c7ac2baf086153e5b71865d93fd76
psABI v2.30 requires the extreme code model instructions sequence (pcalau12i+addi.d+lu32i.d+lu52i.d) to be adjacent.
See #71907 and loongson-community/discussions#17 for details.