* elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame
authorAlan Modra <amodra@gmail.com>
Tue, 22 May 2012 12:09:26 +0000 (12:09 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 22 May 2012 12:09:26 +0000 (12:09 +0000)
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
bfd/bfd-in2.h
bfd/elflink.c
bfd/section.c

index a77a28c..270b83a 100644 (file)
@@ -1,3 +1,11 @@
+2012-05-22  Alan Modra  <amodra@gmail.com>
+
+       * 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  <schwab@linux-m68k.org>
 
        * elf32-m68k.c (elf_m68k_grok_prstatus): New function.
index 7535483..efd542f 100644 (file)
@@ -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,
index 3614575..42f27a0 100644 (file)
@@ -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
index 3a70ccf..0a7908e 100644 (file)
@@ -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
-       <<asection>>s whose name matches @var{name}, otherwise <<NULL>>.
-       @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 <<bfd_map_over_sections>> and
-       <<strcmp>> 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 *
@@ -869,6 +863,41 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
 
 /*
 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
 
 SYNOPSIS