PATCH: Properly identify the section in a group

H. J. Lu hjl@lucon.org
Wed Jun 30 20:21:00 GMT 2004


Error messages in

http://sources.redhat.com/bugzilla/show_bug.cgi?id=246

are generated with a patched linker. Otherwise, you will get

y1.o(.text+0x0):...

where you can have more than one .text sections.


H.J.
-------------- next part --------------
bfd/

2004-06-30  H.J. Lu  <hongjiu.lu@intel.com>

	* bfd.c (bfd_get_section_ident): New.

	* elf-bfd.h (bfd_elf_section_data): Add sec_group.
	(elf_sec_group): Defined.
	(_bfd_elf_setup_group_pointers): New prototype.

	* elf.c (_bfd_elf_setup_group_pointers): New function.
	* elfcode.h (elf_object_p): Call _bfd_elf_setup_group_pointers.

	* elflink.c (elf_link_read_relocs_from_section): Call
	bfd_get_section_ident to identify the section when reporting
	error.
	(_bfd_elf_link_output_relocs): Likewise.
	(elf_link_output_extsym): Likewise.
	(elf_link_input_bfd): Likewise.
	(bfd_elf_gc_record_vtinherit): Likewise.

	* bfd-in2.h: Regenerated.

ld/

2004-06-30  H.J. Lu  <hongjiu.lu@intel.com>

	* ldmisc.c (vfinfo): Call bfd_get_section_ident to identify
	the section.

--- binutils/bfd/bfd.c.ident	2004-05-17 18:59:10.000000000 -0700
+++ binutils/bfd/bfd.c	2004-06-30 11:01:27.546397214 -0700
@@ -1417,3 +1417,45 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE
      objalloc.  */
   bfd_hash_table_free (&preserve->section_htab);
 }
+
+/*
+FUNCTION
+	bfd_get_section_ident
+
+SYNOPSIS
+	char *bfd_get_section_ident (asection *sec);
+
+DESCRIPTION
+	This function returns "section name[group name]" in a malloced
+	buffer if @var{sec} is a member of an ELF section group and
+	returns NULL otherwise. The caller should free the non-NULL
+	return after use.
+
+*/
+
+char *
+bfd_get_section_ident (asection *sec)
+{
+  char *buf;
+  bfd_size_type nlen;
+  bfd_size_type glen;
+
+  if (sec->owner == NULL
+      || bfd_get_flavour (sec->owner) != bfd_target_elf_flavour
+      || elf_sec_group (sec) == NULL)
+    return NULL;
+
+  nlen = strlen (sec->name);
+  glen = strlen (elf_sec_group (sec)->name);
+  buf = bfd_malloc (nlen + glen + 2 + 1);
+  if (buf != NULL)
+    {
+      strcpy (buf, sec->name);
+      buf [nlen] = '[';
+      strcpy (&buf [nlen + 1], elf_sec_group (sec)->name);
+      buf [nlen + 1 + glen] = ']';
+      buf [nlen + 1 + glen + 1] = '\0';
+    }
+
+  return buf;
+}
--- binutils/bfd/elf-bfd.h.ident	2004-06-30 10:50:33.569053052 -0700
+++ binutils/bfd/elf-bfd.h	2004-06-30 10:55:11.242108924 -0700
@@ -1048,6 +1048,10 @@ struct bfd_elf_section_data
     struct bfd_symbol *id;
   } group;
 
+  /* Optional information about section group; NULL if it doesn't
+     belongs to any section group. */
+  asection *sec_group;
+
   /* A linked list of sections in the group.  Circular when used by
      the linker.  */
   asection *next_in_group;
@@ -1062,6 +1066,7 @@ struct bfd_elf_section_data
 #define elf_group_name(sec)    (elf_section_data(sec)->group.name)
 #define elf_group_id(sec)      (elf_section_data(sec)->group.id)
 #define elf_next_in_group(sec) (elf_section_data(sec)->next_in_group)
+#define elf_sec_group(sec)	(elf_section_data(sec)->sec_group)
 
 /* Return TRUE if section has been discarded.  */
 #define elf_discarded_section(sec)				\
@@ -1565,6 +1570,9 @@ extern bfd_boolean _bfd_elf_dynamic_symb
 extern bfd_boolean _bfd_elf_symbol_refs_local_p
   (struct elf_link_hash_entry *, struct bfd_link_info *, bfd_boolean);
 
+extern void _bfd_elf_setup_group_pointers
+  (bfd *);
+
 extern const bfd_target *bfd_elf32_object_p
   (bfd *);
 extern const bfd_target *bfd_elf32_core_file_p
--- binutils/bfd/elf.c.ident	2004-06-28 19:02:02.000000000 -0700
+++ binutils/bfd/elf.c	2004-06-30 10:52:47.938659221 -0700
@@ -612,6 +612,29 @@ setup_group (bfd *abfd, Elf_Internal_Shd
   return TRUE;
 }
 
+void
+_bfd_elf_setup_group_pointers (bfd *abfd)
+{
+  unsigned int i;
+  unsigned int num_group = elf_tdata (abfd)->num_group;
+
+  if (num_group == (unsigned) -1)
+    return;
+
+  for (i = 0; i < num_group; i++)
+    {
+      Elf_Internal_Shdr *shdr = elf_tdata (abfd)->group_sect_ptr[i];
+      Elf_Internal_Group *idx = (Elf_Internal_Group *) shdr->contents;
+      unsigned int n_elt = shdr->sh_size / 4;
+
+      while (--n_elt != 0)
+	if ((++idx)->shdr->bfd_section)
+	  elf_sec_group (idx->shdr->bfd_section) = shdr->bfd_section;
+	else
+	  abort ();
+    }
+}
+
 bfd_boolean
 bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
 {
--- binutils/bfd/elfcode.h.ident	2004-06-28 19:02:08.000000000 -0700
+++ binutils/bfd/elfcode.h	2004-06-30 10:50:33.661041145 -0700
@@ -742,6 +742,9 @@ elf_object_p (bfd *abfd)
 	  if (shindex == SHN_LORESERVE - 1)
 	    shindex += SHN_HIRESERVE + 1 - SHN_LORESERVE;
 	}
+
+      /* Set up group pointers.  */
+      _bfd_elf_setup_group_pointers (abfd);
     }
 
   /* Let the backend double check the format and override global
--- binutils/bfd/elflink.c.ident	2004-06-30 10:50:33.576052146 -0700
+++ binutils/bfd/elflink.c	2004-06-30 11:00:47.549574709 -0700
@@ -1859,10 +1859,14 @@ elf_link_read_relocs_from_section (bfd *
 	r_symndx >>= 24;
       if ((size_t) r_symndx >= nsyms)
 	{
+	  char *sec_name = bfd_get_section_ident (sec);
 	  (*_bfd_error_handler)
 	    (_("%s: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%s'"),
 	     bfd_archive_filename (abfd), (unsigned long) r_symndx,
-	     (unsigned long) nsyms, irela->r_offset, sec->name);
+	     (unsigned long) nsyms, irela->r_offset,
+	     sec_name ? sec_name : sec->name);
+	  if (sec_name)
+	    free (sec_name);
 	  bfd_set_error (bfd_error_bad_value);
 	  return FALSE;
 	}
@@ -2048,11 +2052,14 @@ _bfd_elf_link_output_relocs (bfd *output
     }
   else
     {
+      char *sec_name = bfd_get_section_ident (input_section);
       (*_bfd_error_handler)
 	(_("%s: relocation size mismatch in %s section %s"),
 	 bfd_get_filename (output_bfd),
 	 bfd_archive_filename (input_section->owner),
-	 input_section->name);
+	 sec_name ? sec_name : input_section->name);
+      if (sec_name)
+	free (sec_name);
       bfd_set_error (bfd_error_wrong_object_format);
       return FALSE;
     }
@@ -6073,11 +6080,14 @@ elf_link_output_extsym (struct elf_link_
 						 input_sec->output_section);
 	    if (sym.st_shndx == SHN_BAD)
 	      {
+		char *sec_name = bfd_get_section_ident (input_sec);
 		(*_bfd_error_handler)
 		  (_("%s: could not find output section %s for input section %s"),
 		   bfd_get_filename (finfo->output_bfd),
 		   input_sec->output_section->name,
-		   input_sec->name);
+		   sec_name ? sec_name : input_sec->name);
+		if (sec_name)
+		  free (sec_name);
 		eoinfo->failed = TRUE;
 		return FALSE;
 	      }
@@ -6590,6 +6600,10 @@ elf_link_input_bfd (struct elf_final_lin
 			    }
 			  else
 			    {
+			      char *r_sec
+				= bfd_get_section_ident (o);
+			      char *d_sec
+				= bfd_get_section_ident (h->root.u.def.section);
 			      char *r_name
 				= xstrdup (bfd_archive_filename (o->owner));
 			      finfo->info->callbacks->error_handler
@@ -6597,9 +6611,13 @@ elf_link_input_bfd (struct elf_final_lin
 				 _("`%T' referenced in section `%s' from %s: discarded in section `%s' from %s\n"),
 				 h->root.root.string,
 				 h->root.root.string,
-				 o->name, r_name,
-				 h->root.u.def.section->name,
+				 r_sec ? r_sec : o->name, r_name,
+				 d_sec ? d_sec : h->root.u.def.section->name,
 				 bfd_archive_filename (h->root.u.def.section->owner));
+			      if (r_sec)
+				free (r_sec);
+			      if (d_sec)
+				free (d_sec);
 			      if (r_name)
 				free (r_name);
 			    }
@@ -6630,6 +6648,10 @@ elf_link_input_bfd (struct elf_final_lin
 			      static int count;
 			      int ok;
 			      char *buf;
+			      char *r_sec
+				= bfd_get_section_ident (o);
+			      char *d_sec
+				= bfd_get_section_ident (sec);
 
 			      ok = asprintf (&buf, "local symbol %d",
 					     count++);
@@ -6638,10 +6660,16 @@ elf_link_input_bfd (struct elf_final_lin
 			      finfo->info->callbacks->error_handler
 				(LD_DEFINITION_IN_DISCARDED_SECTION,
 				 _("`%T' referenced in section `%s': discarded in section `%s' from %s\n"),
-				 buf, buf, o->name, sec->name,
+				 buf, buf,
+				 r_sec ? r_sec : o->name,
+				 d_sec ? d_sec : sec->name,
 				 bfd_archive_filename (input_bfd));
 			      if (ok != -1)
 				free (buf);
+			      if (r_sec)
+				free (r_sec);
+			      if (d_sec)
+				free (d_sec);
 			    }
 			}
 		    }
@@ -8555,6 +8583,7 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
   struct elf_link_hash_entry **search, *child;
   bfd_size_type extsymcount;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  char *sec_name;
 
   /* The sh_info field of the symtab header tells us where the
      external symbols start.  We don't care about the local symbols at
@@ -8578,8 +8607,10 @@ bfd_elf_gc_record_vtinherit (bfd *abfd,
 	goto win;
     }
 
+  sec_name = bfd_get_section_ident (sec);
   (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT",
-			 bfd_archive_filename (abfd), sec->name,
+			 bfd_archive_filename (abfd),
+			 sec_name ? sec_name : sec->name,
 			 (unsigned long) offset);
   bfd_set_error (bfd_error_invalid_operation);
   return FALSE;
--- binutils/ld/ldmisc.c.ident	2003-07-24 12:18:12.000000000 -0700
+++ binutils/ld/ldmisc.c	2004-06-30 11:06:18.639715864 -0700
@@ -241,6 +241,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
 		const char *functionname;
 		unsigned int linenumber;
 		bfd_boolean discard_last;
+		char *sec_name;
 
 		abfd = va_arg (arg, bfd *);
 		section = va_arg (arg, asection *);
@@ -269,7 +270,11 @@ vfinfo (FILE *fp, const char *fmt, va_li
 		      }
 		  }
 
-		lfinfo (fp, "%B(%s+0x%v)", abfd, section->name, offset);
+		sec_name = bfd_get_section_ident (section);
+		lfinfo (fp, "%B(%s+0x%v)", abfd,
+			sec_name ? sec_name : section->name, offset);
+		if (sec_name)
+		  free (sec_name);
 
 		discard_last = TRUE;
 		if (bfd_find_nearest_line (abfd, section, asymbols, offset,


More information about the Binutils mailing list