aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf-eh-frame.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-10-13 15:18:21 +1030
committerAlan Modra <amodra@gmail.com>2014-10-13 22:58:44 +1030
commit5b69e3572d1ee8e8e6e1991fd07f87a96c48746d (patch)
treee5688986dcaa7b0882440ee3f568f55f3cb03e58 /bfd/elf-eh-frame.c
parentc780cc2f5062451a568458b6ef9b8aef7cc1dd8a (diff)
downloadgdb-5b69e3572d1ee8e8e6e1991fd07f87a96c48746d.zip
gdb-5b69e3572d1ee8e8e6e1991fd07f87a96c48746d.tar.gz
gdb-5b69e3572d1ee8e8e6e1991fd07f87a96c48746d.tar.bz2
Run eh_frame optimisation for relocatable link
The idea here is to drop .eh_frame FDEs corresponding to dropped comdat group sections or linkonce sections, but not perform changes in encoding. bfd/ PR 17467 * elf-eh-frame.c (ENSURE_NO_RELOCS): Don't stop at first NONE reloc. (_bfd_elf_parse_eh_frame): When relocatable output, don't set flags enabling conversion of CIEs and FDEs to use relative encoding. (find_merged_cie): Similarly. (_bfd_elf_write_section_eh_frame): Don't edit FDEs when relocatable, except for CIE pointer. * elflink.c (bfd_elf_reloc_symbol_deleted_p): Return true for relocs against symbols in dropped comdat group sections. (bfd_elf_discard_info): Do some eh_frame optimisation when relocatable. ld/ * ldlang.c (lang_add_section): Set up map_head.s and map_tail.s when relocatable.
Diffstat (limited to 'bfd/elf-eh-frame.c')
-rw-r--r--bfd/elf-eh-frame.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 331570a..e481f34 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -556,10 +556,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
/* FIXME: octets_per_byte. */
#define ENSURE_NO_RELOCS(buf) \
- REQUIRE (!(cookie->rel < cookie->relend \
- && (cookie->rel->r_offset \
- < (bfd_size_type) ((buf) - ehbuf)) \
- && cookie->rel->r_info != 0))
+ while (cookie->rel < cookie->relend \
+ && (cookie->rel->r_offset \
+ < (bfd_size_type) ((buf) - ehbuf))) \
+ { \
+ REQUIRE (cookie->rel->r_info == 0); \
+ cookie->rel++; \
+ }
/* FIXME: octets_per_byte. */
#define SKIP_RELOCS(buf) \
@@ -726,6 +729,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
/* For shared libraries, try to get rid of as many RELATIVE relocs
as possible. */
if (info->shared
+ && !info->relocatable
&& (get_elf_backend_data (abfd)
->elf_backend_can_make_relative_eh_frame
(abfd, info, sec)))
@@ -763,10 +767,12 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
ENSURE_NO_RELOCS (buf);
if (!info->relocatable)
- /* Keep info for merging cies. */
- this_inf->u.cie.u.full_cie = cie;
- this_inf->u.cie.per_encoding_relative
- = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
+ {
+ /* Keep info for merging cies. */
+ this_inf->u.cie.u.full_cie = cie;
+ this_inf->u.cie.per_encoding_relative
+ = (cie->per_encoding & 0x70) == DW_EH_PE_pcrel;
+ }
}
else
{
@@ -1071,6 +1077,7 @@ find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
if (per_binds_local
&& info->shared
+ && !info->relocatable
&& (cie->per_encoding & 0x70) == DW_EH_PE_absptr
&& (get_elf_backend_data (abfd)
->elf_backend_can_make_relative_eh_frame (abfd, info, sec)))
@@ -1577,6 +1584,8 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
value = ((ent->new_offset + sec->output_offset + 4)
- (cie->new_offset + cie->u.cie.u.sec->output_offset));
bfd_put_32 (abfd, value, buf);
+ if (info->relocatable)
+ continue;
buf += 4;
width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
value = read_value (abfd, buf, width,