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