This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
PATCH: Warning relocs against discarded functions
- To: Keith Owens <kaos at melbourne dot sgi dot com>
- Subject: PATCH: Warning relocs against discarded functions
- From: "H . J . Lu" <hjl at lucon dot org>
- Date: Thu, 1 Nov 2001 14:28:35 -0800
- Cc: Daniel Jacobowitz <dan at debian dot org>, gdb at sources dot redhat dot com,binutils at sourceware dot cygnus dot com
- References: <20011031174749.A28985@nevyn.them.org> <30951.1004618590@ocs3.intra.ocs.com.au>
On Thu, Nov 01, 2001 at 11:43:10PM +1100, Keith Owens wrote:
> The problem is worse than stabs. If a function is marked __exit _and_
> some code in another section refers to that function then :-
>
> * ld resolves the reference as offset xxx from the start of section
> .text.exit which is expected to get a decent start address.
> * Section .text.exit is discarded, giving it a zero start address.
> * The function call ends up as a branch to _address_ xxx.
>
> This is a silent bug on many architectures, it only bites when the
> __exit function is called, usually on a rarely tested error path. On
> architectures that use PC relative branches (such as IA64), the linker
> may not be able to fit a PC relative branch from the high kernel
> address to the low (and incorrect) xxx address into an instruction so
> it gets an error during link. Section .data.exit is even worse, most
> references to data are via full word pointers and the bug is silent
> again.
>
> ld should probably discard sections and all symbols in those sections
> before resolving external references.
How about this patch?
H.J.
-----
2001-11-01 H.J. Lu (hjl@gnu.org)
* elflink.h (elf_link_input_bfd): Complain relocs against
discarded sections.
Index: elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.88
diff -u -p -r1.88 elflink.h
--- elflink.h 2001/10/31 21:30:43 1.88
+++ elflink.h 2001/11/01 22:24:39
@@ -6079,6 +6079,7 @@ elf_link_input_bfd (finfo, input_bfd)
asection *o;
struct elf_backend_data *bed;
boolean emit_relocs;
+ struct elf_link_hash_entry **sym_hashes;
output_bfd = finfo->output_bfd;
bed = get_elf_backend_data (output_bfd);
@@ -6251,6 +6252,7 @@ elf_link_input_bfd (finfo, input_bfd)
}
/* Relocate the contents of each section. */
+ sym_hashes = elf_sym_hashes (input_bfd);
for (o = input_bfd->sections; o != NULL; o = o->next)
{
bfd_byte *contents;
@@ -6298,26 +6300,49 @@ elf_link_input_bfd (finfo, input_bfd)
&& o->reloc_count > 0)
return false;
-#if BFD_VERSION_DATE < 20031005
{
Elf_Internal_Rela *rel, *relend;
/* Run through the relocs looking for any against section
- symbols from removed link-once sections. Zero any such
- relocs. We should really complain if anything in the
- final link tries to use it, but DWARF-based exception
- handling might have an entry in .eh_frame to describe a
- routine in the linkonce section, and it turns out to be
- hard to remove the .eh_frame entry too. FIXME. */
+ symbols from discarded or removed link-once sections.
+ Complain about relocs against discarded sections. Zero
+ relocs against removed link-once sections. We should
+ really complain if anything in the final link tries to
+ use it, but DWARF-based exception handling might have an
+ entry in .eh_frame to describe a routine in the linkonce
+ section, and it turns out to be hard to remove the
+ .eh_frame entry too. FIXME. */
rel = internal_relocs;
relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel;
for ( ; rel < relend; rel++)
{
unsigned long r_symndx = ELF_R_SYM (rel->r_info);
- if (r_symndx < locsymcount
- && (!elf_bad_symtab (input_bfd)
- || finfo->sections[r_symndx] != NULL))
+ if (r_symndx >= locsymcount
+ || (elf_bad_symtab (input_bfd)
+ && finfo->sections[r_symndx] == NULL))
{
+ struct elf_link_hash_entry *h;
+
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ /* Complain if the definition comes from a
+ discarded section. */
+ if ((h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section->output_section
+ == bfd_abs_section_ptr)
+ {
+ if (! ((*finfo->info->callbacks->undefined_symbol)
+ (finfo->info, h->root.root.string,
+ input_bfd, o, rel->r_offset, true)))
+ return false;
+ }
+ }
+#if BFD_VERSION_DATE < 20031005
+ else
+ {
isym = finfo->internal_syms + r_symndx;
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
{
@@ -6337,11 +6362,11 @@ elf_link_input_bfd (finfo, input_bfd)
}
}
}
- }
- }
#else
#error "gcc should be fixed by now, and this kludge no longer needed"
#endif
+ }
+ }
/* Relocate the section by invoking a back end routine.