Re: `typeinfo for foo' referenced in section `.text' of bar.o: defined in discarded section `.gnu.linkonce.d._ZTI4foo' of r2.o

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: `typeinfo for foo' referenced in section `.text' of bar.o: defined in discarded section `.gnu.linkonce.d._ZTI4foo' of r2.o

Alan Modra
On Fri, 20 May 2005 12:03:34 +0200, Kendy Kutzner <[hidden email]> wrote:
[ http://lists.gnu.org/archive/html/bug-binutils/2005-05/msg00133.html ]

This has also been reported to bugzilla.
http://sources.redhat.com/bugzilla/show_bug.cgi?id=568

The following should fix the abort.

        PR 568
        * elf32-i386.c (elf_i386_relocate_section): Handle zero symndx
        for all reloc types.

Applying mainline and branch.  I'm also going to put
2005-05-12  H.J. Lu  <[hidden email]>
        * elf32-i386.c (elf_i386_relocate_section): Allow R_386_GOTOFF
        against protected function when building executable.
on the branch.

Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.141
diff -u -p -r1.141 elf32-i386.c
--- bfd/elf32-i386.c 20 May 2005 22:02:08 -0000 1.141
+++ bfd/elf32-i386.c 2 Jun 2005 14:20:46 -0000
@@ -2270,6 +2270,21 @@ elf_i386_relocate_section (bfd *output_b
    unresolved_reloc, warned);
  }
 
+      if (r_symndx == 0)
+ {
+ /* r_symndx will be zero only for relocs against symbols from
+   removed linkonce sections, or sections discarded by a linker
+   script.  For these relocs, we just want the section contents
+   zeroed.  Avoid any special processing in the switch below.  */
+  r_type = R_386_NONE;
+
+  relocation = 0;
+  if (howto->pc_relative)
+    relocation = (input_section->output_section->vma
+  + input_section->output_offset
+  + rel->r_offset);
+ }
+
       switch (r_type)
  {
  case R_386_GOT32:
@@ -2426,21 +2441,6 @@ elf_i386_relocate_section (bfd *output_b
 
  case R_386_32:
  case R_386_PC32:
-  /* r_symndx will be zero only for relocs against symbols
-     from removed linkonce sections, or sections discarded by
-     a linker script.  */
-  if (r_symndx == 0)
-    {
-      /* Zero the section contents.  eh_frame generated by old
- versions of gcc isn't edited by elf-eh-frame.c, so
- FDEs for discarded linkonce functions might remain.
- Putting zeros here will zero such FDE's address range.
- This is a hint to unwinders and other consumers of
- exception handling info that the FDE is invalid.  */
-      bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
-      break;
-    }
-
   if ((input_section->flags & SEC_ALLOC) == 0)
     break;
 
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Reply | Threaded
Open this post in threaded view
|

Re: `typeinfo for foo' referenced in section `.text' of bar.o: defined in discarded section `.gnu.linkonce.d._ZTI4foo' of r2.o

Alan Modra
This is the other part of the mainline fix for PR 568.  Mainline
currently bombs immediately if we get references to symbols in discarded
sections, which is a little harsh considering that people might be using
older compilers with a new binutils.  Also, there are situations where
even a new gcc will hit this linker error, for example
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17828 so we ought to at
least give people a chance to continue past this error.  I've made that
possible by printing the error via a new linker callback, which flags
the output as invalid and normally not written.  It's possible to
override this behaviour with --noinhibit-exec.  Lots of other places in
bfd linker functions probably should use this rather than calling
bfd_error_handler and giving up.

include/
        * bfdlink.h (struct bfd_link_callbacks): Add einfo.
bfd/
        * configure.in: Bump version
        * configure: Regenerate.
        * elflink.c (elf_link_input_bfd): Use einfo linker callback to print
        discarded section sym refs and kill linker output.
        * simple.c (simple_dummy_einfo): New function.
        (bfd_simple_get_relocated_section_contents): Init callbacks.einfo.
ld/
        * ldmain.c (link_callbacks): Add einfo.
        (add_archive_element): Use passed info, not link_info.
        (constructor_callback): Likewise.
        (reloc_overflow): Don't handle null bfd specially.
        (reloc_dangerous, unattached_reloc): Likewise.
        * ldmisc.c (vfinfo <B>): Print "ld generated" for null bfd.
        (vfinfo <C, D, G>): Handle null bfd.  Wrap comments.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.55
diff -u -p -r1.55 bfdlink.h
--- include/bfdlink.h 10 May 2005 10:21:08 -0000 1.55
+++ include/bfdlink.h 3 Jun 2005 06:40:56 -0000
@@ -422,11 +422,11 @@ struct bfd_link_info
 };
 
 /* This structures holds a set of callback functions.  These are
-   called by the BFD linker routines.  The first argument to each
-   callback function is the bfd_link_info structure being used.  Each
-   function returns a boolean value.  If the function returns FALSE,
-   then the BFD function which called it will return with a failure
-   indication.  */
+   called by the BFD linker routines.  Except for einfo, the first
+   argument to each callback function is the bfd_link_info structure
+   being used and each function returns a boolean value.  If the
+   function returns FALSE, then the BFD function which called it should
+   return with a failure indication.  */
 
 struct bfd_link_callbacks
 {
@@ -535,6 +535,9 @@ struct bfd_link_callbacks
   bfd_boolean (*notice)
     (struct bfd_link_info *, const char *name,
      bfd *abfd, asection *section, bfd_vma address);
+  /* General link info message.  */
+  void (*einfo)
+    (const char *fmt, ...);
 };
 
 /* The linker builds link_order structures which tell the code how to
Index: bfd/configure.in
===================================================================
RCS file: /cvs/src/src/bfd/configure.in,v
retrieving revision 1.185
diff -u -p -r1.185 configure.in
--- bfd/configure.in 29 May 2005 23:13:39 -0000 1.185
+++ bfd/configure.in 3 Jun 2005 09:33:50 -0000
@@ -8,7 +8,7 @@ AC_CONFIG_SRCDIR([libbfd.c])
 AC_CANONICAL_TARGET
 AC_ISC_POSIX
 
-AM_INIT_AUTOMAKE(bfd, 2.16.90)
+AM_INIT_AUTOMAKE(bfd, 2.16.91)
 
 dnl These must be called before AM_PROG_LIBTOOL, because it may want
 dnl to call AC_CHECK_PROG.
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.165
diff -u -p -r1.165 elflink.c
--- bfd/elflink.c 19 May 2005 08:26:55 -0000 1.165
+++ bfd/elflink.c 3 Jun 2005 06:40:14 -0000
@@ -7087,14 +7087,10 @@ elf_link_input_bfd (struct elf_final_lin
     {
       BFD_ASSERT (r_symndx != 0);
       if (action & COMPLAIN)
- {
-  (*_bfd_error_handler)
-    (_("`%s' referenced in section `%A' of %B: "
-       "defined in discarded section `%A' of %B"),
-     o, input_bfd, sec, sec->owner, sym_name);
-  bfd_set_error (bfd_error_bad_value);
-  return FALSE;
- }
+ (*finfo->info->callbacks->einfo)
+  (_("%X`%s' referenced in section `%A' of %B: "
+     "defined in discarded section `%A' of %B"),
+   sym_name, o, input_bfd, sec, sec->owner);
 
       /* Try to do the best we can to support buggy old
  versions of gcc.  If we've warned, or this is
Index: bfd/simple.c
===================================================================
RCS file: /cvs/src/src/bfd/simple.c,v
retrieving revision 1.24
diff -u -p -r1.24 simple.c
--- bfd/simple.c 4 May 2005 15:53:38 -0000 1.24
+++ bfd/simple.c 3 Jun 2005 06:40:15 -0000
@@ -92,6 +92,11 @@ simple_dummy_multiple_definition (struct
   return TRUE;
 }
 
+static void
+simple_dummy_einfo (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
+}
+
 struct saved_output_info
 {
   bfd_vma offset;
@@ -187,6 +192,7 @@ bfd_simple_get_relocated_section_content
   callbacks.reloc_dangerous = simple_dummy_reloc_dangerous;
   callbacks.unattached_reloc = simple_dummy_unattached_reloc;
   callbacks.multiple_definition = simple_dummy_multiple_definition;
+  callbacks.einfo = simple_dummy_einfo;
 
   memset (&link_order, 0, sizeof (link_order));
   link_order.next = NULL;
Index: ld/ldmain.c
===================================================================
RCS file: /cvs/src/src/ld/ldmain.c,v
retrieving revision 1.97
diff -u -p -r1.97 ldmain.c
--- ld/ldmain.c 12 May 2005 07:32:03 -0000 1.97
+++ ld/ldmain.c 3 Jun 2005 06:41:06 -0000
@@ -160,7 +160,8 @@ static struct bfd_link_callbacks link_ca
   reloc_overflow,
   reloc_dangerous,
   unattached_reloc,
-  notice
+  notice,
+  einfo
 };
 
 struct bfd_link_info link_info;
@@ -873,7 +874,7 @@ add_keepsyms_file (const char *filename)
    a link.  */
 
 static bfd_boolean
-add_archive_element (struct bfd_link_info *info ATTRIBUTE_UNUSED,
+add_archive_element (struct bfd_link_info *info,
      bfd *abfd,
      const char *name)
 {
@@ -904,7 +905,7 @@ add_archive_element (struct bfd_link_inf
       bfd *from;
       int len;
 
-      h = bfd_link_hash_lookup (link_info.hash, name, FALSE, FALSE, TRUE);
+      h = bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, TRUE);
 
       if (h == NULL)
  from = NULL;
@@ -1145,7 +1146,7 @@ constructor_callback (struct bfd_link_in
   /* Ensure that BFD_RELOC_CTOR exists now, so that we can give a
      useful error message.  */
   if (bfd_reloc_type_lookup (output_bfd, BFD_RELOC_CTOR) == NULL
-      && (link_info.relocatable
+      && (info->relocatable
   || bfd_reloc_type_lookup (abfd, BFD_RELOC_CTOR) == NULL))
     einfo (_("%P%F: BFD backend error: BFD_RELOC_CTOR unsupported\n"));
 
@@ -1422,10 +1423,7 @@ reloc_overflow (struct bfd_link_info *in
   if (overflow_cutoff_limit == -1)
     return TRUE;
 
-  if (abfd == NULL)
-    einfo (_("%P%X: generated"));
-  else
-    einfo ("%X%C:", abfd, section, address);
+  einfo ("%X%C:", abfd, section, address);
 
   if (overflow_cutoff_limit >= 0
       && overflow_cutoff_limit-- == 0)
@@ -1477,11 +1475,8 @@ reloc_dangerous (struct bfd_link_info *i
  asection *section,
  bfd_vma address)
 {
-  if (abfd == NULL)
-    einfo (_("%P%X: generated"));
-  else
-    einfo ("%X%C:", abfd, section, address);
-  einfo (_("dangerous relocation: %s\n"), message);
+  einfo (_("%X%C: dangerous relocation: %s\n"),
+ abfd, section, address, message);
   return TRUE;
 }
 
@@ -1495,11 +1490,8 @@ unattached_reloc (struct bfd_link_info *
   asection *section,
   bfd_vma address)
 {
-  if (abfd == NULL)
-    einfo (_("%P%X: generated"));
-  else
-    einfo ("%X%C:", abfd, section, address);
-  einfo (_(" reloc refers to symbol `%T' which is not being output\n"), name);
+  einfo (_("%X%C: reloc refers to symbol `%T' which is not being output\n"),
+ abfd, section, address, name);
   return TRUE;
 }
 
Index: ld/ldmisc.c
===================================================================
RCS file: /cvs/src/src/ld/ldmisc.c,v
retrieving revision 1.25
diff -u -p -r1.25 ldmisc.c
--- ld/ldmisc.c 12 May 2005 07:32:03 -0000 1.25
+++ ld/ldmisc.c 3 Jun 2005 06:41:06 -0000
@@ -190,7 +190,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
  bfd *abfd = va_arg (arg, bfd *);
 
  if (abfd == NULL)
-  fprintf (fp, "<none>");
+  fprintf (fp, "%s generated", program_name);
  else if (abfd->my_archive)
   fprintf (fp, "%s(%s)", abfd->my_archive->filename,
    abfd->filename);
@@ -275,49 +275,62 @@ vfinfo (FILE *fp, const char *fmt, va_li
  section = va_arg (arg, asection *);
  offset = va_arg (arg, bfd_vma);
 
- entry = (lang_input_statement_type *) abfd->usrdata;
- if (entry != (lang_input_statement_type *) NULL
-    && entry->asymbols != (asymbol **) NULL)
-  asymbols = entry->asymbols;
+ if (abfd == NULL)
+  {
+    entry = NULL;
+    asymbols = NULL;
+  }
  else
   {
-    long symsize;
-    long symbol_count;
-
-    symsize = bfd_get_symtab_upper_bound (abfd);
-    if (symsize < 0)
-      einfo (_("%B%F: could not read symbols\n"), abfd);
-    asymbols = xmalloc (symsize);
-    symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
-    if (symbol_count < 0)
-      einfo (_("%B%F: could not read symbols\n"), abfd);
-    if (entry != (lang_input_statement_type *) NULL)
+    entry = (lang_input_statement_type *) abfd->usrdata;
+    if (entry != (lang_input_statement_type *) NULL
+ && entry->asymbols != (asymbol **) NULL)
+      asymbols = entry->asymbols;
+    else
       {
- entry->asymbols = asymbols;
- entry->symbol_count = symbol_count;
+ long symsize;
+ long sym_count;
+
+ symsize = bfd_get_symtab_upper_bound (abfd);
+ if (symsize < 0)
+  einfo (_("%B%F: could not read symbols\n"), abfd);
+ asymbols = xmalloc (symsize);
+ sym_count = bfd_canonicalize_symtab (abfd, asymbols);
+ if (sym_count < 0)
+  einfo (_("%B%F: could not read symbols\n"), abfd);
+ if (entry != (lang_input_statement_type *) NULL)
+  {
+    entry->asymbols = asymbols;
+    entry->symbol_count = sym_count;
+  }
       }
   }
 
- /* The GNU Coding Standard requires that error messages be of the form:
+ /* The GNU Coding Standard requires that error messages
+   be of the form:
   
      source-file-name:lineno: message
 
-   We do not always have a line number available so if we cannot find
-   them we print out the section name and offset instread.  */
+   We do not always have a line number available so if
+   we cannot find them we print out the section name and
+   offset instread.  */
  discard_last = TRUE;
- if (bfd_find_nearest_line (abfd, section, asymbols, offset,
-   &filename, &functionname,
-   &linenumber))
+ if (abfd != NULL
+    && bfd_find_nearest_line (abfd, section, asymbols, offset,
+      &filename, &functionname,
+      &linenumber))
   {
     if (functionname != NULL && fmt[-1] == 'C')
       {
- /* Detect the case where we are printing out a message
-   for the same function as the last call to vinfo ("%C").
-   In this situation do not print out the ABFD filename
-   or the function name again.  Note - we do still print
-   out the source filename, as this will allow programs
-   that parse the linker's output (eg emacs) to correctly
-   locate multiple errors in the same source file.  */
+ /* Detect the case where we are printing out a
+   message for the same function as the last
+   call to vinfo ("%C").  In this situation do
+   not print out the ABFD filename or the
+   function name again.  Note - we do still
+   print out the source filename, as this will
+   allow programs that parse the linker's output
+   (eg emacs) to correctly locate multiple
+   errors in the same source file.  */
  if (last_bfd == NULL
     || last_file == NULL
     || last_function == NULL

--
Alan Modra
IBM OzLabs - Linux Technology Centre