This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Add bfd_get_section_by_name_if


On Fri, Apr 30, 2004 at 11:06:50AM +0930, Alan Modra wrote:
> On Thu, Apr 29, 2004 at 05:01:33PM -0700, H. J. Lu wrote:
> > bfd_map_over_sections is used to call a function on each section in
> > a bfd. However, there are many places where bfd_map_over_sections
> > is called to find something. It isn't necessary to go through all
> > sections once it is found. I'd like to modify bfd_map_over_sections to
> 
> I like the idea.  The following trick might help too, allowing you to
> find sections with the same name without going via bfd_map_over_sections.
> 
> I don't intend to apply this patch unless you (or others) find a use for
> it.
> 

This patch adds bfd_get_section_by_name_if to use it. There is no
regression on ia32, EM64T nor IA64.



H.J.
----
bfd/

2004-04-30  H.J. Lu  <hongjiu.lu@intel.com>

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

gas/

2004-04-30  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.

--- binutils/bfd/section.c.IF	2004-04-30 08:27:07.000000000 -0700
+++ binutils/bfd/section.c	2004-04-30 10:24:20.000000000 -0700
@@ -801,6 +801,47 @@ bfd_get_section_by_name (bfd *abfd, cons
 
 /*
 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;
+
+  sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+  for (; sh != NULL; sh = (struct section_hash_entry *) sh->root.next)
+    if ((*operation) (abfd, &sh->section, user_storage))
+      break;
+
+  return (sh != NULL) ? &sh->section : NULL;
+}
+
+/*
+FUNCTION
 	bfd_get_unique_section_name
 
 SYNOPSIS
--- binutils/gas/config/obj-elf.c.IF	2004-04-30 10:07:52.000000000 -0700
+++ binutils/gas/config/obj-elf.c	2004-04-30 10:15:54.000000000 -0700
@@ -473,28 +473,22 @@ 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 *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
-	  || (group_name != NULL
-	      && group->group_name != NULL
-	      && strcmp (group_name, group->group_name) == 0)))
-    group->section = sec;
+  return ((sec->name == group->name
+	   || (sec->name != NULL
+	       && group->name != NULL
+	       && strcmp (sec->name, group->name) == 0))
+	  && (group_name == group->group_name
+	      || (group_name != NULL
+		  && group->group_name != NULL
+		  && strcmp (group_name, group->group_name) == 0)));
 }
 
 /* Handle the .section pseudo-op.  This code supports two different
@@ -524,6 +518,7 @@ 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;
@@ -550,12 +545,11 @@ obj_elf_change_section (const char *name
 
   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,
+					&group);
+  if (old_sec)
     {
-      sec = group.section;
+      sec = old_sec;
       subseg_set (sec, 0);
     }
   else
@@ -571,7 +565,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 +589,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 +621,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 +646,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 +671,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);
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]