Skip to content

Commit 792e4d2

Browse files
xen0nLuffy-tsai
authored andcommitted
LoongArch: Un-skip cross-segment alignment compensation during relax pass 2
It turned out wrong to skip compensating for segment alignment if the current section is closed for deletion, as my recent system update with binutils trunk revealed link failures of many high-profile packages such as ffmpeg, numpy and wxGTK -- the dreaded "relocation truncated to fit" errors regarding improperly produced R_LARCH_PCREL20_S2. As it's near 2.45 branching time, revert the problematic change and XFAIL the original test case for now. Suggested-by: Xi Ruoyao <[email protected]> Signed-off-by: WANG Xuerui <[email protected]>
1 parent 7ea90d9 commit 792e4d2

File tree

2 files changed

+45
-64
lines changed

2 files changed

+45
-64
lines changed

bfd/elfnn-loongarch.c

Lines changed: 44 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5374,22 +5374,17 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
53745374
symval = sec_addr (sec)
53755375
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
53765376

5377-
/* If pc and symbol not in the same segment, add/sub segment alignment if the
5378-
section has not undergone alignment processing because distances may grow
5379-
after alignment. */
5380-
if (!loongarch_sec_closed_for_deletion (sec))
5381-
{
5382-
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5383-
sec->output_section,
5384-
sym_sec->output_section))
5385-
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5386-
: max_alignment;
5387-
5388-
if (symval > pc)
5389-
pc -= (max_alignment > 4 ? max_alignment : 0);
5390-
else if (symval < pc)
5391-
pc += (max_alignment > 4 ? max_alignment : 0);
5392-
}
5377+
/* If pc and symbol not in the same segment, add/sub segment alignment. */
5378+
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5379+
sec->output_section,
5380+
sym_sec->output_section))
5381+
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5382+
: max_alignment;
5383+
5384+
if (symval > pc)
5385+
pc -= (max_alignment > 4 ? max_alignment : 0);
5386+
else if (symval < pc)
5387+
pc += (max_alignment > 4 ? max_alignment : 0);
53935388

53945389
const uint32_t pcaddi = LARCH_OP_PCADDI;
53955390

@@ -5444,22 +5439,17 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
54445439
symval = sec_addr (sec)
54455440
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
54465441

5447-
/* If pc and symbol not in the same segment, add/sub segment alignment if the
5448-
section has not undergone alignment processing because distances may grow
5449-
after alignment. */
5450-
if (!loongarch_sec_closed_for_deletion (sec))
5451-
{
5452-
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5453-
sec->output_section,
5454-
sym_sec->output_section))
5455-
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5456-
: max_alignment;
5457-
5458-
if (symval > pc)
5459-
pc -= (max_alignment > 4 ? max_alignment : 0);
5460-
else if (symval < pc)
5461-
pc += (max_alignment > 4 ? max_alignment : 0);
5462-
}
5442+
/* If pc and symbol not in the same segment, add/sub segment alignment. */
5443+
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5444+
sec->output_section,
5445+
sym_sec->output_section))
5446+
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5447+
: max_alignment;
5448+
5449+
if (symval > pc)
5450+
pc -= (max_alignment > 4 ? max_alignment : 0);
5451+
else if (symval < pc)
5452+
pc += (max_alignment > 4 ? max_alignment : 0);
54635453

54645454
/* Is pcalau12i + addi.d insns? */
54655455
if (!LARCH_INSN_JIRL (jirl)
@@ -5513,22 +5503,17 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
55135503
symval = sec_addr (sec)
55145504
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
55155505

5516-
/* If pc and symbol not in the same segment, add/sub segment alignment if the
5517-
section has not undergone alignment processing because distances may grow
5518-
after alignment. */
5519-
if (!loongarch_sec_closed_for_deletion (sec))
5520-
{
5521-
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5522-
sec->output_section,
5523-
sym_sec->output_section))
5524-
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5525-
: max_alignment;
5526-
5527-
if (symval > pc)
5528-
pc -= (max_alignment > 4 ? max_alignment : 0);
5529-
else if (symval < pc)
5530-
pc += (max_alignment > 4 ? max_alignment : 0);
5531-
}
5506+
/* If pc and symbol not in the same segment, add/sub segment alignment. */
5507+
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5508+
sec->output_section,
5509+
sym_sec->output_section))
5510+
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5511+
: max_alignment;
5512+
5513+
if (symval > pc)
5514+
pc -= (max_alignment > 4 ? max_alignment : 0);
5515+
else if (symval < pc)
5516+
pc += (max_alignment > 4 ? max_alignment : 0);
55325517

55335518
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
55345519
|| (LARCH_GET_RD (ld) != rd)
@@ -5651,22 +5636,17 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
56515636
symval = sec_addr (sec)
56525637
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
56535638

5654-
/* If pc and symbol not in the same segment, add/sub segment alignment if the
5655-
section has not undergone alignment processing because distances may grow
5656-
after alignment. */
5657-
if (!loongarch_sec_closed_for_deletion (sec))
5658-
{
5659-
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5660-
sec->output_section,
5661-
sym_sec->output_section))
5662-
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5663-
: max_alignment;
5664-
5665-
if (symval > pc)
5666-
pc -= (max_alignment > 4 ? max_alignment : 0);
5667-
else if (symval < pc)
5668-
pc += (max_alignment > 4 ? max_alignment : 0);
5669-
}
5639+
/* If pc and symbol not in the same segment, add/sub segment alignment. */
5640+
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
5641+
sec->output_section,
5642+
sym_sec->output_section))
5643+
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
5644+
: max_alignment;
5645+
5646+
if (symval > pc)
5647+
pc -= (max_alignment > 4 ? max_alignment : 0);
5648+
else if (symval < pc)
5649+
pc += (max_alignment > 4 ? max_alignment : 0);
56705650

56715651
const uint32_t pcaddi = LARCH_OP_PCADDI;
56725652

ld/testsuite/ld-loongarch-elf/relax-after-alignment.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#as:
33
#ld: --defsym _start=0
44
#objdump: -d --no-show-raw-insn
5+
#xfail: *-*-*
56

67
.*:\s+file format .*
78

0 commit comments

Comments
 (0)