public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Spurious undefined reference error?
@ 2012-12-20 19:22 Dan Kegel
  2012-12-20 19:48 ` Dan Kegel
  0 siblings, 1 reply; 5+ messages in thread
From: Dan Kegel @ 2012-12-20 19:22 UTC (permalink / raw)
  To: binutils

The command (sanitized)

g++ -Wl,--verbose -v -pthread videos.C -Wl,-rpath,/opt/foo/bar/lib
-L/opt/foo/bar/lib \
-lxxx3 -lxxx6++ -llxxx7++ -lxxx6 -lxxx7 ../xxx8/xxx8.a -o videos

fails for me with

found libxxx6++.so at /opt/foo/bar/lib/libxxx6++.so
/usr/local/bin/ld: /opt/foo/bar/lib/libxxx3.so: undefined reference to
symbol 'foo::xxx6::bletch() const'
/usr/local/bin/ld: note: 'foo::xxx6::bletch() const' is defined in DSO
/opt/foo/bar/lib/libxxx6++.so so try adding it to the linker command
line

The commandline

g++ -Wl,--verbose -v -pthread videos.C -Wl,-rpath,/opt/foo/bar/lib
-L/opt/foo/bar/lib \
-lxxx3 -lxxx6++ -llxxx7++ -lxxx6 -lxxx7 ../xxx8/xxx8.a
/opt/foo/bar/lib/libxxx6++.so -o videos

works.

Why, if it was able to find the library, can't it use it without an
absolute path?

ld --version says 2.22; this is the stock linker on ubuntu 12.04 x86-64.

(Building a fresh binutils-2.23 from source in /usr/local doesn't seem
to help.... probably because even /usr/local/bin/ld --version still
says 2.22 then, so evidently it's not that easy to replace binutils.
A clue on how to gather more info would be appreciated.)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Spurious undefined reference error?
  2012-12-20 19:22 Spurious undefined reference error? Dan Kegel
@ 2012-12-20 19:48 ` Dan Kegel
  2012-12-20 20:00   ` H.J. Lu
  0 siblings, 1 reply; 5+ messages in thread
From: Dan Kegel @ 2012-12-20 19:48 UTC (permalink / raw)
  To: binutils

On Thu, Dec 20, 2012 at 11:22 AM, Dan Kegel <dank@kegel.com> wrote:
>(Building a fresh binutils-2.23 from source in /usr/local doesn't seem
>to help.... probably because even /usr/local/bin/ld --version still
>says 2.22

Logging in again, I see that now ld --version says
GNU ld (GNU Binutils) 2.23.0.20121106
so I must have had a path problem.  The new linker still doesn't help.

The problem was not present on ubuntu 10.04, where ld --version said
GNU ld (GNU Binutils for Ubuntu) 2.20.1-system.20100303

I guess I can now try a regression search.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Spurious undefined reference error?
  2012-12-20 19:48 ` Dan Kegel
@ 2012-12-20 20:00   ` H.J. Lu
  2012-12-20 23:19     ` Dan Kegel
  0 siblings, 1 reply; 5+ messages in thread
From: H.J. Lu @ 2012-12-20 20:00 UTC (permalink / raw)
  To: Dan Kegel; +Cc: binutils

On Thu, Dec 20, 2012 at 11:47 AM, Dan Kegel <dank@kegel.com> wrote:
> On Thu, Dec 20, 2012 at 11:22 AM, Dan Kegel <dank@kegel.com> wrote:
>>(Building a fresh binutils-2.23 from source in /usr/local doesn't seem
>>to help.... probably because even /usr/local/bin/ld --version still
>>says 2.22
>
> Logging in again, I see that now ld --version says
> GNU ld (GNU Binutils) 2.23.0.20121106
> so I must have had a path problem.  The new linker still doesn't help.
>
> The problem was not present on ubuntu 10.04, where ld --version said
> GNU ld (GNU Binutils for Ubuntu) 2.20.1-system.20100303
>
> I guess I can now try a regression search.

I think Ubuntu changed linker command-line options passed from GCC
driver.  Please compare the linker command-line options

-- 
H.J.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Spurious undefined reference error?
  2012-12-20 20:00   ` H.J. Lu
@ 2012-12-20 23:19     ` Dan Kegel
  2013-01-08  6:10       ` Alan Modra
  0 siblings, 1 reply; 5+ messages in thread
From: Dan Kegel @ 2012-12-20 23:19 UTC (permalink / raw)
  To: H.J. Lu; +Cc: binutils

On Thu, Dec 20, 2012 at 12:00 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> The problem was not present on ubuntu 10.04
>
> I think Ubuntu changed linker command-line options passed from GCC
> driver.  Please compare the linker command-line options

On ubuntu 12.04, the extra options
  --no-add-needed --as-needed
appear on the collect2 commandline.

Adding  -Wl,--no-add-needed -Wl,--as-needed  to the g++ commandline on
ubuntu 10.04 replicates the link failure on the previously working
system.
Adding -Wl,--no-as-needed  on ubuntu 12.04 works around the problem.

On 10.04,  'readelf -d /opt/foo/bar/lib/libxxx3.so | grep NEEDED' showed
 0x0000000000000001 (NEEDED)             Shared library: [libxxx6++.so.2]
On 12.04, it didn't.

Adding the needed dependency in the Makefile for libxxx3
caused the NEEDED flag to appear, but that didn't seem solve the
linking problem,
even though from the doc for --as-needed, I would have thought it would.
( see thread http://sourceware.org/ml/binutils/2009-01/msg00413.html )

I'd kind of like to not need to pass --no-as-needed.  I suppose the
next step is a small test case.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Spurious undefined reference error?
  2012-12-20 23:19     ` Dan Kegel
@ 2013-01-08  6:10       ` Alan Modra
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Modra @ 2013-01-08  6:10 UTC (permalink / raw)
  To: Dan Kegel; +Cc: H.J. Lu, binutils

On Thu, Dec 20, 2012 at 03:19:25PM -0800, Dan Kegel wrote:
> On Thu, Dec 20, 2012 at 12:00 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> >> The problem was not present on ubuntu 10.04
> >
> > I think Ubuntu changed linker command-line options passed from GCC
> > driver.  Please compare the linker command-line options
> 
> On ubuntu 12.04, the extra options
>   --no-add-needed --as-needed
> appear on the collect2 commandline.
> 
> Adding  -Wl,--no-add-needed -Wl,--as-needed  to the g++ commandline on
> ubuntu 10.04 replicates the link failure on the previously working
> system.
> Adding -Wl,--no-as-needed  on ubuntu 12.04 works around the problem.

Using your testcase from
http://sourceware.org/bugzilla/show_bug.cgi?id=13141#c1
I could not reproduce this problem on my x86_64 Ubuntu 11.10 system.
ld says
GNU ld (GNU Binutils for Ubuntu) 2.21.53.20110810

Nor did I see a problem when using current mainline ld.  For both
versions of ld, we get a DT_NEEDED entry for libm in both libf1.so and
the main app.  Which is odd because --no-copy-dt-needed-entries was in
effect when linking app and there was no command line reference to
libm.  So I dug around a little to see why libm is somehow special and
found we're picking up libm via elf32.em:check_ld_so_conf(), which
calls search_needed() with needed.by == NULL, and that results in this
piece of code in try_needed() not seeing libm as a dependent library.

  /* Tell the ELF linker that we don't want the output file to have a
     DT_NEEDED entry for this file at all if the entry is from a file
     with DYN_NO_ADD_NEEDED.  */
  if (needed->by != NULL
      && (bfd_elf_get_dyn_lib_class (needed->by) & DYN_NO_ADD_NEEDED) != 0)
    link_class |= DYN_NO_NEEDED | DYN_NO_ADD_NEEDED;

Easily enough fixed.  I'll probably be blamed for breaking a number
of projects with this change, but of course all I'm doing here is
making http://sourceware.org/ml/binutils/2011-08/msg00129.html
effective.

	* emultempl/elf32.em (gld${EMULATION_NAME}_check_ld_so_conf): Replace
	"name" param with a bfd_link_needed_list pointer.  Update caller.
	(gld${EMULATION_NAME}_check_ld_elf_hints): Likewise.

Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.234
diff -u -p -r1.234 elf32.em
--- ld/emultempl/elf32.em	6 Dec 2012 00:25:18 -0000	1.234
+++ ld/emultempl/elf32.em	8 Jan 2013 05:27:24 -0000
@@ -569,7 +569,8 @@ EOF
 #endif
 
 static bfd_boolean
-gld${EMULATION_NAME}_check_ld_elf_hints (const char *name, int force)
+gld${EMULATION_NAME}_check_ld_elf_hints (const struct bfd_link_needed_list *l,
+					 int force)
 {
   static bfd_boolean initialized;
   static char *ld_elf_hints;
@@ -612,10 +613,9 @@ gld${EMULATION_NAME}_check_ld_elf_hints 
   if (ld_elf_hints == NULL)
     return FALSE;
 
-  needed.by = NULL;
-  needed.name = name;
-  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, & needed,
-					     force);
+  needed.by = l->by;
+  needed.name = l->name;
+  return gld${EMULATION_NAME}_search_needed (ld_elf_hints, &needed, force);
 }
 EOF
     # FreeBSD
@@ -787,7 +787,8 @@ gld${EMULATION_NAME}_parse_ld_so_conf
 }
 
 static bfd_boolean
-gld${EMULATION_NAME}_check_ld_so_conf (const char *name, int force)
+gld${EMULATION_NAME}_check_ld_so_conf (const struct bfd_link_needed_list *l,
+				       int force)
 {
   static bfd_boolean initialized;
   static char *ld_so_conf;
@@ -824,8 +825,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (c
     return FALSE;
 
 
-  needed.by = NULL;
-  needed.name = name;
+  needed.by = l->by;
+  needed.name = l->name;
   return gld${EMULATION_NAME}_search_needed (ld_so_conf, &needed, force);
 }
 
@@ -1308,7 +1309,7 @@ if [ "x${USE_LIBPATH}" = xyes ] ; then
   case ${target} in
     *-*-freebsd* | *-*-dragonfly*)
       fragment <<EOF
-	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l->name, force))
+	  if (gld${EMULATION_NAME}_check_ld_elf_hints (l, force))
 	    break;
 EOF
     # FreeBSD
@@ -1317,7 +1318,7 @@ EOF
     *-*-linux-* | *-*-k*bsd*-* | *-*-gnu*)
     # Linux
       fragment <<EOF
-	  if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
+	  if (gld${EMULATION_NAME}_check_ld_so_conf (l, force))
 	    break;
 
 EOF

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-08  6:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-20 19:22 Spurious undefined reference error? Dan Kegel
2012-12-20 19:48 ` Dan Kegel
2012-12-20 20:00   ` H.J. Lu
2012-12-20 23:19     ` Dan Kegel
2013-01-08  6:10       ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).