This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Confusing meaning of --no-undefined
Hi Alan, Hi H.J.,
I need your help/advice. I took a look at the error reported by Jan
Vroonhof:
http://sources.redhat.com/ml/binutils/2003-02/msg00024.html
concerning the fact that:
ld --share --no-undefined foo.o bar.so
does not report an undefined symbol in bar.so.
It seemed to me that the problem was in elf_link_output_extsym()
in bfd/elflink.h, where there is a test for unresolved symbols:
/* If we are not creating a shared library and this symbol is
referenced by a shared library but is not defined anywhere, then
warn that it is undefined. If we do not do this, the runtime
linker will complain that the symbol is undefined when the
program is run. We don't have to worry about symbols that are
referenced by regular files, because we will already have issued
warnings for them. */
if (! finfo->info->relocateable
&& ! finfo->info->allow_shlib_undefined
&& ! finfo->info->shared
&& h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
&& ! elf_link_check_versioned_symbol (finfo->info, h))
{
This seemed wrong to me, since if we *are* creating a shared library
we should also issue an error message unless allow_shlib_undefined
is true. So I changed the test like this:
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.204
diff -c -3 -p -w -r1.204 elflink.h
*** bfd/elflink.h 4 Feb 2003 12:49:57 -0000 1.204
--- bfd/elflink.h 11 Feb 2003 17:09:10 -0000
*************** elf_link_output_extsym (h, data)
*** 6096,6103 ****
referenced by regular files, because we will already have issued
warnings for them. */
if (! finfo->info->relocateable
! && ! finfo->info->allow_shlib_undefined
! && ! finfo->info->shared
&& h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
--- 6097,6103 ----
referenced by regular files, because we will already have issued
warnings for them. */
if (! finfo->info->relocateable
! && (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
&& h->root.type == bfd_link_hash_undefined
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
and sure enough the error message in Jan's test was now correctly
generated. When I ran the linker tests however, I discovered that
this patch causes the ld-elfweak tests to fail:
FAIL: ELF weak
because of errors like this:
/lib/libc.so.6: undefined reference to `_dl_lookup_versioned_symbol_skip@GLIBC_PRIVATE'
Now I can patch up the testsuite to add the --allow-shlib-undefined
switch (see second patch below), but is this the correct thing to
do ? You guys are more experienced with this area of the linker, so
I would appreciate your advice.
Cheers
Nick
Index: ld/testsuite/ld-elfweak/elfweak.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-elfweak/elfweak.exp,v
retrieving revision 1.4
diff -c -3 -p -w -r1.4 elfweak.exp
*** ld/testsuite/ld-elfweak/elfweak.exp 30 Jul 2002 07:41:13 -0000 1.4
--- ld/testsuite/ld-elfweak/elfweak.exp 11 Feb 2003 17:26:25 -0000
*************** proc build_lib {test libname objs dynsym
*** 281,287 ****
set files "$files $tmpdir/$obj"
}
! if {![ld_link $ld $tmpdir/$libname.so "$shared $files"]} {
fail $test
return
}
--- 281,287 ----
set files "$files $tmpdir/$obj"
}
! if {![ld_link $ld $tmpdir/$libname.so "--allow-shlib-undefined $shared $files"]} {
fail $test
return
}
*************** if ![ld_compile "$CC $CFLAGS" $srcdir/$s
*** 391,397 ****
return
}
! if {![ld_link $ld $tmpdir/libbar.so "$shared $tmpdir/bar.o"]} {
fail "ELF weak"
return
}
--- 391,397 ----
return
}
! if {![ld_link $ld $tmpdir/libbar.so "$shared --allow-shlib-undefined $tmpdir/bar.o"]} {
fail "ELF weak"
return
}
*************** if ![ld_compile "$CC $CFLAGS" $srcdir/$s
*** 426,442 ****
return
}
! if {![ld_link $ld $tmpdir/libfoo1a.so "$shared $tmpdir/foo1a.o"]} {
fail "ELF weak"
return
}
! if {![ld_link $ld $tmpdir/libfoo1b.so "$shared $tmpdir/foo1b.o"]} {
fail "ELF weak"
return
}
! if {![ld_link $ld $tmpdir/libbar1a.so "$shared $tmpdir/bar1a.o $tmpdir/libfoo1a.so"]} {
fail "ELF weak"
return
}
--- 426,442 ----
return
}
! if {![ld_link $ld $tmpdir/libfoo1a.so "$shared --allow-shlib-undefined $tmpdir/foo1a.o"]} {
fail "ELF weak"
return
}
! if {![ld_link $ld $tmpdir/libfoo1b.so "$shared --allow-shlib-undefined $tmpdir/foo1b.o"]} {
fail "ELF weak"
return
}
! if {![ld_link $ld $tmpdir/libbar1a.so "$shared --allow-shlib-undefined $tmpdir/bar1a.o $tmpdir/libfoo1a.so"]} {
fail "ELF weak"
return
}