From 90061c3348116fbc64c9ef19dc28c154450d218e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 22 May 2012 12:09:26 +0000 Subject: [PATCH] * elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame sections attached to a BFD. * section.c (bfd_get_section_by_name): Rewrite description. (bfd_get_next_section_by_name): New function. * bfd-in2.h: Regenerate. --- bfd/ChangeLog | 8 ++++++++ bfd/bfd-in2.h | 2 ++ bfd/elflink.c | 5 +++-- bfd/section.c | 45 +++++++++++++++++++++++++++++++++++++-------- 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index a77a28c9ab0..270b83a73dd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2012-05-22 Alan Modra + + * elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame + sections attached to a BFD. + * section.c (bfd_get_section_by_name): Rewrite description. + (bfd_get_next_section_by_name): New function. + * bfd-in2.h: Regenerate. + 2012-05-21 Andreas Schwab * elf32-m68k.c (elf_m68k_grok_prstatus): New function. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7535483623c..efd542fd390 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1704,6 +1704,8 @@ void bfd_section_list_clear (bfd *); asection *bfd_get_section_by_name (bfd *abfd, const char *name); +asection *bfd_get_next_section_by_name (asection *sec); + asection *bfd_get_section_by_name_if (bfd *abfd, const char *name, diff --git a/bfd/elflink.c b/bfd/elflink.c index 3614575d23d..42f27a00f75 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -12522,8 +12522,8 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) fini_reloc_cookie_rels (&cookie, stab); } - if (eh != NULL - && init_reloc_cookie_rels (&cookie, info, abfd, eh)) + while (eh != NULL + && init_reloc_cookie_rels (&cookie, info, abfd, eh)) { _bfd_elf_parse_eh_frame (abfd, info, eh, &cookie); if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, @@ -12531,6 +12531,7 @@ bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) &cookie)) ret = TRUE; fini_reloc_cookie_rels (&cookie, eh); + eh = bfd_get_next_section_by_name (eh); } if (bed->elf_backend_discard_info != NULL diff --git a/bfd/section.c b/bfd/section.c index 3a70ccf994c..0a7908e1f6c 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -845,14 +845,8 @@ SYNOPSIS asection *bfd_get_section_by_name (bfd *abfd, const char *name); DESCRIPTION - Run through @var{abfd} and return the one of the - <>s whose name matches @var{name}, otherwise <>. - @xref{Sections}, for more information. - - This should only be used in special cases; the normal way to process - all sections of a given name is to use <> and - <> on the name (or better yet, base it on the section flags - or something else) for each section. + Return the most recently created section attached to @var{abfd} + named @var{name}. Return NULL if no such section exists. */ asection * @@ -867,6 +861,41 @@ bfd_get_section_by_name (bfd *abfd, const char *name) return NULL; } +/* +FUNCTION + bfd_get_next_section_by_name + +SYNOPSIS + asection *bfd_get_next_section_by_name (asection *sec); + +DESCRIPTION + Given @var{sec} is a section returned by @code{bfd_get_section_by_name}, + return the next most recently created section attached to the same + BFD with the same name. Return NULL if no such section exists. +*/ + +asection * +bfd_get_next_section_by_name (asection *sec) +{ + struct section_hash_entry *sh; + const char *name; + unsigned long hash; + + sh = ((struct section_hash_entry *) + ((char *) sec - offsetof (struct section_hash_entry, section))); + + hash = sh->root.hash; + name = sec->name; + for (sh = (struct section_hash_entry *) sh->root.next; + sh != NULL; + sh = (struct section_hash_entry *) sh->root.next) + if (sh->root.hash == hash + && strcmp (sh->root.string, name) == 0) + return &sh->section; + + return NULL; +} + /* FUNCTION bfd_get_section_by_name_if -- 2.30.2