mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-12-18 08:49:29 +08:00
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 <xry111@xry111.site> Signed-off-by: WANG Xuerui <git@xen0n.name>
This commit is contained in:
@@ -5374,22 +5374,17 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
|
|||||||
symval = sec_addr (sec)
|
symval = sec_addr (sec)
|
||||||
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
||||||
|
|
||||||
/* If pc and symbol not in the same segment, add/sub segment alignment if the
|
/* If pc and symbol not in the same segment, add/sub segment alignment. */
|
||||||
section has not undergone alignment processing because distances may grow
|
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
||||||
after alignment. */
|
sec->output_section,
|
||||||
if (!loongarch_sec_closed_for_deletion (sec))
|
sym_sec->output_section))
|
||||||
{
|
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
||||||
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
: max_alignment;
|
||||||
sec->output_section,
|
|
||||||
sym_sec->output_section))
|
|
||||||
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
|
||||||
: max_alignment;
|
|
||||||
|
|
||||||
if (symval > pc)
|
if (symval > pc)
|
||||||
pc -= (max_alignment > 4 ? max_alignment : 0);
|
pc -= (max_alignment > 4 ? max_alignment : 0);
|
||||||
else if (symval < pc)
|
else if (symval < pc)
|
||||||
pc += (max_alignment > 4 ? max_alignment : 0);
|
pc += (max_alignment > 4 ? max_alignment : 0);
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t pcaddi = LARCH_OP_PCADDI;
|
const uint32_t pcaddi = LARCH_OP_PCADDI;
|
||||||
|
|
||||||
@@ -5444,22 +5439,17 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
|
|||||||
symval = sec_addr (sec)
|
symval = sec_addr (sec)
|
||||||
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
||||||
|
|
||||||
/* If pc and symbol not in the same segment, add/sub segment alignment if the
|
/* If pc and symbol not in the same segment, add/sub segment alignment. */
|
||||||
section has not undergone alignment processing because distances may grow
|
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
||||||
after alignment. */
|
sec->output_section,
|
||||||
if (!loongarch_sec_closed_for_deletion (sec))
|
sym_sec->output_section))
|
||||||
{
|
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
||||||
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
: max_alignment;
|
||||||
sec->output_section,
|
|
||||||
sym_sec->output_section))
|
|
||||||
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
|
||||||
: max_alignment;
|
|
||||||
|
|
||||||
if (symval > pc)
|
if (symval > pc)
|
||||||
pc -= (max_alignment > 4 ? max_alignment : 0);
|
pc -= (max_alignment > 4 ? max_alignment : 0);
|
||||||
else if (symval < pc)
|
else if (symval < pc)
|
||||||
pc += (max_alignment > 4 ? max_alignment : 0);
|
pc += (max_alignment > 4 ? max_alignment : 0);
|
||||||
}
|
|
||||||
|
|
||||||
/* Is pcalau12i + addi.d insns? */
|
/* Is pcalau12i + addi.d insns? */
|
||||||
if (!LARCH_INSN_JIRL (jirl)
|
if (!LARCH_INSN_JIRL (jirl)
|
||||||
@@ -5513,22 +5503,17 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
|
|||||||
symval = sec_addr (sec)
|
symval = sec_addr (sec)
|
||||||
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
||||||
|
|
||||||
/* If pc and symbol not in the same segment, add/sub segment alignment if the
|
/* If pc and symbol not in the same segment, add/sub segment alignment. */
|
||||||
section has not undergone alignment processing because distances may grow
|
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
||||||
after alignment. */
|
sec->output_section,
|
||||||
if (!loongarch_sec_closed_for_deletion (sec))
|
sym_sec->output_section))
|
||||||
{
|
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
||||||
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
: max_alignment;
|
||||||
sec->output_section,
|
|
||||||
sym_sec->output_section))
|
|
||||||
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
|
||||||
: max_alignment;
|
|
||||||
|
|
||||||
if (symval > pc)
|
if (symval > pc)
|
||||||
pc -= (max_alignment > 4 ? max_alignment : 0);
|
pc -= (max_alignment > 4 ? max_alignment : 0);
|
||||||
else if (symval < pc)
|
else if (symval < pc)
|
||||||
pc += (max_alignment > 4 ? max_alignment : 0);
|
pc += (max_alignment > 4 ? max_alignment : 0);
|
||||||
}
|
|
||||||
|
|
||||||
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
|
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
|
||||||
|| (LARCH_GET_RD (ld) != rd)
|
|| (LARCH_GET_RD (ld) != rd)
|
||||||
@@ -5651,22 +5636,17 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
|
|||||||
symval = sec_addr (sec)
|
symval = sec_addr (sec)
|
||||||
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
+ loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
|
||||||
|
|
||||||
/* If pc and symbol not in the same segment, add/sub segment alignment if the
|
/* If pc and symbol not in the same segment, add/sub segment alignment. */
|
||||||
section has not undergone alignment processing because distances may grow
|
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
||||||
after alignment. */
|
sec->output_section,
|
||||||
if (!loongarch_sec_closed_for_deletion (sec))
|
sym_sec->output_section))
|
||||||
{
|
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
||||||
if (!loongarch_two_sections_in_same_segment (info->output_bfd,
|
: max_alignment;
|
||||||
sec->output_section,
|
|
||||||
sym_sec->output_section))
|
|
||||||
max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
|
|
||||||
: max_alignment;
|
|
||||||
|
|
||||||
if (symval > pc)
|
if (symval > pc)
|
||||||
pc -= (max_alignment > 4 ? max_alignment : 0);
|
pc -= (max_alignment > 4 ? max_alignment : 0);
|
||||||
else if (symval < pc)
|
else if (symval < pc)
|
||||||
pc += (max_alignment > 4 ? max_alignment : 0);
|
pc += (max_alignment > 4 ? max_alignment : 0);
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t pcaddi = LARCH_OP_PCADDI;
|
const uint32_t pcaddi = LARCH_OP_PCADDI;
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#as:
|
#as:
|
||||||
#ld: --defsym _start=0
|
#ld: --defsym _start=0
|
||||||
#objdump: -d --no-show-raw-insn
|
#objdump: -d --no-show-raw-insn
|
||||||
|
#xfail: *-*-*
|
||||||
|
|
||||||
.*:\s+file format .*
|
.*:\s+file format .*
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user