mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-25 08:25:22 +08:00
* elf-bfd.h (_bfd_elf_maybe_strip_eh_frame_hdr): New prototype.
* elf-eh-frame.c (struct eh_frame_hdr_info): Add strip. (_bfd_elf_discard_section_eh_frame): Don't create .eh_frame_hdr sec_info here. Free ehbuf. (_bfd_elf_discard_section_eh_frame_hdr): Don't size the section if hdr_info->strip. (_bfd_elf_maybe_strip_eh_frame_hdr): New. * elflink.h (size_dynamic_sections): Call it.
This commit is contained in:
@ -1,3 +1,14 @@
|
|||||||
|
2001-12-15 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* elf-bfd.h (_bfd_elf_maybe_strip_eh_frame_hdr): New prototype.
|
||||||
|
* elf-eh-frame.c (struct eh_frame_hdr_info): Add strip.
|
||||||
|
(_bfd_elf_discard_section_eh_frame): Don't create .eh_frame_hdr
|
||||||
|
sec_info here. Free ehbuf.
|
||||||
|
(_bfd_elf_discard_section_eh_frame_hdr): Don't size the section
|
||||||
|
if hdr_info->strip.
|
||||||
|
(_bfd_elf_maybe_strip_eh_frame_hdr): New.
|
||||||
|
* elflink.h (size_dynamic_sections): Call it.
|
||||||
|
|
||||||
2001-12-14 Alan Modra <amodra@bigpond.net.au>
|
2001-12-14 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
* elflink.h (elf_bfd_discard_info): Fix segfault when dynobj NULL.
|
* elflink.h (elf_bfd_discard_info): Fix segfault when dynobj NULL.
|
||||||
|
@ -1296,6 +1296,8 @@ extern boolean _bfd_elf_write_section_eh_frame
|
|||||||
PARAMS ((bfd *, asection *, asection *, bfd_byte *));
|
PARAMS ((bfd *, asection *, asection *, bfd_byte *));
|
||||||
extern boolean _bfd_elf_write_section_eh_frame_hdr
|
extern boolean _bfd_elf_write_section_eh_frame_hdr
|
||||||
PARAMS ((bfd *, asection *));
|
PARAMS ((bfd *, asection *));
|
||||||
|
extern boolean _bfd_elf_maybe_strip_eh_frame_hdr
|
||||||
|
PARAMS ((struct bfd_link_info *));
|
||||||
|
|
||||||
extern boolean _bfd_elf_link_record_dynamic_symbol
|
extern boolean _bfd_elf_link_record_dynamic_symbol
|
||||||
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
|
||||||
|
@ -86,6 +86,7 @@ struct eh_frame_hdr_info
|
|||||||
We build it if we successfully read all .eh_frame input sections
|
We build it if we successfully read all .eh_frame input sections
|
||||||
and recognize them. */
|
and recognize them. */
|
||||||
boolean table;
|
boolean table;
|
||||||
|
boolean strip;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bfd_vma read_unsigned_leb128
|
static bfd_vma read_unsigned_leb128
|
||||||
@ -246,7 +247,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
|
|||||||
struct cie_header hdr;
|
struct cie_header hdr;
|
||||||
struct cie cie;
|
struct cie cie;
|
||||||
struct eh_frame_hdr_info *hdr_info;
|
struct eh_frame_hdr_info *hdr_info;
|
||||||
struct eh_frame_sec_info *sec_info;
|
struct eh_frame_sec_info *sec_info = NULL;
|
||||||
unsigned int leb128_tmp;
|
unsigned int leb128_tmp;
|
||||||
unsigned int cie_usage_count, last_cie_ndx, i, offset, make_relative;
|
unsigned int cie_usage_count, last_cie_ndx, i, offset, make_relative;
|
||||||
Elf_Internal_Rela *rel;
|
Elf_Internal_Rela *rel;
|
||||||
@ -267,23 +268,20 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BFD_ASSERT (elf_section_data (ehdrsec)->sec_info_type
|
||||||
|
== ELF_INFO_TYPE_EH_FRAME_HDR);
|
||||||
|
hdr_info = (struct eh_frame_hdr_info *)
|
||||||
|
elf_section_data (ehdrsec)->sec_info;
|
||||||
|
|
||||||
/* Read the frame unwind information from abfd. */
|
/* Read the frame unwind information from abfd. */
|
||||||
|
|
||||||
ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
|
ehbuf = (bfd_byte *) bfd_malloc (sec->_raw_size);
|
||||||
if (ehbuf == NULL
|
if (ehbuf == NULL)
|
||||||
|| ! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
|
goto free_no_table;
|
||||||
|
|
||||||
|
if (! bfd_get_section_contents (abfd, sec, ehbuf, (bfd_vma) 0,
|
||||||
sec->_raw_size))
|
sec->_raw_size))
|
||||||
{
|
goto free_no_table;
|
||||||
if (elf_section_data (ehdrsec)->sec_info_type
|
|
||||||
!= ELF_INFO_TYPE_EH_FRAME_HDR)
|
|
||||||
{
|
|
||||||
elf_section_data (ehdrsec)->sec_info
|
|
||||||
= bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
|
|
||||||
elf_section_data (ehdrsec)->sec_info_type
|
|
||||||
= ELF_INFO_TYPE_EH_FRAME_HDR;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sec->_raw_size >= 4
|
if (sec->_raw_size >= 4
|
||||||
&& bfd_get_32 (abfd, ehbuf) == 0
|
&& bfd_get_32 (abfd, ehbuf) == 0
|
||||||
@ -294,24 +292,10 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elf_section_data (ehdrsec)->sec_info_type
|
|
||||||
!= ELF_INFO_TYPE_EH_FRAME_HDR)
|
|
||||||
{
|
|
||||||
hdr_info = (struct eh_frame_hdr_info *)
|
|
||||||
bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
|
|
||||||
hdr_info->table = true;
|
|
||||||
elf_section_data (ehdrsec)->sec_info = hdr_info;
|
|
||||||
elf_section_data (ehdrsec)->sec_info_type
|
|
||||||
= ELF_INFO_TYPE_EH_FRAME_HDR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hdr_info = (struct eh_frame_hdr_info *)
|
|
||||||
elf_section_data (ehdrsec)->sec_info;
|
|
||||||
|
|
||||||
/* If .eh_frame section size doesn't fit into int, we cannot handle
|
/* If .eh_frame section size doesn't fit into int, we cannot handle
|
||||||
it (it would need to use 64-bit .eh_frame format anyway). */
|
it (it would need to use 64-bit .eh_frame format anyway). */
|
||||||
if (sec->_raw_size != (unsigned int) sec->_raw_size)
|
if (sec->_raw_size != (unsigned int) sec->_raw_size)
|
||||||
return false;
|
goto free_no_table;
|
||||||
|
|
||||||
ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
|
ptr_size = (elf_elfheader (abfd)->e_ident[EI_CLASS]
|
||||||
== ELFCLASS64) ? 8 : 4;
|
== ELFCLASS64) ? 8 : 4;
|
||||||
@ -650,9 +634,12 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
|
|||||||
if (sec->_cooked_size == 0)
|
if (sec->_cooked_size == 0)
|
||||||
sec->flags |= SEC_EXCLUDE;
|
sec->flags |= SEC_EXCLUDE;
|
||||||
|
|
||||||
|
free (ehbuf);
|
||||||
return new_size != sec->_raw_size;
|
return new_size != sec->_raw_size;
|
||||||
|
|
||||||
free_no_table:
|
free_no_table:
|
||||||
|
if (ehbuf)
|
||||||
|
free (ehbuf);
|
||||||
if (sec_info)
|
if (sec_info)
|
||||||
free (sec_info);
|
free (sec_info);
|
||||||
hdr_info->table = false;
|
hdr_info->table = false;
|
||||||
@ -686,6 +673,8 @@ _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
|
|||||||
|
|
||||||
hdr_info = (struct eh_frame_hdr_info *)
|
hdr_info = (struct eh_frame_hdr_info *)
|
||||||
elf_section_data (sec)->sec_info;
|
elf_section_data (sec)->sec_info;
|
||||||
|
if (hdr_info->strip)
|
||||||
|
return false;
|
||||||
sec->_cooked_size = EH_FRAME_HDR_SIZE;
|
sec->_cooked_size = EH_FRAME_HDR_SIZE;
|
||||||
if (hdr_info->table)
|
if (hdr_info->table)
|
||||||
sec->_cooked_size += 4 + hdr_info->fde_count * 8;
|
sec->_cooked_size += 4 + hdr_info->fde_count * 8;
|
||||||
@ -696,6 +685,52 @@ _bfd_elf_discard_section_eh_frame_hdr (abfd, info, sec)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is called from size_dynamic_sections.
|
||||||
|
It needs to decide whether .eh_frame_hdr should be output or not,
|
||||||
|
because later on it is too late for calling _bfd_strip_section_from_output,
|
||||||
|
since dynamic symbol table has been sized. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
_bfd_elf_maybe_strip_eh_frame_hdr (info)
|
||||||
|
struct bfd_link_info *info;
|
||||||
|
{
|
||||||
|
asection *sec, *o;
|
||||||
|
bfd *abfd;
|
||||||
|
struct eh_frame_hdr_info *hdr_info;
|
||||||
|
|
||||||
|
sec = bfd_get_section_by_name (elf_hash_table (info)->dynobj, ".eh_frame_hdr");
|
||||||
|
if (sec == NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
hdr_info
|
||||||
|
= bfd_zmalloc (sizeof (struct eh_frame_hdr_info));
|
||||||
|
if (hdr_info == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
elf_section_data (sec)->sec_info = hdr_info;
|
||||||
|
elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME_HDR;
|
||||||
|
|
||||||
|
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");
|
||||||
|
if (o && o->_raw_size > 8)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abfd == NULL)
|
||||||
|
{
|
||||||
|
_bfd_strip_section_from_output (info, sec);
|
||||||
|
hdr_info->strip = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hdr_info->table = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjust an address in the .eh_frame section. Given OFFSET within
|
/* Adjust an address in the .eh_frame section. Given OFFSET within
|
||||||
SEC, this returns the new offset in the adjusted .eh_frame section,
|
SEC, this returns the new offset in the adjusted .eh_frame section,
|
||||||
or -1 if the address refers to a CIE/FDE which has been removed
|
or -1 if the address refers to a CIE/FDE which has been removed
|
||||||
|
@ -3002,6 +3002,9 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
|||||||
if (dynobj == NULL)
|
if (dynobj == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (elf_hash_table (info)->dynamic_sections_created)
|
if (elf_hash_table (info)->dynamic_sections_created)
|
||||||
{
|
{
|
||||||
struct elf_info_failed eif;
|
struct elf_info_failed eif;
|
||||||
|
Reference in New Issue
Block a user