mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
PR ld/13909
* elf-eh-frame.c (_bfd_elf_eh_frame_present): New function. (_bfd_elf_maybe_strip_eh_frame_hdr): Use it here. * elf-bfd.h (_bfd_elf_eh_frame_present): Declare. * elflink.c (bfd_elf_size_dynamic_sections): Let the backend size dynamic sections before stripping eh_frame_hdr. (bfd_elf_gc_sections): Handle multiple .eh_frame sections. * elf32-ppc.c (ppc_elf_size_dynamic_sections): Drop glink_eh_frame if no other .eh_frame sections exist. * elf64-ppc.c (ppc64_elf_size_stubs): Likewise. * elf32-i386.c (elf_i386_create_dynamic_sections): Don't size or alloc plt_eh_frame here.. (elf_i386_size_dynamic_sections): ..do it here instead. Don't specially keep sgotplt, iplt, tgotplt, sdynbss for symbols. (elf_i386_finish_dynamic_sections): Check plt_eh_frame->contents before writing plt offset. * elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Don't size or alloc plt_eh_frame here.. (elf_x86_64_size_dynamic_sections): ..do it here instead. (elf_x86_64_finish_dynamic_sections): Check plt_eh_frame->contents before writing plt offset.
This commit is contained in:
parent
3161ca4f50
commit
9a2a56cc5a
@ -1,3 +1,27 @@
|
||||
2012-05-25 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/13909
|
||||
* elf-eh-frame.c (_bfd_elf_eh_frame_present): New function.
|
||||
(_bfd_elf_maybe_strip_eh_frame_hdr): Use it here.
|
||||
* elf-bfd.h (_bfd_elf_eh_frame_present): Declare.
|
||||
* elflink.c (bfd_elf_size_dynamic_sections): Let the backend
|
||||
size dynamic sections before stripping eh_frame_hdr.
|
||||
(bfd_elf_gc_sections): Handle multiple .eh_frame sections.
|
||||
* elf32-ppc.c (ppc_elf_size_dynamic_sections): Drop glink_eh_frame
|
||||
if no other .eh_frame sections exist.
|
||||
* elf64-ppc.c (ppc64_elf_size_stubs): Likewise.
|
||||
* elf32-i386.c (elf_i386_create_dynamic_sections): Don't size
|
||||
or alloc plt_eh_frame here..
|
||||
(elf_i386_size_dynamic_sections): ..do it here instead. Don't
|
||||
specially keep sgotplt, iplt, tgotplt, sdynbss for symbols.
|
||||
(elf_i386_finish_dynamic_sections): Check plt_eh_frame->contents
|
||||
before writing plt offset.
|
||||
* elf64-x86-64.c (elf_x86_64_create_dynamic_sections): Don't size
|
||||
or alloc plt_eh_frame here..
|
||||
(elf_x86_64_size_dynamic_sections): ..do it here instead.
|
||||
(elf_x86_64_finish_dynamic_sections): Check plt_eh_frame->contents
|
||||
before writing plt offset.
|
||||
|
||||
2012-05-24 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR ld/14158
|
||||
|
@ -1950,6 +1950,8 @@ extern bfd_boolean _bfd_elf_write_section_eh_frame
|
||||
(bfd *, struct bfd_link_info *, asection *, bfd_byte *);
|
||||
extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern bfd_boolean _bfd_elf_eh_frame_present
|
||||
(struct bfd_link_info *);
|
||||
extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
|
||||
(struct bfd_link_info *);
|
||||
|
||||
|
@ -1247,6 +1247,26 @@ _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Return true if there is at least one non-empty .eh_frame section in
|
||||
input files. Can only be called after ld has mapped input to
|
||||
output sections, and before sections are stripped. */
|
||||
bfd_boolean
|
||||
_bfd_elf_eh_frame_present (struct bfd_link_info *info)
|
||||
{
|
||||
asection *eh = bfd_get_section_by_name (info->output_bfd, ".eh_frame");
|
||||
|
||||
if (eh == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Count only sections which have at least a single CIE or FDE.
|
||||
There cannot be any CIE or FDE <= 8 bytes. */
|
||||
for (eh = eh->map_head.s; eh != NULL; eh = eh->map_head.s)
|
||||
if (eh->size > 8)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* This function is called from size_dynamic_sections.
|
||||
It needs to decide whether .eh_frame_hdr should be output or not,
|
||||
because when the dynamic symbol table has been sized it is too late
|
||||
@ -1255,8 +1275,6 @@ _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
|
||||
bfd_boolean
|
||||
_bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
|
||||
{
|
||||
asection *o;
|
||||
bfd *abfd;
|
||||
struct elf_link_hash_table *htab;
|
||||
struct eh_frame_hdr_info *hdr_info;
|
||||
|
||||
@ -1265,28 +1283,9 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
|
||||
if (hdr_info->hdr_sec == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
|
||||
{
|
||||
hdr_info->hdr_sec = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
abfd = NULL;
|
||||
if (info->eh_frame_hdr)
|
||||
for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
|
||||
{
|
||||
/* Count only sections which have at least a single CIE or FDE.
|
||||
There cannot be any CIE or FDE <= 8 bytes. */
|
||||
o = bfd_get_section_by_name (abfd, ".eh_frame");
|
||||
while (o != NULL
|
||||
&& (o->size <= 8
|
||||
|| bfd_is_abs_section (o->output_section)))
|
||||
o = bfd_get_next_section_by_name (o);
|
||||
if (o != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (abfd == NULL)
|
||||
if (bfd_is_abs_section (hdr_info->hdr_sec->output_section)
|
||||
|| !info->eh_frame_hdr
|
||||
|| !_bfd_elf_eh_frame_present (info))
|
||||
{
|
||||
hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
|
||||
hdr_info->hdr_sec = NULL;
|
||||
|
@ -1027,12 +1027,6 @@ elf_i386_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
|
||||
if (htab->plt_eh_frame == NULL
|
||||
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 2))
|
||||
return FALSE;
|
||||
|
||||
htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
|
||||
htab->plt_eh_frame->contents
|
||||
= bfd_alloc (dynobj, htab->plt_eh_frame->size);
|
||||
memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
|
||||
sizeof (elf_i386_eh_frame_plt));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -2726,7 +2720,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||||
FALSE, FALSE, FALSE);
|
||||
|
||||
/* Don't allocate .got.plt section if there are no GOT nor PLT
|
||||
entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
|
||||
entries and there is no reference to _GLOBAL_OFFSET_TABLE_. */
|
||||
if ((got == NULL
|
||||
|| !got->ref_regular_nonweak)
|
||||
&& (htab->elf.sgotplt->size
|
||||
@ -2742,6 +2736,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||||
htab->elf.sgotplt->size = 0;
|
||||
}
|
||||
|
||||
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
&& !bfd_is_abs_section (htab->elf.splt->output_section)
|
||||
&& _bfd_elf_eh_frame_present (info))
|
||||
htab->plt_eh_frame->size = sizeof (elf_i386_eh_frame_plt);
|
||||
|
||||
/* We now have determined the sizes of the various dynamic sections.
|
||||
Allocate memory for them. */
|
||||
relocs = FALSE;
|
||||
@ -2753,11 +2755,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||||
continue;
|
||||
|
||||
if (s == htab->elf.splt
|
||||
|| s == htab->elf.sgot
|
||||
|| s == htab->elf.sgotplt
|
||||
|| s == htab->elf.iplt
|
||||
|| s == htab->elf.igotplt
|
||||
|| s == htab->sdynbss)
|
||||
|| s == htab->elf.sgot)
|
||||
{
|
||||
/* Strip this section if we don't need it; see the
|
||||
comment below. */
|
||||
@ -2768,6 +2766,14 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||||
if (htab->elf.hplt != NULL)
|
||||
strip_section = FALSE;
|
||||
}
|
||||
else if (s == htab->elf.sgotplt
|
||||
|| s == htab->elf.iplt
|
||||
|| s == htab->elf.igotplt
|
||||
|| s == htab->plt_eh_frame
|
||||
|| s == htab->sdynbss)
|
||||
{
|
||||
/* Strip these too. */
|
||||
}
|
||||
else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rel"))
|
||||
{
|
||||
if (s->size != 0
|
||||
@ -2815,11 +2821,13 @@ elf_i386_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
|
||||
}
|
||||
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
&& (htab->elf.splt->flags & SEC_EXCLUDE) == 0)
|
||||
bfd_put_32 (dynobj, htab->elf.splt->size,
|
||||
htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
|
||||
&& htab->plt_eh_frame->contents != NULL)
|
||||
{
|
||||
memcpy (htab->plt_eh_frame->contents, elf_i386_eh_frame_plt,
|
||||
sizeof (elf_i386_eh_frame_plt));
|
||||
bfd_put_32 (dynobj, htab->elf.splt->size,
|
||||
htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
|
||||
}
|
||||
|
||||
if (htab->elf.dynamic_sections_created)
|
||||
{
|
||||
@ -4840,7 +4848,8 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
|
||||
/* Adjust .eh_frame for .plt section. */
|
||||
if (htab->plt_eh_frame != NULL)
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->plt_eh_frame->contents != NULL)
|
||||
{
|
||||
if (htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
|
@ -6244,7 +6244,8 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
|
||||
if (htab->glink != NULL
|
||||
&& htab->glink->size != 0
|
||||
&& htab->glink_eh_frame != NULL
|
||||
&& !bfd_is_abs_section (htab->glink_eh_frame->output_section))
|
||||
&& !bfd_is_abs_section (htab->glink_eh_frame->output_section)
|
||||
&& _bfd_elf_eh_frame_present (info))
|
||||
{
|
||||
s = htab->glink_eh_frame;
|
||||
s->size = sizeof (glink_eh_frame_cie) + 20;
|
||||
|
@ -11662,7 +11662,7 @@ ppc64_elf_size_stubs (struct bfd_link_info *info, bfd_signed_vma group_size,
|
||||
|
||||
if (htab->glink_eh_frame != NULL
|
||||
&& !bfd_is_abs_section (htab->glink_eh_frame->output_section)
|
||||
&& (htab->glink_eh_frame->flags & SEC_EXCLUDE) == 0)
|
||||
&& htab->glink_eh_frame->output_section->size != 0)
|
||||
{
|
||||
size_t size = 0, align;
|
||||
|
||||
|
@ -982,8 +982,6 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
|
||||
&& htab->plt_eh_frame == NULL
|
||||
&& htab->elf.splt != NULL)
|
||||
{
|
||||
const struct elf_x86_64_backend_data *const abed
|
||||
= get_elf_x86_64_backend_data (dynobj);
|
||||
flagword flags = get_elf_backend_data (dynobj)->dynamic_sec_flags;
|
||||
htab->plt_eh_frame
|
||||
= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame",
|
||||
@ -993,12 +991,6 @@ elf_x86_64_create_dynamic_sections (bfd *dynobj,
|
||||
if (htab->plt_eh_frame == NULL
|
||||
|| !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
|
||||
return FALSE;
|
||||
|
||||
htab->plt_eh_frame->size = abed->eh_frame_plt_size;
|
||||
htab->plt_eh_frame->contents
|
||||
= bfd_alloc (dynobj, htab->plt_eh_frame->size);
|
||||
memcpy (htab->plt_eh_frame->contents,
|
||||
abed->eh_frame_plt, abed->eh_frame_plt_size);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -2797,6 +2789,17 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
||||
htab->elf.sgotplt->size = 0;
|
||||
}
|
||||
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
&& !bfd_is_abs_section (htab->elf.splt->output_section)
|
||||
&& _bfd_elf_eh_frame_present (info))
|
||||
{
|
||||
const struct elf_x86_64_backend_data *arch_data
|
||||
= (const struct elf_x86_64_backend_data *) bed->arch_data;
|
||||
htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
|
||||
}
|
||||
|
||||
/* We now have determined the sizes of the various dynamic sections.
|
||||
Allocate memory for them. */
|
||||
relocs = FALSE;
|
||||
@ -2810,6 +2813,7 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
||||
|| s == htab->elf.sgotplt
|
||||
|| s == htab->elf.iplt
|
||||
|| s == htab->elf.igotplt
|
||||
|| s == htab->plt_eh_frame
|
||||
|| s == htab->sdynbss)
|
||||
{
|
||||
/* Strip this section if we don't need it; see the
|
||||
@ -2861,11 +2865,16 @@ elf_x86_64_size_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
&& (htab->elf.splt->flags & SEC_EXCLUDE) == 0)
|
||||
bfd_put_32 (dynobj, htab->elf.splt->size,
|
||||
htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
|
||||
&& htab->plt_eh_frame->contents != NULL)
|
||||
{
|
||||
const struct elf_x86_64_backend_data *arch_data
|
||||
= (const struct elf_x86_64_backend_data *) bed->arch_data;
|
||||
|
||||
memcpy (htab->plt_eh_frame->contents,
|
||||
arch_data->eh_frame_plt, htab->plt_eh_frame->size);
|
||||
bfd_put_32 (dynobj, htab->elf.splt->size,
|
||||
htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
|
||||
}
|
||||
|
||||
if (htab->elf.dynamic_sections_created)
|
||||
{
|
||||
@ -4725,7 +4734,8 @@ elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
|
||||
/* Adjust .eh_frame for .plt section. */
|
||||
if (htab->plt_eh_frame != NULL)
|
||||
if (htab->plt_eh_frame != NULL
|
||||
&& htab->plt_eh_frame->contents != NULL)
|
||||
{
|
||||
if (htab->elf.splt != NULL
|
||||
&& htab->elf.splt->size != 0
|
||||
|
@ -5584,17 +5584,9 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
&& ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
|
||||
return FALSE;
|
||||
|
||||
if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
|
||||
return FALSE;
|
||||
|
||||
dynobj = elf_hash_table (info)->dynobj;
|
||||
|
||||
/* If there were no dynamic objects in the link, there is nothing to
|
||||
do here. */
|
||||
if (dynobj == NULL)
|
||||
return TRUE;
|
||||
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
struct elf_info_failed eif;
|
||||
struct elf_link_hash_entry *h;
|
||||
@ -5897,11 +5889,15 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
/* The backend must work out the sizes of all the other dynamic
|
||||
sections. */
|
||||
if (bed->elf_backend_size_dynamic_sections
|
||||
if (dynobj != NULL
|
||||
&& bed->elf_backend_size_dynamic_sections != NULL
|
||||
&& ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
|
||||
return FALSE;
|
||||
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
|
||||
return FALSE;
|
||||
|
||||
if (dynobj != NULL && elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
unsigned long section_sym_count;
|
||||
struct bfd_elf_version_tree *verdefs;
|
||||
@ -12002,12 +11998,14 @@ bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info)
|
||||
struct elf_reloc_cookie cookie;
|
||||
|
||||
sec = bfd_get_section_by_name (sub, ".eh_frame");
|
||||
if (sec && init_reloc_cookie_for_section (&cookie, info, sec))
|
||||
while (sec && init_reloc_cookie_for_section (&cookie, info, sec))
|
||||
{
|
||||
_bfd_elf_parse_eh_frame (sub, info, sec, &cookie);
|
||||
if (elf_section_data (sec)->sec_info)
|
||||
if (elf_section_data (sec)->sec_info
|
||||
&& (sec->flags & SEC_LINKER_CREATED) == 0)
|
||||
elf_eh_frame_section (sub) = sec;
|
||||
fini_reloc_cookie_for_section (&cookie, sec);
|
||||
sec = bfd_get_next_section_by_name (sec);
|
||||
}
|
||||
}
|
||||
_bfd_elf_end_eh_frame_parsing (info);
|
||||
|
Loading…
Reference in New Issue
Block a user