BFD: Fix the bug of R_LARCH_AGLIN caused by discard section
To represent the first and third expression of .align, R_LARCH_ALIGN need to associate with a symbol. We define a local symbol for R_LARCH_AGLIN. But if the section of the local symbol is discarded, it may result in a undefined symbol error. Instead, we use the section name symbols, and this does not need to add extra symbols. During partial linking (ld -r), if the symbol associated with a relocation is STT_SECTION type, the addend of relocation needs to add the section output offset. We prevent it for R_LARCH_ALIGN. The elf_backend_data.rela_normal only can set all relocations of a target to rela_normal. Add a new function is_rela_normal to elf_backend_data, it can set part of relocations to rela_normal.
This commit is contained in:
parent
c7a5bea4c6
commit
daeda14191
9 changed files with 66 additions and 8 deletions
|
@ -1721,6 +1721,10 @@ struct elf_backend_data
|
|||
backend relocate_section routine for relocatable linking. */
|
||||
unsigned rela_normal : 1;
|
||||
|
||||
/* Whether a relocation is rela_normal. Compared with rela_normal,
|
||||
is_rela_normal can set part of relocations to rela_normal. */
|
||||
bool (*is_rela_normal) (Elf_Internal_Rela *);
|
||||
|
||||
/* Set if DT_REL/DT_RELA/DT_RELSZ/DT_RELASZ should not include PLT
|
||||
relocations. */
|
||||
unsigned dtrel_excludes_plt : 1;
|
||||
|
|
|
@ -11692,7 +11692,10 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
|
|||
{
|
||||
rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
|
||||
rela_hash_list = rel_hash;
|
||||
rela_normal = bed->rela_normal;
|
||||
if (bed->is_rela_normal != NULL)
|
||||
rela_normal = bed->is_rela_normal (irela);
|
||||
else
|
||||
rela_normal = bed->rela_normal;
|
||||
}
|
||||
|
||||
irela->r_offset = _bfd_elf_section_offset (output_bfd,
|
||||
|
|
|
@ -5454,6 +5454,21 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
|
|||
return _bfd_elf_hash_symbol (h);
|
||||
}
|
||||
|
||||
/* If a relocation is rela_normal and the symbol associated with the
|
||||
relocation is STT_SECTION type, the addend of the relocation would add
|
||||
sec->output_offset when partial linking (ld -r).
|
||||
See elf_backend_data.rela_normal and elf_link_input_bfd().
|
||||
The addend of R_LARCH_ALIGN is used to represent the first and third
|
||||
expression of .align, it should be a constant when linking. */
|
||||
|
||||
static bool
|
||||
loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel)
|
||||
{
|
||||
if (R_LARCH_ALIGN == ELFNN_R_TYPE (rel->r_info))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define TARGET_LITTLE_SYM loongarch_elfNN_vec
|
||||
#define TARGET_LITTLE_NAME "elfNN-loongarch"
|
||||
#define ELF_ARCH bfd_arch_loongarch
|
||||
|
@ -5489,6 +5504,7 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
|
|||
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
|
||||
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
|
||||
#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
|
||||
#define elf_backend_is_rela_normal loongarch_elf_is_rela_normal
|
||||
|
||||
#define elf_backend_dtrel_excludes_plt 1
|
||||
|
||||
|
|
|
@ -709,6 +709,10 @@
|
|||
#define elf_backend_rela_normal 0
|
||||
#endif
|
||||
|
||||
#ifndef elf_backend_is_rela_normal
|
||||
#define elf_backend_is_rela_normal NULL
|
||||
#endif
|
||||
|
||||
#ifndef elf_backend_dtrel_excludes_plt
|
||||
#define elf_backend_dtrel_excludes_plt 0
|
||||
#endif
|
||||
|
@ -955,6 +959,7 @@ static const struct elf_backend_data elfNN_bed =
|
|||
elf_backend_default_use_rela_p,
|
||||
elf_backend_rela_plts_and_copies_p,
|
||||
elf_backend_rela_normal,
|
||||
elf_backend_is_rela_normal,
|
||||
elf_backend_dtrel_excludes_plt,
|
||||
elf_backend_sign_extend_vma,
|
||||
elf_backend_want_got_plt,
|
||||
|
|
|
@ -1791,10 +1791,7 @@ loongarch_frag_align_code (int n, int max)
|
|||
if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
|
||||
if (max > 0 && (bfd_vma) max < worst_case_bytes)
|
||||
{
|
||||
s = symbol_find (".Lla-relax-align");
|
||||
if (s == NULL)
|
||||
s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
|
||||
&zero_address_frag, 0);
|
||||
s = symbol_find (now_seg->name);
|
||||
ex.X_add_symbol = s;
|
||||
ex.X_op = O_symbol;
|
||||
ex.X_add_number = (max << 8) | n;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
Disassembly of section .text:
|
||||
|
||||
[ ]*0000000000000000 <.Lla-relax-align>:
|
||||
[ ]*0000000000000000 <.text>:
|
||||
[ ]+0:[ ]+4c000020[ ]+ret
|
||||
[ ]+4:[ ]+03400000[ ]+nop
|
||||
[ ]+4: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
|
||||
|
@ -20,12 +20,12 @@ Disassembly of section .text:
|
|||
[ ]+1c:[ ]+03400000[ ]+nop
|
||||
[ ]+20:[ ]+4c000020[ ]+ret
|
||||
[ ]+24:[ ]+03400000[ ]+nop
|
||||
[ ]+24: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x104
|
||||
[ ]+24: R_LARCH_ALIGN[ ]+.text\+0x104
|
||||
[ ]+28:[ ]+03400000[ ]+nop
|
||||
[ ]+2c:[ ]+03400000[ ]+nop
|
||||
[ ]+30:[ ]+4c000020[ ]+ret
|
||||
[ ]+34:[ ]+03400000[ ]+nop
|
||||
[ ]+34: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0xb04
|
||||
[ ]+34: R_LARCH_ALIGN[ ]+.text\+0xb04
|
||||
[ ]+38:[ ]+03400000[ ]+nop
|
||||
[ ]+3c:[ ]+03400000[ ]+nop
|
||||
[ ]+40:[ ]+4c000020[ ]+ret
|
||||
|
|
4
ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
Normal file
4
ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
Normal file
|
@ -0,0 +1,4 @@
|
|||
SECTIONS
|
||||
{
|
||||
/DISCARD/ : { *(.another.*) }
|
||||
}
|
17
ld/testsuite/ld-loongarch-elf/relax-align-discard.s
Normal file
17
ld/testsuite/ld-loongarch-elf/relax-align-discard.s
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Use the section name symbol for R_LARCH_ALIGN to avoid discard section problem
|
||||
.section ".another.text", "ax"
|
||||
.cfi_startproc
|
||||
break 0
|
||||
.cfi_def_cfa_offset 16
|
||||
.p2align 5
|
||||
break 1
|
||||
.cfi_endproc
|
||||
|
||||
.text
|
||||
.cfi_startproc
|
||||
break 0
|
||||
.cfi_def_cfa_offset 16
|
||||
.p2align 5
|
||||
break 1
|
||||
.cfi_endproc
|
||||
|
|
@ -295,6 +295,18 @@ if [istarget loongarch64-*-*] {
|
|||
"relax-align" \
|
||||
] \
|
||||
]
|
||||
|
||||
run_ld_link_tests \
|
||||
[list \
|
||||
[list \
|
||||
"loongarch relax align discard" \
|
||||
"-e 0x0 -T relax-align-discard.lds -r" "" \
|
||||
"" \
|
||||
{relax-align-discard.s} \
|
||||
{} \
|
||||
"relax-align-discard" \
|
||||
] \
|
||||
]
|
||||
}
|
||||
|
||||
set objdump_flags "-s -j .data"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue