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