* elf-bfd.h (struct eh_frame_hdr_info): Add offsets_adjusted.
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Adjust offsets stored in struct eh_cie_fde entries before doing other work.
This commit is contained in:
parent
fda3ecf23f
commit
3472e2e999
|
@ -1,5 +1,10 @@
|
||||||
2004-10-10 Alan Modra <amodra@bigpond.net.au>
|
2004-10-10 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf-bfd.h (struct eh_frame_hdr_info): Add offsets_adjusted.
|
||||||
|
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Adjust
|
||||||
|
offsets stored in struct eh_cie_fde entries before doing other
|
||||||
|
work.
|
||||||
|
|
||||||
* elf-bfd.h (struct eh_cie_fde): Add cie_inf, remove sec.
|
* elf-bfd.h (struct eh_cie_fde): Add cie_inf, remove sec.
|
||||||
(struct eh_frame_hdr_info): Add last_cie_inf, remove last_cie_offset.
|
(struct eh_frame_hdr_info): Add last_cie_inf, remove last_cie_offset.
|
||||||
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete code
|
* elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Delete code
|
||||||
|
|
|
@ -328,6 +328,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. */
|
||||||
bfd_boolean table;
|
bfd_boolean table;
|
||||||
|
bfd_boolean offsets_adjusted;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ELF linker hash table. */
|
/* ELF linker hash table. */
|
||||||
|
|
|
@ -798,6 +798,39 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
sec_info = elf_section_data (sec)->sec_info;
|
sec_info = elf_section_data (sec)->sec_info;
|
||||||
htab = elf_hash_table (info);
|
htab = elf_hash_table (info);
|
||||||
hdr_info = &htab->eh_info;
|
hdr_info = &htab->eh_info;
|
||||||
|
|
||||||
|
/* First convert all offsets to output section offsets, so that a
|
||||||
|
CIE offset is valid if the CIE is used by a FDE from some other
|
||||||
|
section. This can happen when duplicate CIEs are deleted in
|
||||||
|
_bfd_elf_discard_section_eh_frame. We do all sections here because
|
||||||
|
this function might not be called on sections in the same order as
|
||||||
|
_bfd_elf_discard_section_eh_frame. */
|
||||||
|
if (!hdr_info->offsets_adjusted)
|
||||||
|
{
|
||||||
|
bfd *ibfd;
|
||||||
|
asection *eh;
|
||||||
|
struct eh_frame_sec_info *eh_inf;
|
||||||
|
|
||||||
|
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||||
|
{
|
||||||
|
if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
|
||||||
|
|| (ibfd->flags & DYNAMIC) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
eh = bfd_get_section_by_name (ibfd, ".eh_frame");
|
||||||
|
if (eh == NULL || eh->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
eh_inf = elf_section_data (eh)->sec_info;
|
||||||
|
for (ent = eh_inf->entry; ent < eh_inf->entry + eh_inf->count; ++ent)
|
||||||
|
{
|
||||||
|
ent->offset += eh->output_offset;
|
||||||
|
ent->new_offset += eh->output_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hdr_info->offsets_adjusted = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (hdr_info->table && hdr_info->array == NULL)
|
if (hdr_info->table && hdr_info->array == NULL)
|
||||||
hdr_info->array
|
hdr_info->array
|
||||||
= bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
|
= bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
|
||||||
|
@ -810,16 +843,6 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
|
||||||
if (ent->removed)
|
if (ent->removed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* First convert all offsets to output section offsets, so that a
|
|
||||||
CIE offset is valid if the CIE is used by a FDE from some other
|
|
||||||
section. This can happen when duplicate CIEs are deleted in
|
|
||||||
_bfd_elf_discard_section_eh_frame.
|
|
||||||
FIXME: This assumes that _bfd_elf_discard_section_eh_frame is
|
|
||||||
called on sections in the same order as this function, which
|
|
||||||
isn't necessarily so. */
|
|
||||||
ent->offset += sec->output_offset;
|
|
||||||
ent->new_offset += sec->output_offset;
|
|
||||||
|
|
||||||
if (ent->cie)
|
if (ent->cie)
|
||||||
{
|
{
|
||||||
/* CIE */
|
/* CIE */
|
||||||
|
|
Loading…
Reference in New Issue