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]

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


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