This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Linker is broken
OK, I've audited places that set SEC_EXCLUDE and think I have it all
sorted out. SEC_EXCLUDE, as the comment says in sections.c, is really
only meant for final linking, but it may be set by various ELF backend
section_from_shdr functions, where the type of linker operation, if any,
isn't available. We do want to ignore SEC_EXCLUDE in these cases if
doing a relocatable link. However, the linker should act on SEC_EXCLUDE
set by bfd/stabs.c during relocatable linking. That's the reason for
the SEC_DEBUGGING test.
The cleanest solution that I can see to the current problem is to
twiddle SEC_EXCLUDE in ldlang.c:lang_add_section. Then all later linker
code can simply test SEC_EXCLUDE without worrying about SEC_DEBUGGING
and link_info.relocatable.
* elf.c (_bfd_elf_make_section_from_shdr): Don't set SEC_EXCLUDE
for SHT_GROUP sections.
* ldlang.c (lang_add_section): Set SEC_EXCLUDE for SEC_GROUP
sections when doing a final link. Clear SEC_EXCLUDE when doing
a relocable link, except for SEC_DEBUGGING sections.
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Use the
same condition here to drop SEC_EXCLUDE orphan sections.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.228
diff -u -p -r1.228 elf.c
--- bfd/elf.c 25 May 2004 06:33:46 -0000 1.228
+++ bfd/elf.c 26 May 2004 09:33:21 -0000
@@ -677,7 +677,7 @@ _bfd_elf_make_section_from_shdr (bfd *ab
if (hdr->sh_type != SHT_NOBITS)
flags |= SEC_HAS_CONTENTS;
if (hdr->sh_type == SHT_GROUP)
- flags |= SEC_GROUP | SEC_EXCLUDE;
+ flags |= SEC_GROUP;
if ((hdr->sh_flags & SHF_ALLOC) != 0)
{
flags |= SEC_ALLOC;
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.148
diff -u -p -r1.148 ldlang.c
--- ld/ldlang.c 25 May 2004 06:33:50 -0000 1.148
+++ ld/ldlang.c 26 May 2004 09:33:53 -0000
@@ -1096,11 +1096,26 @@ lang_add_section (lang_statement_list_ty
discard = FALSE;
- /* Discard sections marked with SEC_EXCLUDE if we are doing a final
- link. Discard debugging sections marked with SEC_EXCLUDE on a
- relocatable link too. */
- if ((flags & SEC_EXCLUDE) != 0
- && ((flags & SEC_DEBUGGING) != 0 || !link_info.relocatable))
+ if (link_info.relocatable)
+ {
+ /* SEC_EXCLUDE is ignored when doing a relocatable link,
+ except in the special case of debug info. (See bfd/stabs.c) */
+ if ((flags & SEC_DEBUGGING) == 0)
+ flags &= ~SEC_EXCLUDE;
+ }
+ else
+ {
+ /* SEC_GROUP sections should be dropped on a final link. */
+ if ((flags & SEC_GROUP) != 0)
+ flags |= SEC_EXCLUDE;
+ }
+
+ /* Write SEC_EXCLUDE flag back, to simplify later linker code. */
+ if (section->owner != NULL)
+ bfd_set_section_flags (section->owner, section, flags);
+
+ /* Discard sections marked with SEC_EXCLUDE. */
+ if ((flags & SEC_EXCLUDE) != 0)
discard = TRUE;
/* Discard input sections which are assigned to a section named
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.114
diff -u -p -r1.114 elf32.em
--- ld/emultempl/elf32.em 19 May 2004 14:01:14 -0000 1.114
+++ ld/emultempl/elf32.em 26 May 2004 10:01:58 -0000
@@ -1182,7 +1182,9 @@ gld${EMULATION_NAME}_place_orphan (lang_
#define HAVE_SECTION(hold, name) \
(hold.os != NULL || (hold.os = lang_output_section_find (name)) != NULL)
- if ((s->flags & SEC_EXCLUDE) != 0 && !link_info.relocatable)
+ if (((s->flags & (SEC_EXCLUDE | SEC_GROUP)) != 0 && !link_info.relocatable)
+ || ((s->flags & (SEC_EXCLUDE | SEC_DEBUGGING))
+ == (SEC_EXCLUDE | SEC_DEBUGGING)))
{
if (s->output_section == NULL)
s->output_section = bfd_abs_section_ptr;
--
Alan Modra
IBM OzLabs - Linux Technology Centre