public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* RFC: Short circuit bfd_map_over_sections
@ 2004-04-30  0:12 H. J. Lu
  2004-04-30  0:15 ` Ian Lance Taylor
  2004-04-30  4:15 ` Alan Modra
  0 siblings, 2 replies; 13+ messages in thread
From: H. J. Lu @ 2004-04-30  0:12 UTC (permalink / raw)
  To: binutils

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

void
bfd_map_over_sections (bfd *abfd,
		       bfd_boolean (*operation) (bfd *, asection *, void *),
		       void *user_storage)
{
  asection *sect;

  for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
    if (!(*operation) (abfd, sect, user_storage))
      break;
}

Any comments?


H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  0:12 RFC: Short circuit bfd_map_over_sections H. J. Lu
@ 2004-04-30  0:15 ` Ian Lance Taylor
  2004-04-30  0:20   ` H. J. Lu
  2004-04-30  4:15 ` Alan Modra
  1 sibling, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2004-04-30  0:15 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

"H. J. Lu" <hjl@lucon.org> writes:

> 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
> 
> void
> bfd_map_over_sections (bfd *abfd,
> 		       bfd_boolean (*operation) (bfd *, asection *, void *),
> 		       void *user_storage)
> {
>   asection *sect;
> 
>   for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
>     if (!(*operation) (abfd, sect, user_storage))
>       break;
> }
> 
> Any comments?

I don't think it would be wise to change bfd_map_over_sections at this
point.  It is widely used, including by GDB.  A lot of code would have
to changed to have the function argument return true.

I think that, unfortunately, we should add a new function for this.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  0:15 ` Ian Lance Taylor
@ 2004-04-30  0:20   ` H. J. Lu
  2004-04-30  0:29     ` Eric Christopher
  2004-04-30  1:33     ` Ian Lance Taylor
  0 siblings, 2 replies; 13+ messages in thread
From: H. J. Lu @ 2004-04-30  0:20 UTC (permalink / raw)
  To: binutils

On Thu, Apr 29, 2004 at 08:12:39PM -0400, Ian Lance Taylor wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> 
> > 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
> > 
> > void
> > bfd_map_over_sections (bfd *abfd,
> > 		       bfd_boolean (*operation) (bfd *, asection *, void *),
> > 		       void *user_storage)
> > {
> >   asection *sect;
> > 
> >   for (sect = abfd->sections; sect != NULL; i++, sect = sect->next)
> >     if (!(*operation) (abfd, sect, user_storage))
> >       break;
> > }
> > 
> > Any comments?
> 
> I don't think it would be wise to change bfd_map_over_sections at this
> point.  It is widely used, including by GDB.  A lot of code would have
> to changed to have the function argument return true.
> 
> I think that, unfortunately, we should add a new function for this.
> 

That is fine. What should we call it? bfd_run_over_sections,
bfd_call_over_sections, bfd_call_on_sections, ...


H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  0:20   ` H. J. Lu
@ 2004-04-30  0:29     ` Eric Christopher
  2004-04-30  1:33     ` Ian Lance Taylor
  1 sibling, 0 replies; 13+ messages in thread
From: Eric Christopher @ 2004-04-30  0:29 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils


> That is fine. What should we call it? bfd_run_over_sections,
> bfd_call_over_sections, bfd_call_on_sections, ...

I like call_on or call_over. If I had to choose I think I like call_on
more.

run_over sounds painful :)

-eric

-- 
Eric Christopher <echristo@redhat.com>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  0:20   ` H. J. Lu
  2004-04-30  0:29     ` Eric Christopher
@ 2004-04-30  1:33     ` Ian Lance Taylor
  2004-04-30  1:36       ` H. J. Lu
  1 sibling, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2004-04-30  1:33 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

"H. J. Lu" <hjl@lucon.org> writes:

> That is fine. What should we call it? bfd_run_over_sections,
> bfd_call_over_sections, bfd_call_on_sections, ...

By analogy with C++, it should be bfd_sections_find_if, and it should
return the first section for which the function returns true.

bfd_for_each_section is another possibility.

Or bfd_traverse_sections.

Ian

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  1:33     ` Ian Lance Taylor
@ 2004-04-30  1:36       ` H. J. Lu
  2004-04-30  7:29         ` Nick Clifton
  0 siblings, 1 reply; 13+ messages in thread
From: H. J. Lu @ 2004-04-30  1:36 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 502 bytes --]

On Thu, Apr 29, 2004 at 08:29:01PM -0400, Ian Lance Taylor wrote:
> "H. J. Lu" <hjl@lucon.org> writes:
> 
> > That is fine. What should we call it? bfd_run_over_sections,
> > bfd_call_over_sections, bfd_call_on_sections, ...
> 
> By analogy with C++, it should be bfd_sections_find_if, and it should
> return the first section for which the function returns true.
> 

I like bfd_sections_find_if. Here is a patch.

> bfd_for_each_section is another possibility.
> 
> Or bfd_traverse_sections.
> 

H.J.

[-- Attachment #2: bfd-section-if-1.patch --]
[-- Type: text/plain, Size: 1121 bytes --]

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

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

--- bfd/section.c.short	2003-12-04 10:43:20.000000000 -0800
+++ bfd/section.c	2004-04-29 18:30:25.000000000 -0700
@@ -1090,6 +1090,41 @@ bfd_map_over_sections (bfd *abfd,
 
 /*
 FUNCTION
+	bfd_sections_find_if
+
+SYNOPSIS
+	asection *bfd_sections_find_if
+	  (bfd *abfd,
+	   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}, 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.
+
+*/
+
+asection *
+bfd_sections_find_if (bfd *abfd,
+		      bfd_boolean (*operation) (bfd *, asection *, void *),
+		      void *user_storage)
+{
+  asection *sect;
+
+  for (sect = abfd->sections; sect != NULL; sect = sect->next)
+    if ((*operation) (abfd, sect, user_storage))
+      break;
+
+  return sect;
+}
+
+/*
+FUNCTION
 	bfd_set_section_size
 
 SYNOPSIS

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  0:12 RFC: Short circuit bfd_map_over_sections H. J. Lu
  2004-04-30  0:15 ` Ian Lance Taylor
@ 2004-04-30  4:15 ` Alan Modra
  2004-04-30  5:25   ` H. J. Lu
  2004-04-30 17:53   ` PATCH: Add bfd_get_section_by_name_if H. J. Lu
  1 sibling, 2 replies; 13+ messages in thread
From: Alan Modra @ 2004-04-30  4:15 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

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.

Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.67
diff -u -p -r1.67 section.c
--- bfd/section.c	1 Dec 2003 06:33:01 -0000	1.67
+++ bfd/section.c	30 Apr 2004 01:26:16 -0000
@@ -945,13 +945,19 @@ bfd_make_section_anyway (bfd *abfd, cons
   newsect = &sh->section;
   if (newsect->name != NULL)
     {
-      /* We are making a section of the same name.  It can't go in
-	 section_htab without generating a unique section name and
-	 that would be pointless;  We don't need to traverse the
-	 hash table.  */
-      newsect = bfd_zalloc (abfd, sizeof (asection));
-      if (newsect == NULL)
+      /* We are making a section of the same name.  Put it in the
+	 section hash table.  Even though we can't find it directly by a
+	 hash lookup, we'll be able to find the section by traversing
+	 sh->root.next quicker than looking at all the bfd sections.  */
+      struct section_hash_entry *new_sh;
+      new_sh = (struct section_hash_entry *)
+	bfd_section_hash_newfunc (NULL, &abfd->section_htab, name);
+      if (new_sh == NULL)
 	return NULL;
+
+      new_sh->root.next = sh->root.next;
+      sh->root.next = &new_sh->root;
+      newsect = &new_sh->section;
     }
 
   newsect->name = name;

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  4:15 ` Alan Modra
@ 2004-04-30  5:25   ` H. J. Lu
  2004-04-30 17:53   ` PATCH: Add bfd_get_section_by_name_if H. J. Lu
  1 sibling, 0 replies; 13+ messages in thread
From: H. J. Lu @ 2004-04-30  5:25 UTC (permalink / raw)
  To: binutils; +Cc: amodra

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.
> 

It may be useful for

http://sources.redhat.com/ml/binutils/2004-04/msg00763.html
Alan, can you take a look at it and

http://sources.redhat.com/ml/binutils/2004-04/msg00772.html

They are needed for section group support.

We can add

asection *bfd_get_section_by_name_if
  (bfd *abfd, const char *name,
   bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
   void *obj);

It will return the first section named NAME and FUNC returns true.


H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: RFC: Short circuit bfd_map_over_sections
  2004-04-30  1:36       ` H. J. Lu
@ 2004-04-30  7:29         ` Nick Clifton
  0 siblings, 0 replies; 13+ messages in thread
From: Nick Clifton @ 2004-04-30  7:29 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

Hi H. J.

>I like bfd_sections_find_if. Here is a patch.
>  
>
So do I.  Your patch is approved (along with a suitable ChangeLog entry, 
of course).

Cheers
  Nick

^ permalink raw reply	[flat|nested] 13+ messages in thread

* PATCH: Add bfd_get_section_by_name_if
  2004-04-30  4:15 ` Alan Modra
  2004-04-30  5:25   ` H. J. Lu
@ 2004-04-30 17:53   ` H. J. Lu
  2004-05-01 14:20     ` Alan Modra
  1 sibling, 1 reply; 13+ messages in thread
From: H. J. Lu @ 2004-04-30 17:53 UTC (permalink / raw)
  To: binutils

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);
     }
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: Add bfd_get_section_by_name_if
  2004-04-30 17:53   ` PATCH: Add bfd_get_section_by_name_if H. J. Lu
@ 2004-05-01 14:20     ` Alan Modra
  2004-05-01 15:19       ` H. J. Lu
  0 siblings, 1 reply; 13+ messages in thread
From: Alan Modra @ 2004-05-01 14:20 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Fri, Apr 30, 2004 at 10:44:10AM -0700, H. J. Lu wrote:
> +DESCRIPTION
> +	Call the provided function @var{func} for each section
> +	attached to the BFD @var{abfd} whose name matches @var{name},
[snip]

> +  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;

This doesn't work as advertised.  sh->root.next chains entries with the
same *index*, not necessarily the same string or even the same 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;

OK with the above change, assuming it compiles. ;-)

Oh, and I see I made an error in my bfd_make_section_anyway change.

	* section.c (bfd_make_section_anyway): Copy the whole
	bfd_hash_entry, not just "next" from existing entry.

Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.69
diff -u -p -r1.69 section.c
--- bfd/section.c	30 Apr 2004 15:01:15 -0000	1.69
+++ bfd/section.c	1 May 2004 14:12:08 -0000
@@ -955,7 +955,7 @@ bfd_make_section_anyway (bfd *abfd, cons
       if (new_sh == NULL)
 	return NULL;
 
-      new_sh->root.next = sh->root.next;
+      new_sh->root = sh->root;
       sh->root.next = &new_sh->root;
       newsect = &new_sh->section;
     }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: Add bfd_get_section_by_name_if
  2004-05-01 14:20     ` Alan Modra
@ 2004-05-01 15:19       ` H. J. Lu
  2004-05-02 13:32         ` Alan Modra
  0 siblings, 1 reply; 13+ messages in thread
From: H. J. Lu @ 2004-05-01 15:19 UTC (permalink / raw)
  To: binutils

On Sat, May 01, 2004 at 11:50:53PM +0930, Alan Modra wrote:
> On Fri, Apr 30, 2004 at 10:44:10AM -0700, H. J. Lu wrote:
> > +DESCRIPTION
> > +	Call the provided function @var{func} for each section
> > +	attached to the BFD @var{abfd} whose name matches @var{name},
> [snip]
> 
> > +  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;
> 
> This doesn't work as advertised.  sh->root.next chains entries with the
> same *index*, not necessarily the same string or even the same 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;

I don't think it is right. We need to run operation on all matching
sections. That is

      while ((sh = (struct section_hash_entry *) sh->root.next) != NULL)
	if (sh->root.hash == hash
	    && strcmp (sh->root.string, name) == 0)
	  break;

> 
> OK with the above change, assuming it compiles. ;-)
> 

Here is the new one.


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-05-01 08:00:36.000000000 -0700
@@ -801,6 +801,60 @@ 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;
+  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;
+
+      while ((sh = (struct section_hash_entry *) sh->root.next) != NULL)
+	if (sh->root.hash == hash
+	    && strcmp (sh->root.string, name) == 0)
+	  break;
+    }
+  while (sh != NULL);
+
+  return 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-05-01 08:14:56.000000000 -0700
@@ -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);
     }
 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: Add bfd_get_section_by_name_if
  2004-05-01 15:19       ` H. J. Lu
@ 2004-05-02 13:32         ` Alan Modra
  0 siblings, 0 replies; 13+ messages in thread
From: Alan Modra @ 2004-05-02 13:32 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Sat, May 01, 2004 at 08:19:32AM -0700, H. J. Lu wrote:
> I don't think it is right. We need to run operation on all matching
> sections. That is

Duplicate names will always be adjacent.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2004-05-02 13:32 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-04-30  0:12 RFC: Short circuit bfd_map_over_sections H. J. Lu
2004-04-30  0:15 ` Ian Lance Taylor
2004-04-30  0:20   ` H. J. Lu
2004-04-30  0:29     ` Eric Christopher
2004-04-30  1:33     ` Ian Lance Taylor
2004-04-30  1:36       ` H. J. Lu
2004-04-30  7:29         ` Nick Clifton
2004-04-30  4:15 ` Alan Modra
2004-04-30  5:25   ` H. J. Lu
2004-04-30 17:53   ` PATCH: Add bfd_get_section_by_name_if H. J. Lu
2004-05-01 14:20     ` Alan Modra
2004-05-01 15:19       ` H. J. Lu
2004-05-02 13:32         ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).