bfd/
authorH.J. Lu <hjl.tools@gmail.com>
Sun, 2 May 2004 14:36:25 +0000 (14:36 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Sun, 2 May 2004 14:36:25 +0000 (14:36 +0000)
2004-05-02  H.J. Lu  <hongjiu.lu@intel.com>

* section.c (bfd_get_section_by_name_if): New.
* bfd-in2.h: Regenerated.

gas/

2004-05-02  H.J. Lu  <hongjiu.lu@intel.com>

* config/obj-elf.c (get_section): Return bfd_boolean.
(obj_elf_change_section): Call bfd_get_section_by_name_if
instead of bfd_map_over_sections.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/section.c
gas/ChangeLog
gas/config/obj-elf.c

index 875fcd2..b5e5523 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * section.c (bfd_get_section_by_name_if): New.
+       * bfd-in2.h: Regenerated.
+
 2004-05-02  Alan Modra  <amodra@bigpond.net.au>
 
        * som.c (som_bfd_is_group_section): Define.
index 5843a19..c246356 100644 (file)
@@ -1433,6 +1433,12 @@ void bfd_section_list_clear (bfd *);
 
 asection *bfd_get_section_by_name (bfd *abfd, const char *name);
 
+asection *bfd_get_section_by_name_if
+   (bfd *abfd,
+    const char *name,
+    bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+    void *obj);
+
 char *bfd_get_unique_section_name
    (bfd *abfd, const char *templat, int *count);
 
index 58508a2..7f5365b 100644 (file)
@@ -801,6 +801,57 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
 
 /*
 FUNCTION
+       bfd_get_section_by_name_if
+
+SYNOPSIS
+       asection *bfd_get_section_by_name_if
+         (bfd *abfd,
+          const char *name,
+          bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+          void *obj);
+
+DESCRIPTION
+       Call the provided function @var{func} for each section
+       attached to the BFD @var{abfd} whose name matches @var{name},
+       passing @var{obj} as an argument. The function will be called
+       as if by
+
+|      func (abfd, the_section, obj);
+
+       It returns the first section for which @var{func} returns true,
+       otherwise <<NULL>>.
+
+*/
+
+asection *
+bfd_get_section_by_name_if (bfd *abfd, const char *name,
+                           bfd_boolean (*operation) (bfd *,
+                                                     asection *,
+                                                     void *),
+                           void *user_storage)
+{
+  struct section_hash_entry *sh;
+  unsigned long hash;
+
+  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+  if (sh == NULL)
+    return NULL;
+
+  hash = sh->root.hash;
+  do
+    {
+      if ((*operation) (abfd, &sh->section, user_storage))
+       return &sh->section;
+      sh = (struct section_hash_entry *) sh->root.next;
+    }
+  while (sh != NULL && sh->root.hash == hash
+        && strcmp (sh->root.string, name) == 0);
+
+  return NULL;
+}
+
+/*
+FUNCTION
        bfd_get_unique_section_name
 
 SYNOPSIS
index 0d1b4ec..484ed24 100644 (file)
@@ -1,3 +1,9 @@
+2004-05-02  H.J. Lu  <hongjiu.lu@intel.com>
+
+       * config/obj-elf.c (get_section): Return bfd_boolean.
+       (obj_elf_change_section): Call bfd_get_section_by_name_if
+       instead of bfd_map_over_sections.
+
 2004-04-30  H.J. Lu  <hongjiu.lu@intel.com>
 
        * config/obj-elf.c (get_section): New function.
index 3c7f011..7bd62d7 100644 (file)
@@ -469,32 +469,16 @@ struct section_stack
 
 static struct section_stack *section_stack;
 
-struct section_group
-{
-  const char *name;
-  const char *group_name;
-  asection *section;
-};
-
-static void
+static bfd_boolean
 get_section (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
 {
-  struct section_group *group = inf;
+  const char *gname = inf;
   const char *group_name = elf_group_name (sec);
   
-  /* Check if we have found the section we are looking for.  */
-  if (group->section)
-    return;
-
-  if ((sec->name == group->name
-       || (sec->name != NULL
-          && group->name != NULL
-          && strcmp (sec->name, group->name) == 0))
-      && (group_name == group->group_name
+  return (group_name == gname
          || (group_name != NULL
-             && group->group_name != NULL
-             && strcmp (group_name, group->group_name) == 0)))
-    group->section = sec;
+             && gname != NULL
+             && strcmp (group_name, gname) == 0));
 }
 
 /* Handle the .section pseudo-op.  This code supports two different
@@ -524,10 +508,10 @@ obj_elf_change_section (const char *name,
                        int linkonce,
                        int push)
 {
+  asection *old_sec;
   segT sec;
   flagword flags;
   const struct bfd_elf_special_section *ssect;
-  struct section_group group;
 
 #ifdef md_flush_pending_output
   md_flush_pending_output ();
@@ -548,14 +532,11 @@ obj_elf_change_section (const char *name,
   previous_section = now_seg;
   previous_subsection = now_subseg;
 
-  group.name = name;
-  group.group_name = group_name;
-  group.section = NULL;
-  bfd_map_over_sections (stdoutput, get_section, &group);
-
-  if (group.section)
+  old_sec = bfd_get_section_by_name_if (stdoutput, name, get_section,
+                                       (void *) group_name);
+  if (old_sec)
     {
-      sec = group.section;
+      sec = old_sec;
       subseg_set (sec, 0);
     }
   else
@@ -571,7 +552,7 @@ obj_elf_change_section (const char *name,
        type = ssect->type;
       else if (type != ssect->type)
        {
-         if (group.section == NULL
+         if (old_sec == NULL
              /* FIXME: gcc, as of 2002-10-22, will emit
 
                 .section .init_array,"aw",@progbits
@@ -595,7 +576,7 @@ obj_elf_change_section (const char *name,
            }
        }
 
-      if (group.section == NULL && (attr & ~ssect->attr) != 0)
+      if (old_sec == NULL && (attr & ~ssect->attr) != 0)
        {
          /* As a GNU extension, we permit a .note section to be
             allocatable.  If the linker sees an allocatable .note
@@ -627,7 +608,7 @@ obj_elf_change_section (const char *name,
              override = TRUE;
            }
        }
-      if (!override && group.section == NULL)
+      if (!override && old_sec == NULL)
        attr |= ssect->attr;
     }
 
@@ -652,7 +633,7 @@ obj_elf_change_section (const char *name,
   if (linkonce)
     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
 
-  if (group.section == NULL)
+  if (old_sec == NULL)
     {
       symbolS *secsym;
 
@@ -677,14 +658,13 @@ obj_elf_change_section (const char *name,
       /* If section attributes are specified the second time we see a
         particular section, then check that they are the same as we
         saw the first time.  */
-      if (((group.section->flags ^ flags)
+      if (((old_sec->flags ^ flags)
           & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
              | SEC_EXCLUDE | SEC_SORT_ENTRIES | SEC_MERGE | SEC_STRINGS
              | SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD
              | SEC_THREAD_LOCAL)))
        as_warn (_("ignoring changed section attributes for %s"), name);
-      if ((flags & SEC_MERGE)
-         && group.section->entsize != (unsigned) entsize)
+      if ((flags & SEC_MERGE) && old_sec->entsize != (unsigned) entsize)
        as_warn (_("ignoring changed section entity size for %s"), name);
     }