PATCH: PR ld/1396: prohibited cross reference to a local symbol

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

PATCH: PR ld/1396: prohibited cross reference to a local symbol

H.J. Lu-27
When we process prohibited cross reference, we need to match the
symbol type with the type of the symbol the relocation is against.


H.J.
----
2005-10-02  H.J. Lu  <[hidden email]>

        PR ld/1396
        * ldcref.c (check_refs): Accept asymbol *.
        (check_local_sym_xref): Pass sym to check_refs.
        (check_nocrossref): Pass NULL to check_refs.
        (check_refs_info): Add asymbol *.
        (check_refs): Add asymbol * to check_refs_info.
        (check_reloc_refs): Match relocations with proper symbols.

        * ldmisc.c (vfinfo): Don't add extra ":\n".

--- ld/ldcref.c.local 2005-05-16 11:04:39.000000000 -0700
+++ ld/ldcref.c 2005-10-02 07:03:46.000000000 -0700
@@ -71,7 +71,7 @@ struct cref_hash_table {
 static void output_one_cref (FILE *, struct cref_hash_entry *);
 static void check_local_sym_xref (lang_input_statement_type *);
 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
-static void check_refs (const char *, asection *, bfd *,
+static void check_refs (const char *, asymbol *, asection *, bfd *,
  struct lang_nocrossrefs *);
 static void check_reloc_refs (bfd *, asection *, void *);
 
@@ -387,7 +387,7 @@ check_local_sym_xref (lang_input_stateme
   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, outsecname) == 0)
- check_refs (symname, sym->section, abfd, ncrs);
+ check_refs (symname, sym, sym->section, abfd, ncrs);
  }
     }
 
@@ -429,7 +429,8 @@ check_nocrossref (struct cref_hash_entry
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, defsecname) == 0)
  for (ref = h->refs; ref != NULL; ref = ref->next)
-  check_refs (hl->root.string, hl->u.def.section, ref->abfd, ncrs);
+  check_refs (hl->root.string, NULL, hl->u.def.section,
+      ref->abfd, ncrs);
 
   return TRUE;
 }
@@ -439,6 +440,7 @@ check_nocrossref (struct cref_hash_entry
 
 struct check_refs_info {
   const char *sym_name;
+  asymbol *sym;
   asection *defsec;
   struct lang_nocrossrefs *ncrs;
   asymbol **asymbols;
@@ -451,6 +453,7 @@ struct check_refs_info {
 
 static void
 check_refs (const char *name,
+    asymbol *sym,
     asection *sec,
     bfd *abfd,
     struct lang_nocrossrefs *ncrs)
@@ -488,6 +491,7 @@ check_refs (const char *name,
     }
 
   info.sym_name = name;
+  info.sym = sym;
   info.defsec = sec;
   info.ncrs = ncrs;
   info.asymbols = asymbols;
@@ -513,6 +517,7 @@ check_reloc_refs (bfd *abfd, asection *s
   const char *outdefsecname;
   struct lang_nocrossref *ncr;
   const char *symname;
+  asymbol *sym;
   long relsize;
   arelent **relpp;
   long relcount;
@@ -538,9 +543,13 @@ check_reloc_refs (bfd *abfd, asection *s
   /* This section is one for which cross references are prohibited.
      Look through the relocations, and see if any of them are to
      INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
-     against the section symbol.  */
+     against the section symbol.  If INFO->SYM is NULL, the definition
+     is global, check for relocations against the global symbols.
+     Otherwise check for relocations against the local and section
+     symbols.  */
 
   symname = info->sym_name;
+  sym = info->sym;
 
   relsize = bfd_get_reloc_upper_bound (abfd, sec);
   if (relsize < 0)
@@ -561,6 +570,10 @@ check_reloc_refs (bfd *abfd, asection *s
 
       if (q->sym_ptr_ptr != NULL
   && *q->sym_ptr_ptr != NULL
+  && (sym == NULL
+      || ((sym->flags & (BSF_LOCAL | BSF_SECTION_SYM))
+  == ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
+  | BSF_SECTION_SYM))))
   && (symname != NULL
       ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
       : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
--- ld/ldmisc.c.local 2005-06-03 22:27:08.000000000 -0700
+++ ld/ldmisc.c 2005-10-01 14:41:32.000000000 -0700
@@ -339,7 +339,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
  && strcmp (last_file, filename) != 0)
     || strcmp (last_function, functionname) != 0)
   {
-    lfinfo (fp, _("%B: In function `%T':\n"),
+    lfinfo (fp, _("%B: In function `%T'"),
     abfd, functionname);
 
     last_bfd = abfd;
@@ -355,19 +355,19 @@ vfinfo (FILE *fp, const char *fmt, va_li
  discard_last = FALSE;
       }
     else
-      lfinfo (fp, "%B:", abfd);
+      lfinfo (fp, "%B", abfd);
 
     if (filename != NULL)
-      fprintf (fp, "%s:", filename);
+      fprintf (fp, ":%s", filename);
 
     if (functionname != NULL && fmt[-1] == 'G')
-      lfinfo (fp, "%T", functionname);
+      lfinfo (fp, ":%T", functionname);
     else if (filename != NULL)
       {
  if (linenumber != 0)
-  fprintf (fp, "%u", linenumber);
+  fprintf (fp, ":%u", linenumber);
  else
-  lfinfo (fp, "(%A+0x%v)", section, offset);
+  lfinfo (fp, ":(%A+0x%v)", section, offset);
       }
   }
  else
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol

H.J. Lu-27
On Sun, Oct 02, 2005 at 07:21:18AM -0700, H. J. Lu wrote:
> When we process prohibited cross reference, we need to match the
> symbol type with the type of the symbol the relocation is against.
>
>

Here is an updated patch to check global and local symbols explicitly.


H.J.
-----
2005-10-02  H.J. Lu  <[hidden email]>

        PR ld/1396
        * ldcref.c (check_refs): Accept asymbol *.
        (check_local_sym_xref): Pass sym to check_refs.
        (check_nocrossref): Pass NULL to check_refs.
        (check_refs_info): Add asymbol *.
        (check_refs): Add asymbol * to check_refs_info.
        (check_reloc_refs): Match relocations with proper symbols.

        * ldmisc.c (vfinfo): Don't add extra ":\n".

--- ld/ldcref.c.local 2005-05-16 11:04:39.000000000 -0700
+++ ld/ldcref.c 2005-10-02 08:53:05.000000000 -0700
@@ -71,7 +71,7 @@ struct cref_hash_table {
 static void output_one_cref (FILE *, struct cref_hash_entry *);
 static void check_local_sym_xref (lang_input_statement_type *);
 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
-static void check_refs (const char *, asection *, bfd *,
+static void check_refs (const char *, asymbol *, asection *, bfd *,
  struct lang_nocrossrefs *);
 static void check_reloc_refs (bfd *, asection *, void *);
 
@@ -387,7 +387,7 @@ check_local_sym_xref (lang_input_stateme
   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, outsecname) == 0)
- check_refs (symname, sym->section, abfd, ncrs);
+ check_refs (symname, sym, sym->section, abfd, ncrs);
  }
     }
 
@@ -429,7 +429,8 @@ check_nocrossref (struct cref_hash_entry
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, defsecname) == 0)
  for (ref = h->refs; ref != NULL; ref = ref->next)
-  check_refs (hl->root.string, hl->u.def.section, ref->abfd, ncrs);
+  check_refs (hl->root.string, NULL, hl->u.def.section,
+      ref->abfd, ncrs);
 
   return TRUE;
 }
@@ -439,6 +440,7 @@ check_nocrossref (struct cref_hash_entry
 
 struct check_refs_info {
   const char *sym_name;
+  asymbol *sym;
   asection *defsec;
   struct lang_nocrossrefs *ncrs;
   asymbol **asymbols;
@@ -451,6 +453,7 @@ struct check_refs_info {
 
 static void
 check_refs (const char *name,
+    asymbol *sym,
     asection *sec,
     bfd *abfd,
     struct lang_nocrossrefs *ncrs)
@@ -488,6 +491,7 @@ check_refs (const char *name,
     }
 
   info.sym_name = name;
+  info.sym = sym;
   info.defsec = sec;
   info.ncrs = ncrs;
   info.asymbols = asymbols;
@@ -513,6 +517,7 @@ check_reloc_refs (bfd *abfd, asection *s
   const char *outdefsecname;
   struct lang_nocrossref *ncr;
   const char *symname;
+  asymbol *sym;
   long relsize;
   arelent **relpp;
   long relcount;
@@ -538,9 +543,13 @@ check_reloc_refs (bfd *abfd, asection *s
   /* This section is one for which cross references are prohibited.
      Look through the relocations, and see if any of them are to
      INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
-     against the section symbol.  */
+     against the section symbol.  If INFO->SYM is NULL, the definition
+     is global, check for relocations against the global symbols.
+     Otherwise check for relocations against the local and section
+     symbols.  */
 
   symname = info->sym_name;
+  sym = info->sym;
 
   relsize = bfd_get_reloc_upper_bound (abfd, sec);
   if (relsize < 0)
@@ -561,6 +570,11 @@ check_reloc_refs (bfd *abfd, asection *s
 
       if (q->sym_ptr_ptr != NULL
   && *q->sym_ptr_ptr != NULL
+  && (sym == NULL
+      || ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
+      | BSF_SECTION_SYM)) != 0)
+  && (sym != NULL
+      || ((*q->sym_ptr_ptr)->flags & BSF_GLOBAL) != 0)
   && (symname != NULL
       ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
       : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
--- ld/ldmisc.c.local 2005-06-03 22:27:08.000000000 -0700
+++ ld/ldmisc.c 2005-10-01 14:41:32.000000000 -0700
@@ -339,7 +339,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
  && strcmp (last_file, filename) != 0)
     || strcmp (last_function, functionname) != 0)
   {
-    lfinfo (fp, _("%B: In function `%T':\n"),
+    lfinfo (fp, _("%B: In function `%T'"),
     abfd, functionname);
 
     last_bfd = abfd;
@@ -355,19 +355,19 @@ vfinfo (FILE *fp, const char *fmt, va_li
  discard_last = FALSE;
       }
     else
-      lfinfo (fp, "%B:", abfd);
+      lfinfo (fp, "%B", abfd);
 
     if (filename != NULL)
-      fprintf (fp, "%s:", filename);
+      fprintf (fp, ":%s", filename);
 
     if (functionname != NULL && fmt[-1] == 'G')
-      lfinfo (fp, "%T", functionname);
+      lfinfo (fp, ":%T", functionname);
     else if (filename != NULL)
       {
  if (linenumber != 0)
-  fprintf (fp, "%u", linenumber);
+  fprintf (fp, ":%u", linenumber);
  else
-  lfinfo (fp, "(%A+0x%v)", section, offset);
+  lfinfo (fp, ":(%A+0x%v)", section, offset);
       }
   }
  else
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol

Etienne Lorrain-2
In reply to this post by H.J. Lu-27
> On Sun, Oct 02, 2005 at 07:21:18AM -0700, H. J. Lu wrote:
> > When we process prohibited cross reference, we need to match the
> > symbol type with the type of the symbol the relocation is against.
>
> Here is an updated patch to check global and local symbols explicitly.

  Thanks, it works for me - vmlinux now links without problems.

  The bug report can be closed.
http://sourceware.org/bugzilla/show_bug.cgi?id=1396

 I hope I did not force you to work on Sunday.
 Etienne.


Reply | Threaded
Open this post in threaded view
|

Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol

H.J. Lu-27
On Mon, Oct 03, 2005 at 03:45:11PM +0100, Etienne Lorrain wrote:

> > On Sun, Oct 02, 2005 at 07:21:18AM -0700, H. J. Lu wrote:
> > > When we process prohibited cross reference, we need to match the
> > > symbol type with the type of the symbol the relocation is against.
> >
> > Here is an updated patch to check global and local symbols explicitly.
>
>   Thanks, it works for me - vmlinux now links without problems.
>
>   The bug report can be closed.
> http://sourceware.org/bugzilla/show_bug.cgi?id=1396
>

The patch is incorrect. Here is the right one.


H.J.
----
2005-10-04  H.J. Lu  <[hidden email]>

        PR ld/1396
        * ldcref.c (check_refs): Accept asymbol *.
        (check_local_sym_xref): Pass sym to check_refs.
        (check_nocrossref): Pass NULL to check_refs.
        (check_refs_info): Add asymbol *.
        (check_refs): Add asymbol * to check_refs_info.
        (check_reloc_refs): Match relocations with proper symbols.

        * ldmisc.c (vfinfo): Don't add extra ":\n".

--- ld/ldcref.c.local 2005-05-16 11:04:39.000000000 -0700
+++ ld/ldcref.c 2005-10-04 12:30:00.000000000 -0700
@@ -71,7 +71,7 @@ struct cref_hash_table {
 static void output_one_cref (FILE *, struct cref_hash_entry *);
 static void check_local_sym_xref (lang_input_statement_type *);
 static bfd_boolean check_nocrossref (struct cref_hash_entry *, void *);
-static void check_refs (const char *, asection *, bfd *,
+static void check_refs (const char *, asymbol *, asection *, bfd *,
  struct lang_nocrossrefs *);
 static void check_reloc_refs (bfd *, asection *, void *);
 
@@ -387,7 +387,7 @@ check_local_sym_xref (lang_input_stateme
   for (ncrs = nocrossref_list; ncrs != NULL; ncrs = ncrs->next)
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, outsecname) == 0)
- check_refs (symname, sym->section, abfd, ncrs);
+ check_refs (symname, sym, sym->section, abfd, ncrs);
  }
     }
 
@@ -429,7 +429,8 @@ check_nocrossref (struct cref_hash_entry
     for (ncr = ncrs->list; ncr != NULL; ncr = ncr->next)
       if (strcmp (ncr->name, defsecname) == 0)
  for (ref = h->refs; ref != NULL; ref = ref->next)
-  check_refs (hl->root.string, hl->u.def.section, ref->abfd, ncrs);
+  check_refs (hl->root.string, NULL, hl->u.def.section,
+      ref->abfd, ncrs);
 
   return TRUE;
 }
@@ -439,6 +440,7 @@ check_nocrossref (struct cref_hash_entry
 
 struct check_refs_info {
   const char *sym_name;
+  asymbol *sym;
   asection *defsec;
   struct lang_nocrossrefs *ncrs;
   asymbol **asymbols;
@@ -451,6 +453,7 @@ struct check_refs_info {
 
 static void
 check_refs (const char *name,
+    asymbol *sym,
     asection *sec,
     bfd *abfd,
     struct lang_nocrossrefs *ncrs)
@@ -488,6 +491,7 @@ check_refs (const char *name,
     }
 
   info.sym_name = name;
+  info.sym = sym;
   info.defsec = sec;
   info.ncrs = ncrs;
   info.asymbols = asymbols;
@@ -513,6 +517,7 @@ check_reloc_refs (bfd *abfd, asection *s
   const char *outdefsecname;
   struct lang_nocrossref *ncr;
   const char *symname;
+  asymbol *sym;
   long relsize;
   arelent **relpp;
   long relcount;
@@ -538,9 +543,13 @@ check_reloc_refs (bfd *abfd, asection *s
   /* This section is one for which cross references are prohibited.
      Look through the relocations, and see if any of them are to
      INFO->SYM_NAME.  If INFO->SYMNAME is NULL, check for relocations
-     against the section symbol.  */
+     against the section symbol.  If INFO->SYM is NULL, the definition
+     is global, check for relocations against the global symbols.
+     Otherwise check for relocations against the local and section
+     symbols.  */
 
   symname = info->sym_name;
+  sym = info->sym;
 
   relsize = bfd_get_reloc_upper_bound (abfd, sec);
   if (relsize < 0)
@@ -561,6 +570,14 @@ check_reloc_refs (bfd *abfd, asection *s
 
       if (q->sym_ptr_ptr != NULL
   && *q->sym_ptr_ptr != NULL
+  && ((sym == NULL
+       && (bfd_is_und_section (bfd_get_section (*q->sym_ptr_ptr))
+   || bfd_is_com_section (bfd_get_section (*q->sym_ptr_ptr))
+   || ((*q->sym_ptr_ptr)->flags & (BSF_GLOBAL
+   | BSF_WEAK)) != 0))
+      || (sym != NULL
+  && ((*q->sym_ptr_ptr)->flags & (BSF_LOCAL
+  | BSF_SECTION_SYM)) != 0))
   && (symname != NULL
       ? strcmp (bfd_asymbol_name (*q->sym_ptr_ptr), symname) == 0
       : (((*q->sym_ptr_ptr)->flags & BSF_SECTION_SYM) != 0
--- ld/ldmisc.c.local 2005-06-03 22:27:08.000000000 -0700
+++ ld/ldmisc.c 2005-10-04 10:51:59.000000000 -0700
@@ -339,7 +339,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
  && strcmp (last_file, filename) != 0)
     || strcmp (last_function, functionname) != 0)
   {
-    lfinfo (fp, _("%B: In function `%T':\n"),
+    lfinfo (fp, _("%B: In function `%T'"),
     abfd, functionname);
 
     last_bfd = abfd;
@@ -355,19 +355,19 @@ vfinfo (FILE *fp, const char *fmt, va_li
  discard_last = FALSE;
       }
     else
-      lfinfo (fp, "%B:", abfd);
+      lfinfo (fp, "%B", abfd);
 
     if (filename != NULL)
-      fprintf (fp, "%s:", filename);
+      fprintf (fp, ":%s", filename);
 
     if (functionname != NULL && fmt[-1] == 'G')
-      lfinfo (fp, "%T", functionname);
+      lfinfo (fp, ":%T", functionname);
     else if (filename != NULL)
       {
  if (linenumber != 0)
-  fprintf (fp, "%u", linenumber);
+  fprintf (fp, ":%u", linenumber);
  else
-  lfinfo (fp, "(%A+0x%v)", section, offset);
+  lfinfo (fp, ":(%A+0x%v)", section, offset);
       }
   }
  else
Reply | Threaded
Open this post in threaded view
|

Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol

Alan Modra
On Tue, Oct 04, 2005 at 12:52:49PM -0700, H. J. Lu wrote:

> 2005-10-04  H.J. Lu  <[hidden email]>
>
> PR ld/1396
> * ldcref.c (check_refs): Accept asymbol *.
> (check_local_sym_xref): Pass sym to check_refs.
> (check_nocrossref): Pass NULL to check_refs.
> (check_refs_info): Add asymbol *.
> (check_refs): Add asymbol * to check_refs_info.
> (check_reloc_refs): Match relocations with proper symbols.
>
> * ldmisc.c (vfinfo): Don't add extra ":\n".

This is OK, except that

>  struct check_refs_info {
>    const char *sym_name;
> +  asymbol *sym;
>    asection *defsec;
>    struct lang_nocrossrefs *ncrs;
>    asymbol **asymbols;

I don't see anywhere you use SYM other than to test for NULL
vs. non-NULL.  I think it would be better to change this to a boolean
called "global" or somesuch.

--
Alan Modra
IBM OzLabs - Linux Technology Centre
Reply | Threaded
Open this post in threaded view
|

Broken -frepo (was Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol)

Jakub Jelinek
In reply to this post by H.J. Lu-27
On Tue, Oct 04, 2005 at 12:52:49PM -0700, H. J. Lu wrote:
> The patch is incorrect. Here is the right one.

> 2005-10-04  H.J. Lu  <[hidden email]>
>
> PR ld/1396
> * ldcref.c (check_refs): Accept asymbol *.
> (check_local_sym_xref): Pass sym to check_refs.
> (check_nocrossref): Pass NULL to check_refs.
> (check_refs_info): Add asymbol *.
> (check_refs): Add asymbol * to check_refs_info.
> (check_reloc_refs): Match relocations with proper symbols.
>
> * ldmisc.c (vfinfo): Don't add extra ":\n".

This patch broke g++ -frepo.
While previously we got output like:
a.o: In function `main':
a.C:(.text+0xd): undefined reference to `C<int>::C()'
with 2005-10-05+ binutils we now get it all on one line:
a.o: In function `main':a.C:(.text+0xd): undefined reference to `C<int>::C()'

Is that ld change desirable?  If not, we need to fix it, otherwise
we should update collect2's ld output parser to handle even this.

Testcase is:
template<class T> class C
{
public:
    C();
};

template<class T>
C<T>::C()
{
}

int
main(void)
{
    C<int> x;
    return 0;
}

g++ -c -frepo a.C
g++ -frepo -o a a.o

2006-03-30  Jakub Jelinek  <[hidden email]>

        * tlink.c (scan_linker_output): Handle
        "In function `foo'...undefined...`bar'" on one line.

--- gcc/tlink.c.jj 2006-03-30 05:00:02.000000000 -0500
+++ gcc/tlink.c 2006-03-30 08:36:57.000000000 -0500
@@ -1,7 +1,7 @@
 /* Scan linker error messages for missing template instantiations and provide
    them.
 
-   Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+   Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Jason Merrill ([hidden email]).
 
@@ -648,10 +647,11 @@ scan_linker_output (const char *fname)
   sym = symbol_hash_lookup (p, false);
  }
 
+  retry_quoted:
       if (! sym && ! end)
  /* Try a mangled name in quotes.  */
  {
-  const char *oldq = q + 1;
+  const char *oldq = q + 1, *oldp;
   demangled *dem = 0;
   q = 0;
 
@@ -668,6 +668,7 @@ scan_linker_output (const char *fname)
     if (q != oldq)
       p = (char *)oldq;
   }
+  oldp = p;
 
   if (p)
     {
@@ -699,6 +700,15 @@ scan_linker_output (const char *fname)
   sym = symbol_hash_lookup (p, false);
  }
     }
+  /* 20051005+ GNU ld emits
+     "In function `foo':file:section: undefined reference to `bar'"
+     style error message.  */
+  else if (q && (oldp - oldq) >= (int) sizeof ("In function ")
+   && strcmp (oldp - sizeof ("In function "),
+      "In function ") == 0
+   && (p = strchr (q, '`')) != NULL
+   && strchr (p, '\'') != NULL)
+      goto retry_quoted;
  }
 
       if (sym && sym->tweaked)


        Jakub
Reply | Threaded
Open this post in threaded view
|

Re: Broken -frepo (was Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol)

H.J. Lu-27
On Thu, Mar 30, 2006 at 03:51:34PM +0200, Jakub Jelinek wrote:

> On Tue, Oct 04, 2005 at 12:52:49PM -0700, H. J. Lu wrote:
> > The patch is incorrect. Here is the right one.
>
> > 2005-10-04  H.J. Lu  <[hidden email]>
> >
> > PR ld/1396
> > * ldcref.c (check_refs): Accept asymbol *.
> > (check_local_sym_xref): Pass sym to check_refs.
> > (check_nocrossref): Pass NULL to check_refs.
> > (check_refs_info): Add asymbol *.
> > (check_refs): Add asymbol * to check_refs_info.
> > (check_reloc_refs): Match relocations with proper symbols.
> >
> > * ldmisc.c (vfinfo): Don't add extra ":\n".
>
> This patch broke g++ -frepo.
> While previously we got output like:
> a.o: In function `main':
> a.C:(.text+0xd): undefined reference to `C<int>::C()'
> with 2005-10-05+ binutils we now get it all on one line:
> a.o: In function `main':a.C:(.text+0xd): undefined reference to `C<int>::C()'
>
> Is that ld change desirable?  If not, we need to fix it, otherwise
> we should update collect2's ld output parser to handle even this.
>

When .o file isn't compiled with -g, the old linker outputs:

lib.o: In function `bar':
: prohibited cross reference from .text to `foo' in .foo

I changed it to one line:

lib.o: In function `bar': prohibited cross reference from .text to `foo' in .foo

I have no strong opinion one way or the other.



H.J.
Reply | Threaded
Open this post in threaded view
|

Re: Broken -frepo (was Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol)

Jakub Jelinek
On Thu, Mar 30, 2006 at 07:15:54AM -0800, H. J. Lu wrote:

> When .o file isn't compiled with -g, the old linker outputs:
>
> lib.o: In function `bar':
> : prohibited cross reference from .text to `foo' in .foo
>
> I changed it to one line:
>
> lib.o: In function `bar': prohibited cross reference from .text to `foo' in .foo
>
> I have no strong opinion one way or the other.

Digging some more into vfinfo, this sounds very wrong.
<bfd>: In function `function':
is on a separate line for a reason - if there is more than one error
with the same bfd/filename/function, ld will emit it just once, and with
In function on the same line that's just plain ugly (in addition that it
breaks tools that parse ld output).  Say:

a.o: In function `main':a.C:(.text+0xd): undefined reference to `C<int>::C()'
a.C:(.text+0x2b): undefined reference to `foobar'

where previously we would print here:

a.o: In function `main':
a.C:(.text+0xd): undefined reference to `C<int>::C()'
a.C:(.text+0x2b): undefined reference to `foobar'

(in both cases the In function `main' is for both errors, but it is really
non-obvious in the first case).

The reason why you got the ugly

lib.o: In function `bar':
: prohibited cross reference from .text to `foo' in .foo

is IMHO because ld just failed to print the location.
When bfd_find_nearest_line fails, it will for %C print:
lib.o:(.text+0x7): prohibited cross reference from .text to `foo' in .foo
so I don't understand why it doesn't provide section/offset also when it
knows the function name, but doesn't know file/line.  The following patch
reverts the ldmisc.c changes from last October and makes ld print for your
testcase (if I revert the ldcref.c fix, otherwise I don't get the error
obviously)
lib.o: In function `bar':
(.text+0x7): prohibited cross reference from .text to `foo' in .foo

Ok for trunk?

2006-03-30  Jakub Jelinek  <[hidden email]>

        * ldmisc.c (vfinfo): Revert 2005-10-05 changes.  If
        bfd_find_nearest_line succeeded for %C or %D, but filename
        is NULL, print section+offset at the end.

--- ld/ldmisc.c.jj 2005-12-14 13:50:35.000000000 +0100
+++ ld/ldmisc.c 2006-03-30 18:23:59.000000000 +0200
@@ -1,6 +1,6 @@
 /* ldmisc.c
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005
+   2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support.
 
@@ -337,7 +337,7 @@ vfinfo (FILE *fp, const char *fmt, va_li
  && strcmp (last_file, filename) != 0)
     || strcmp (last_function, functionname) != 0)
   {
-    lfinfo (fp, _("%B: In function `%T'"),
+    lfinfo (fp, _("%B: In function `%T':\n"),
     abfd, functionname);
 
     last_bfd = abfd;
@@ -353,20 +353,17 @@ vfinfo (FILE *fp, const char *fmt, va_li
  discard_last = FALSE;
       }
     else
-      lfinfo (fp, "%B", abfd);
+      lfinfo (fp, "%B:", abfd);
 
     if (filename != NULL)
-      fprintf (fp, ":%s", filename);
+      fprintf (fp, "%s:", filename);
 
     if (functionname != NULL && fmt[-1] == 'G')
-      lfinfo (fp, ":%T", functionname);
-    else if (filename != NULL)
-      {
- if (linenumber != 0)
-  fprintf (fp, ":%u", linenumber);
- else
-  lfinfo (fp, ":(%A+0x%v)", section, offset);
-      }
+      lfinfo (fp, "%T", functionname);
+    else if (filename != NULL && linenumber != 0)
+      fprintf (fp, "%u", linenumber);
+    else
+      lfinfo (fp, "(%A+0x%v)", section, offset);
   }
  else
   lfinfo (fp, "%B:(%A+0x%v)", abfd, section, offset);


        Jakub
Reply | Threaded
Open this post in threaded view
|

Re: Broken -frepo (was Re: PATCH: PR ld/1396: prohibited cross reference to a local symbol)

Alan Modra
On Thu, Mar 30, 2006 at 06:47:25PM +0200, Jakub Jelinek wrote:
> * ldmisc.c (vfinfo): Revert 2005-10-05 changes.  If
> bfd_find_nearest_line succeeded for %C or %D, but filename
> is NULL, print section+offset at the end.

Looks good to me.

--
Alan Modra
IBM OzLabs - Linux Technology Centre