mirror of
https://github.com/bminor/binutils-gdb.git
synced 2026-02-06 19:01:30 +00:00
PR 33453 linker generated .eh_frame
This is the final piece to fix the PR33453 testcase. It makes use of the extended size final link buffer when writing linker generated .eh_frame. PR 33453 * elf-bfd.h (_bfd_elf_write_linker_section_eh_frame): Declare. * elf-eh-frame.c (_bfd_elf_write_linker_section_eh_frame): New. * elf32-ppc.c (ppc_elf_finish_dynamic_sections): Use new function. * elf64-ppc.c (ppc64_elf_finish_dynamic_sections): Likewise. * elf64-s390.c (elf_s390_finish_dynamic_sections): Likewise. * elfxx-x86.c (_bfd_x86_elf_finish_dynamic_sections): Likewise.
This commit is contained in:
@@ -2553,7 +2553,9 @@ extern bfd_vma _bfd_elf_eh_frame_section_offset
|
||||
(bfd *, struct bfd_link_info *, asection *, bfd_vma) ATTRIBUTE_HIDDEN;
|
||||
extern bool _bfd_elf_write_section_eh_frame
|
||||
(bfd *, struct bfd_link_info *, asection *, bfd_byte *) ATTRIBUTE_HIDDEN;
|
||||
bool _bfd_elf_write_section_eh_frame_entry
|
||||
extern bool _bfd_elf_write_linker_section_eh_frame
|
||||
(bfd *, struct bfd_link_info *, asection *, bfd_byte *) ATTRIBUTE_HIDDEN;
|
||||
extern bool _bfd_elf_write_section_eh_frame_entry
|
||||
(bfd *, struct bfd_link_info *, asection *, bfd_byte *) ATTRIBUTE_HIDDEN;
|
||||
extern bool _bfd_elf_fixup_eh_frame_hdr
|
||||
(struct bfd_link_info *) ATTRIBUTE_HIDDEN;
|
||||
|
||||
@@ -2294,6 +2294,34 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||
sec->size);
|
||||
}
|
||||
|
||||
/* A handy wrapper for writing linker generated .eh_frame sections
|
||||
with contents that may need to be extended beyond the initial size
|
||||
allocated. */
|
||||
|
||||
bool
|
||||
_bfd_elf_write_linker_section_eh_frame (bfd *obfd, struct bfd_link_info *info,
|
||||
asection *sec, bfd_byte *bigbuf)
|
||||
{
|
||||
bfd_size_type initial_size = sec->rawsize != 0 ? sec->rawsize : sec->size;
|
||||
memcpy (bigbuf, sec->contents, initial_size);
|
||||
if (!_bfd_elf_write_section_eh_frame (obfd, info, sec, bigbuf))
|
||||
return false;
|
||||
if (sec->size > initial_size)
|
||||
{
|
||||
if (sec->alloced)
|
||||
sec->contents = bfd_alloc (sec->owner, sec->size);
|
||||
else
|
||||
{
|
||||
free (sec->contents);
|
||||
sec->contents = bfd_malloc (sec->size);
|
||||
}
|
||||
if (sec->contents == NULL)
|
||||
return false;
|
||||
}
|
||||
memcpy (sec->contents, bigbuf, sec->size);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Helper function used to sort .eh_frame_hdr search table by increasing
|
||||
VMA of FDE initial location. */
|
||||
|
||||
|
||||
@@ -9921,7 +9921,7 @@ ppc_elf_reloc_type_class (const struct bfd_link_info *info,
|
||||
static bool
|
||||
ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd_byte *buf ATTRIBUTE_UNUSED)
|
||||
bfd_byte *buf)
|
||||
{
|
||||
asection *sdyn;
|
||||
struct ppc_elf_link_hash_table *htab;
|
||||
@@ -10345,9 +10345,9 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
bfd_put_32 (htab->elf.dynobj, val, p);
|
||||
|
||||
if (htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->glink_eh_frame,
|
||||
htab->glink_eh_frame->contents))
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->glink_eh_frame,
|
||||
buf))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -18249,7 +18249,7 @@ ppc64_elf_reloc_type_class (const struct bfd_link_info *info,
|
||||
static bool
|
||||
ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd_byte *buf ATTRIBUTE_UNUSED)
|
||||
bfd_byte *buf)
|
||||
{
|
||||
struct ppc_link_hash_table *htab;
|
||||
bfd *dynobj;
|
||||
@@ -18387,9 +18387,8 @@ ppc64_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
if (htab->glink_eh_frame != NULL
|
||||
&& htab->glink_eh_frame->size != 0
|
||||
&& htab->glink_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->glink_eh_frame,
|
||||
htab->glink_eh_frame->contents))
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->glink_eh_frame, buf))
|
||||
return false;
|
||||
|
||||
/* We need to handle writing out multiple GOT sections ourselves,
|
||||
|
||||
@@ -3842,7 +3842,7 @@ elf_s390_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
|
||||
static bool
|
||||
elf_s390_finish_dynamic_sections (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd_byte *buf ATTRIBUTE_UNUSED)
|
||||
bfd_byte *buf)
|
||||
{
|
||||
struct elf_s390_link_hash_table *htab;
|
||||
bfd *dynobj;
|
||||
@@ -4009,13 +4009,10 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
|
||||
+ PLT_FDE_START_OFFSET);
|
||||
}
|
||||
|
||||
if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
|
||||
{
|
||||
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->plt_eh_frame,
|
||||
htab->plt_eh_frame->contents))
|
||||
return NULL;
|
||||
}
|
||||
if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->plt_eh_frame, buf))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make any adjustment if necessary and merge .sframe section to
|
||||
|
||||
@@ -2763,7 +2763,7 @@ _bfd_x86_elf_late_size_sections (bfd *output_bfd,
|
||||
struct elf_x86_link_hash_table *
|
||||
_bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
struct bfd_link_info *info,
|
||||
bfd_byte *buf ATTRIBUTE_UNUSED)
|
||||
bfd_byte *buf)
|
||||
{
|
||||
struct elf_x86_link_hash_table *htab;
|
||||
const struct elf_backend_data *bed;
|
||||
@@ -2924,13 +2924,10 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
+ PLT_FDE_START_OFFSET);
|
||||
}
|
||||
|
||||
if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
|
||||
{
|
||||
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->plt_eh_frame,
|
||||
htab->plt_eh_frame->contents))
|
||||
return NULL;
|
||||
}
|
||||
if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->plt_eh_frame, buf))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Adjust .eh_frame for .plt.got section. */
|
||||
@@ -2951,13 +2948,11 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
htab->plt_got_eh_frame->contents
|
||||
+ PLT_FDE_START_OFFSET);
|
||||
}
|
||||
if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
|
||||
{
|
||||
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->plt_got_eh_frame,
|
||||
htab->plt_got_eh_frame->contents))
|
||||
return NULL;
|
||||
}
|
||||
if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->plt_got_eh_frame,
|
||||
buf))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Adjust .eh_frame for the second PLT section. */
|
||||
@@ -2979,14 +2974,11 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
|
||||
htab->plt_second_eh_frame->contents
|
||||
+ PLT_FDE_START_OFFSET);
|
||||
}
|
||||
if (htab->plt_second_eh_frame->sec_info_type
|
||||
== SEC_INFO_TYPE_EH_FRAME)
|
||||
{
|
||||
if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
|
||||
htab->plt_second_eh_frame,
|
||||
htab->plt_second_eh_frame->contents))
|
||||
return NULL;
|
||||
}
|
||||
if (htab->plt_second_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME
|
||||
&& !_bfd_elf_write_linker_section_eh_frame (output_bfd, info,
|
||||
htab->plt_second_eh_frame,
|
||||
buf))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make any adjustment if necessary and merge .sframe section to
|
||||
|
||||
Reference in New Issue
Block a user