Bug 2721 - --as-needed vs. DT_NEEDED undef symbols checks
Summary: --as-needed vs. DT_NEEDED undef symbols checks
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-06-01 13:21 UTC by Jakub Jelinek
Modified: 2006-07-20 21:06 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2006-06-01 13:21:13 UTC
echo 'int foo1;' | gcc -shared -fpic -o /usr/lib/libfoo.so -xc - -xnone
-Wl,-soname,libfoo.so
echo 'int foo1; int foo2;' | gcc -shared -fpic -o libfoo.so -xc - -xnone
-Wl,-soname,libfoo.so
echo 'int foo (void) { extern int foo2; return foo2; }' | gcc -shared -fpic -o
libbar.so -xc - -xnone ./libfoo.so
echo 'extern int foo (void); int main (void) { return foo (); }' \
  | gcc -o test -xc - -xnone -Wl,--as-needed ./libfoo.so ./libbar.so
-Wl,--no-as-needed

fails to link because foo2 is undefined.
Withouth -Wl,--as-needed this links just fine (and so does adding
-Wl,--rpath-link,.), but I don't think --as-needed should make a difference
whether something links or not and what the above script does is something
that happens quite often - a project with several libraries adds a new symbol to
one of them and as the library is explicitly listed on the command line, the
user shouldn't be really requested to supply a rpath-link as well.

The problem I'd say is in
gld${EMULATION_NAME}_check_needed
which ignores --as-needed libraries:
  /* If this input file was an as-needed entry, and wasn't found to be
     needed at the stage it was linked, then don't say we have loaded it.  */
  if (s->as_needed
      && (s->the_bfd == NULL
          || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0))
    return;

I think it should in this case either load that library again (as in, call
gld${EMULATION_NAME}_try_needed on the same filename), or just mark the library
not only DYN_AS_NEEDED, but also DYN_DT_NEEDED and handle that combination of
flags.
Comment 1 Jakub Jelinek 2006-06-01 13:40:31 UTC
Oops, actually, swap the order of libfoo.so and libbar.so on the last command
line and then it is a regression from older binutils (e.g. 2.16.91.0.6 20060212).

echo 'int foo1;' | gcc -shared -fpic -o /usr/lib/libfoo.so -xc - -xnone \
  -Wl,-soname,libfoo.so
echo 'int foo1; int foo2;' | gcc -shared -fpic -o libfoo.so -xc - -xnone \
  -Wl,-soname,libfoo.so
echo 'int foo (void) { extern int foo2; return foo2; }' \
  | gcc -shared -fpic -o libbar.so -xc - -xnone ./libfoo.so
echo 'extern int foo (void); int main (void) { return foo (); }' \
   | gcc -o test -xc - -xnone -Wl,--as-needed ./libbar.so ./libfoo.so \ 
     -Wl,--no-as-needed

Comment 3 Alan Modra 2006-06-05 13:19:27 UTC
Fixed mainline with http://sources.redhat.com/ml/binutils-cvs/2006-06/msg00018.html
Comment 4 Daniel Jacobowitz 2006-07-20 21:06:48 UTC
This was fixed a while ago.