Fix seg-fault when generating an empty DLL with LTO enabled.
ld PR 29998 * pe-dll.c (generate_reloc): Handle sections with no assigned output section. Terminate early of there are no relocs to put in the .reloc section. (pe_exe_fill_sections): Do not emit an empty .reloc section. bfd * cofflink.c (_bfd_coff_generic_relocate_section): Add an assertion that the output section is set for defined, global symbols.
This commit is contained in:
parent
59d49a8d83
commit
f3d8ae90b2
4 changed files with 61 additions and 24 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2023-01-24 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 29998
|
||||||
|
* cofflink.c (_bfd_coff_generic_relocate_section): Add an
|
||||||
|
assertion that the output section is set for defined, global
|
||||||
|
symbols.
|
||||||
|
|
||||||
2023-01-17 Xianmiao Qu <cooper.qu@linux.alibaba.com>
|
2023-01-17 Xianmiao Qu <cooper.qu@linux.alibaba.com>
|
||||||
|
|
||||||
* elf32-csky.c (elf32_csky_merge_attributes): Don't save
|
* elf32-csky.c (elf32_csky_merge_attributes): Don't save
|
||||||
|
|
|
@ -2977,10 +2977,11 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (h->root.type == bfd_link_hash_defined
|
if (h->root.type == bfd_link_hash_defined
|
||||||
|
/* Defined weak symbols are a GNU extension. */
|
||||||
|| h->root.type == bfd_link_hash_defweak)
|
|| h->root.type == bfd_link_hash_defweak)
|
||||||
{
|
{
|
||||||
/* Defined weak symbols are a GNU extension. */
|
|
||||||
sec = h->root.u.def.section;
|
sec = h->root.u.def.section;
|
||||||
|
BFD_ASSERT (sec->output_section != NULL);
|
||||||
val = (h->root.u.def.value
|
val = (h->root.u.def.value
|
||||||
+ sec->output_section->vma
|
+ sec->output_section->vma
|
||||||
+ sec->output_offset);
|
+ sec->output_offset);
|
||||||
|
@ -3087,7 +3088,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
|
||||||
return false;
|
return false;
|
||||||
case bfd_reloc_overflow:
|
case bfd_reloc_overflow:
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Ignore any weak undef symbols that may have overflowed. Due to
|
/* Ignore any weak undef symbols that may have overflowed. Due to
|
||||||
PR ld/19011 the base address is now in the upper 64-bit address
|
PR ld/19011 the base address is now in the upper 64-bit address
|
||||||
range. This means that when _bfd_final_link_relocate calculates
|
range. This means that when _bfd_final_link_relocate calculates
|
||||||
|
@ -3123,5 +3123,6 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2023-01-24 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
PR 29998
|
||||||
|
* pe-dll.c (generate_reloc): Handle sections with no assigned
|
||||||
|
output section. Terminate early of there are no relocs to put in
|
||||||
|
the .reloc section.
|
||||||
|
(pe_exe_fill_sections): Do not emit an empty .reloc section.
|
||||||
|
|
||||||
2023-01-06 Nick Clifton <nickc@redhat.com>
|
2023-01-06 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/bg.po: Updated Bulgarian translation.
|
* po/bg.po: Updated Bulgarian translation.
|
||||||
|
|
63
ld/pe-dll.c
63
ld/pe-dll.c
|
@ -168,7 +168,8 @@ static bfd_vma image_base;
|
||||||
static bfd *filler_bfd;
|
static bfd *filler_bfd;
|
||||||
static struct bfd_section *edata_s, *reloc_s;
|
static struct bfd_section *edata_s, *reloc_s;
|
||||||
static unsigned char *edata_d, *reloc_d;
|
static unsigned char *edata_d, *reloc_d;
|
||||||
static size_t edata_sz, reloc_sz;
|
static unsigned char *reloc_d = NULL;
|
||||||
|
static size_t edata_sz, reloc_sz = 0;
|
||||||
static int runtime_pseudo_relocs_created = 0;
|
static int runtime_pseudo_relocs_created = 0;
|
||||||
static bool runtime_pseudp_reloc_v2_init = false;
|
static bool runtime_pseudp_reloc_v2_init = false;
|
||||||
|
|
||||||
|
@ -1033,9 +1034,10 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
|
||||||
/* Build the bfd that will contain .edata and .reloc sections. */
|
/* Build the bfd that will contain .edata and .reloc sections. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
build_filler_bfd (int include_edata)
|
build_filler_bfd (bool include_edata)
|
||||||
{
|
{
|
||||||
lang_input_statement_type *filler_file;
|
lang_input_statement_type *filler_file;
|
||||||
|
|
||||||
filler_file = lang_add_input_file ("dll stuff",
|
filler_file = lang_add_input_file ("dll stuff",
|
||||||
lang_input_file_is_fake_enum,
|
lang_input_file_is_fake_enum,
|
||||||
NULL);
|
NULL);
|
||||||
|
@ -1526,6 +1528,8 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
if (reloc_s == NULL || reloc_s->output_section == bfd_abs_section_ptr)
|
if (reloc_s == NULL || reloc_s->output_section == bfd_abs_section_ptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Set an upper bound for the total number of relocations we will have to generate. */
|
||||||
total_relocs = 0;
|
total_relocs = 0;
|
||||||
for (b = info->input_bfds; b; b = b->link.next)
|
for (b = info->input_bfds; b; b = b->link.next)
|
||||||
for (s = b->sections; s; s = s->next)
|
for (s = b->sections; s; s = s->next)
|
||||||
|
@ -1541,28 +1545,34 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
for (s = b->sections; s; s = s->next)
|
for (s = b->sections; s; s = s->next)
|
||||||
{
|
{
|
||||||
bfd_vma sec_vma = s->output_section->vma + s->output_offset;
|
bfd_vma sec_vma;
|
||||||
asymbol **symbols;
|
asymbol **symbols;
|
||||||
|
|
||||||
/* If it's not loaded, we don't need to relocate it this way. */
|
/* If the section is not going to be output, then ignore it. */
|
||||||
if (!(s->output_section->flags & SEC_LOAD))
|
if (s->output_section == NULL)
|
||||||
|
{
|
||||||
|
/* PR 29998: LTO processing can elminate whole code sections,
|
||||||
|
but it sets the output section to NULL rather than *ABS*.
|
||||||
|
Fix that here, then ignore the section. */
|
||||||
|
s->output_section = bfd_abs_section_ptr;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* I don't know why there would be a reloc for these, but I've
|
/* I don't know why there would be a reloc for these, but I've
|
||||||
seen it happen - DJ */
|
seen it happen - DJ */
|
||||||
if (s->output_section == bfd_abs_section_ptr)
|
if (s->output_section == bfd_abs_section_ptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (s->output_section->vma == 0)
|
/* If it's not loaded, we don't need to relocate it this way. */
|
||||||
{
|
if (!(s->output_section->flags & SEC_LOAD))
|
||||||
/* Huh? Shouldn't happen, but punt if it does. */
|
|
||||||
#if 0 /* This happens when linking with --just-symbols=<file>, so do not generate an error. */
|
|
||||||
einfo (_("%P: zero vma section reloc detected: `%s' #%d f=%d\n"),
|
|
||||||
s->output_section->name, s->output_section->index,
|
|
||||||
s->output_section->flags);
|
|
||||||
#endif
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
/* This happens when linking with --just-symbols=<file>
|
||||||
|
so do not generate an error. */
|
||||||
|
if (s->output_section->vma == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sec_vma = s->output_section->vma + s->output_offset;
|
||||||
|
|
||||||
if (!bfd_generic_link_read_symbols (b))
|
if (!bfd_generic_link_read_symbols (b))
|
||||||
{
|
{
|
||||||
|
@ -1696,12 +1706,17 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free (relocs);
|
free (relocs);
|
||||||
/* Warning: the allocated symbols are remembered in BFD and
|
/* Warning: the allocated symbols are remembered in BFD and
|
||||||
reused later, so don't free them! */
|
reused later, so don't free them! */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This can happen for example when LTO has eliminated all code. */
|
||||||
|
if (total_relocs == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
/* At this point, we have total_relocs relocation addresses in
|
/* At this point, we have total_relocs relocation addresses in
|
||||||
reloc_addresses, which are all suitable for the .reloc section.
|
reloc_addresses, which are all suitable for the .reloc section.
|
||||||
We must now create the new sections. */
|
We must now create the new sections. */
|
||||||
|
@ -1726,9 +1741,9 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
|
reloc_sz = (reloc_sz + 3) & ~3; /* 4-byte align. */
|
||||||
reloc_d = xmalloc (reloc_sz);
|
reloc_d = xmalloc (reloc_sz);
|
||||||
sec_page = (bfd_vma) -1;
|
|
||||||
|
page_ptr = sec_page = (bfd_vma) -1;
|
||||||
reloc_sz = 0;
|
reloc_sz = 0;
|
||||||
page_ptr = (bfd_vma) -1;
|
|
||||||
|
|
||||||
for (i = 0; i < total_relocs; i++)
|
for (i = 0; i < total_relocs; i++)
|
||||||
{
|
{
|
||||||
|
@ -1758,7 +1773,6 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
|
||||||
bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
|
bfd_put_16 (abfd, reloc_data[i].extra, reloc_d + reloc_sz);
|
||||||
reloc_sz += 2;
|
reloc_sz += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (reloc_sz & 3)
|
while (reloc_sz & 3)
|
||||||
|
@ -3649,14 +3663,14 @@ pe_dll_build_sections (bfd *abfd, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
if (pe_dll_enable_reloc_section)
|
if (pe_dll_enable_reloc_section)
|
||||||
{
|
{
|
||||||
build_filler_bfd (0);
|
build_filler_bfd (false /* edata not needed. */);
|
||||||
pe_output_file_set_long_section_names (filler_bfd);
|
pe_output_file_set_long_section_names (filler_bfd);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_edata ();
|
generate_edata ();
|
||||||
build_filler_bfd (1);
|
build_filler_bfd (true /* edata is needed. */);
|
||||||
pe_output_file_set_long_section_names (filler_bfd);
|
pe_output_file_set_long_section_names (filler_bfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3692,6 +3706,7 @@ pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
|
||||||
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
|
image_base = pe_data (abfd)->pe_opthdr.ImageBase;
|
||||||
|
|
||||||
generate_reloc (abfd, info);
|
generate_reloc (abfd, info);
|
||||||
|
|
||||||
if (reloc_sz > 0)
|
if (reloc_sz > 0)
|
||||||
{
|
{
|
||||||
bfd_set_section_size (reloc_s, reloc_sz);
|
bfd_set_section_size (reloc_s, reloc_sz);
|
||||||
|
@ -3705,9 +3720,15 @@ pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
/* Do the assignments again. */
|
/* Do the assignments again. */
|
||||||
lang_do_assignments (lang_final_phase_enum);
|
lang_do_assignments (lang_final_phase_enum);
|
||||||
}
|
|
||||||
if (reloc_s)
|
|
||||||
reloc_s->contents = reloc_d;
|
reloc_s->contents = reloc_d;
|
||||||
|
}
|
||||||
|
else if (reloc_s)
|
||||||
|
{
|
||||||
|
/* Do not emit an empty reloc section. */
|
||||||
|
bfd_set_section_flags (reloc_s, SEC_IN_MEMORY | SEC_EXCLUDE);
|
||||||
|
reloc_s->output_section = bfd_abs_section_ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue