Hi,

It turns out the undefined fstat symbol problem can be traced to
something going wrong with earlier build of newt.  As you can see,
libnewt.so was providing the fstat symbol:

[EMAIL PROTECTED]:/home/scsi/dhd/src/debian/boot-floppies/utilities/dbootstrap$ 
objdump --dynamic-syms /usr/lib/libnewt.so | grep fstat
0000000000018860  w   DF .text  0000000000000000  Base        0x88 fstat
0000000000018860 g    DF .text  0000000000000038  Base        0x88 __fstat

[EMAIL PROTECTED]:~$ objdump --dynamic-syms /usr/lib/libnewt.so | grep fstat
0000f14c  w   DF .text  00000028  Base        fstat
0000f14c g    DF .text  00000028  Base        __fstat

That version of libnewt0 will break library reduction if you compile
dbootstrap against it, because:

1) libloadtrm.a is compiled without -O and thus depends on fstat
   (fstat is inlined).
2) dbootstrap inherits an undefined fstat symbol from libloadtrm.a
   (which is also not compiled with -O)
3) The reduced version of libnewt.so that ends up on the root.bin disk
   doesn't provide the symbol (as well it shouldn't :P).
4) libc.so.6.1 doesn't provide fstat either.

This may be indicative of a bug in glibc or gcc (take your pick,
they're all broken at one point or another it seems...) - the
changelog indicates that libnewt0 was never compiled with optimization
before 0.50-6.

Specifically it seems that if you have a program that uses fstat() and
is compiled without optimization, that links with a library that uses
fstat() and was compiled without optimization, and then the library is
recompiled with optimization, the aforementioned program will no
longer work.

Here's a demonstration:

/* begin fstattest.c */
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
        int fd;
        struct stat buf;

        fd = open("foobar", O_RDWR | O_CREAT, 0644);
        if (fd < 0) {
                perror("foobar");
                return 1;
        }
        mystat(fd, &buf);
        fstat(fd, &buf);
        return 0;
}
/* end fstattest.c */

/* begin libfstattest.c */
#include <sys/stat.h>

int mystat(int fd, struct stat * buf)
{
        return fstat(fd, buf);
}
/* end libfstattest.c

Now, observe:

$ gcc -shared -o libfstattest.so libfstattest.c 
$ objdump --dynamic-syms libfstattest.so | grep fstat 
libfstattest.so:     file format elf32-i386
000007b4  w   DF .text  00000028  Base        fstat
000007b4 g    DF .text  00000028  Base        __fstat
$ gcc -o fstattest fstattest.c -L. -Wl,-rpath -Wl,`pwd` -lfstattest 
$ nm fstattest | grep fstat 
         U fstat
$ ./fstattest 
$ gcc -shared -o libfstattest.so -O libfstattest.c 
$ objdump --dynamic-syms libfstattest.so | grep fstat 
libfstattest.so:     file format elf32-i386
$ ./fstattest 
./fstattest: error in loading shared libraries: ./fstattest: undefined symbol: 
fstat

-- 
David Huggins-Daines, Senior Linux Consultant, Linuxcare, Inc.
613.562.1239 desk, 613.223.0225 mobile [EMAIL PROTECTED],
http://www.linuxcare.com/
Linuxcare. Support for the revolution.

Reply via email to