This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: The problem with linkonce sections in ELF
Date: Mon, 7 Feb 2000 18:06:39 -0800
From: "H . J . Lu" <hjl@lucon.org>
On Mon, Feb 07, 2000 at 08:54:50PM -0500, Ian Lance Taylor wrote:
>
> Yes, you're right, there are problems with my patch. It seems to
> confuse the linker.
>
> This needs to be redone somehow. I don't know when I will have the
> time.
>
> Do you see what I think is wrong with your patch?
I didn't study it further. I trust your judgement. If you can
remind me what is wrong in my patch, I may be able to figure
something out between yours and mine.
_bfd_strip_section_from_output should not strip the section if it has
another input section.
The existing code checks the link_orders to see if there is a
link_order. However, this is wrong. At the time the function is
called, the link_orders have not been set up. In fact, at the time
the code is called, the link order can not be set up.
Your patch stuffed in a link order, because that is what the existing
code was looking for. However, there shouldn't be a link order at
that point. Putting one in doesn't make sense.
I tried a different mechanism to detect whether there was another
input section for the output section. But I got it wrong.
But, actually, now I see that I made a simple mistake. Instead of my
earlier patch, try this one.
Ian
Index: section.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/section.c,v
retrieving revision 1.10
diff -u -r1.10 section.c
--- section.c 2000/01/13 22:10:36 1.10
+++ section.c 2000/02/08 02:11:56
@@ -1100,20 +1100,28 @@
SYNOPSIS
void _bfd_strip_section_from_output
- (asection *section);
+ (struct bfd_link_info *info, asection *section);
DESCRIPTION
- Remove @var{section} from the output. If the output section becomes
- empty, remove it from the output bfd.
+ Remove @var{section} from the output. If the output section
+ becomes empty, remove it from the output bfd. @var{info} may
+ be NULL; if it is not, it is used to decide whether the output
+ section is empty.
*/
void
-_bfd_strip_section_from_output (s)
+_bfd_strip_section_from_output (info, s)
+ struct bfd_link_info *info;
asection *s;
{
asection **spp, *os;
struct bfd_link_order *p, *pp;
+ boolean keep_os;
- /* Excise the input section from the link order. */
+ /* Excise the input section from the link order.
+
+ FIXME: For all calls that I can see to this function, the link
+ orders have not yet been set up. So why are we checking them? --
+ Ian */
os = s->output_section;
for (p = os->link_order_head, pp = NULL; p != NULL; pp = p, p = p->next)
if (p->type == bfd_indirect_link_order
@@ -1128,10 +1136,30 @@
break;
}
+ keep_os = os->link_order_head != NULL;
+
+ if (! keep_os && info != NULL)
+ {
+ bfd *abfd;
+ for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+ {
+ asection *is;
+ for (is = abfd->sections; is != NULL; is = is->next)
+ {
+ if (is != s && is->output_section == os)
+ break;
+ }
+ if (is != NULL)
+ break;
+ }
+ if (abfd != NULL)
+ keep_os = true;
+ }
+
/* If the output section is empty, remove it too. Careful about sections
that have been discarded in the link script -- they are mapped to
bfd_abs_section, which has no owner. */
- if (!os->link_order_head && os->owner)
+ if (!keep_os && os->owner != NULL)
{
for (spp = &os->owner->sections; *spp; spp = &(*spp)->next)
if (*spp == os)