[binutils-gdb] LoongArch: Fix linker relaxation alignment
liu zhensong via Binutils-cvs <[email protected]> Mon, 6 Jul 2026 06:13:04 +0000 (GMT)
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7858cadd335b3ffbc8e0250c0c180253d9f09489 commit 7858cadd335b3ffbc8e0250c0c180253d9f09489 Author: mengqinggang <[email protected]> Date: Tue Jun 16 19:10:26 2026 +0800 LoongArch: Fix linker relaxation alignment When linking multiple objects, relaxation can cause alignment issues. Input section's output_offset is updated in relaxation without considering alignment. Update section output_offset by align_opwer. Diff: --- bfd/elfnn-loongarch.c | 24 +++--------------------- ld/testsuite/ld-loongarch-elf/relax-align-1.d | 13 +++++++++++++ ld/testsuite/ld-loongarch-elf/relax-align-1a.s | 5 +++++ ld/testsuite/ld-loongarch-elf/relax-align-1b.s | 3 +++ ld/testsuite/ld-loongarch-elf/relax.exp | 4 ++++ 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 9d9c68664bb..b7af2041238 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -5725,11 +5725,6 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec, uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); uint32_t rd = LARCH_GET_RD (pca); - /* This section's output_offset need to subtract the bytes of instructions - relaxed by the previous sections, so it needs to be updated beforehand. - size_input_section already took care of updating it after relaxation, - so we additionally update once here. */ - sec->output_offset = sec->output_section->size; bfd_vma pc = sec_addr (sec) + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); if (sym_sec == sec) @@ -5790,11 +5785,6 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec, uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4); uint32_t rd = LARCH_GET_RD (jirl); - /* This section's output_offset need to subtract the bytes of instructions - relaxed by the previous sections, so it needs to be updated beforehand. - size_input_section already took care of updating it after relaxation, - so we additionally update once here. */ - sec->output_offset = sec->output_section->size; bfd_vma pc = sec_addr (sec) + loongarch_calc_relaxed_addr (info, rel->r_offset); if (sym_sec == sec) @@ -5851,11 +5841,6 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec, bool *again ATTRIBUTE_UNUSED, bfd_vma max_alignment) { - /* This section's output_offset need to subtract the bytes of instructions - relaxed by the previous sections, so it needs to be updated beforehand. - size_input_section already took care of updating it after relaxation, - so we additionally update once here. */ - sec->output_offset = sec->output_section->size; bfd_vma pc = sec_addr (sec) + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); if (sym_sec == sec) @@ -6008,11 +5993,6 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec, uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset); uint32_t rd = LARCH_GET_RD (pca); - /* This section's output_offset need to subtract the bytes of instructions - relaxed by the previous sections, so it needs to be updated beforehand. - size_input_section already took care of updating it after relaxation, - so we additionally update once here. */ - sec->output_offset = sec->output_section->size; bfd_vma pc = sec_addr (sec) + loongarch_calc_relaxed_addr (info, rel_hi->r_offset); if (sym_sec == sec) @@ -6187,7 +6167,9 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, so we additionally update once here. */ /* update before tls trans and relax, or may cause same pcadd_hi20 address. */ - sec->output_offset = sec->output_section->size; + + sec->output_offset = align_power (sec->output_section->size, + sec->alignment_power); for (unsigned int i = 0; i < sec->reloc_count; i++) { diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-1.d b/ld/testsuite/ld-loongarch-elf/relax-align-1.d new file mode 100644 index 00000000000..5681efb16d1 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-align-1.d @@ -0,0 +1,13 @@ +#source: relax-align-1a.s +#source: relax-align-1b.s +#ld: -e0 +#objdump: -d + +#... +.*: 54000400 bl 4.*<f> +#... +.*[0|8]: 02c001ac addi.d \$t0, \$t1, 0 +#... +.*0: 02c005ac addi.d \$t0, \$t1, 1 +#... +.*0: 02c005ac addi.d \$t0, \$t1, 1 diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-1a.s b/ld/testsuite/ld-loongarch-elf/relax-align-1a.s new file mode 100644 index 00000000000..2b7f3ecb6be --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-align-1a.s @@ -0,0 +1,5 @@ +.text + call f +f: + .align 3 + addi.d $t0, $t1, 0 diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-1b.s b/ld/testsuite/ld-loongarch-elf/relax-align-1b.s new file mode 100644 index 00000000000..2ed480a6c1b --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relax-align-1b.s @@ -0,0 +1,3 @@ +addi.d $t0, $t1, 1 +.align 4 +addi.d $t0, $t1, 1 diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp index 7c32a65244c..31787a93967 100644 --- a/ld/testsuite/ld-loongarch-elf/relax.exp +++ b/ld/testsuite/ld-loongarch-elf/relax.exp @@ -46,6 +46,10 @@ proc run_partial_linking_align_test {} { } } +if [istarget loongarch*-*-*] { + run_dump_test "relax-align-1" +} + if [istarget loongarch64-*-*] { if [isbuild loongarch64-*-*] { run_dump_test "relax-align-ignore-start"