From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624 Description of problem: When lstat is called from a routine in a shared library, the following error is generated when a binary linked against the shared library is executed: <binary>: relocation error: <shared library>: undefined symbol: lstat This also holds true for lstat64, fstat, and fstat64. This appears to be a problem with the glibc headers, because in sys/stat.h, lstat is #defined to translate to __lxstat. lstat is not a symbol in libc, where __lxstat is. For some reason, the define is not being applied properly and lstat remains unresolved. As a work-around, the #define from sys/stat.h can be removed and inserted at the top of the shared library source file which calls lstat, and everything works correctly (see below). Version-Release number of selected component (if applicable): glibc-2.3.2-4.80.6 How reproducible: Always Steps to Reproduce: Can be reproduced by building the following source code: ==== main.c ==== #include <stdio.h> int size(char *); int main(int argc, char **argv) { int s; s = size(argv[1]); fprintf(stdout, "Size of %s is %d\n", argv[1], s); return 0; } ==== size.c ==== #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int size(char *file) { struct stat sbuf; if (lstat(file, &sbuf) < 0) { perror("lstat"); return 0; } fprintf(stdout, "File size: %d\n",sbuf.st_size); return sbuf.st_size; } Then: % gcc -c -o size.o size.c % ld -G -o libsize.so size.o % gcc -L. -lsize -o main main.c % export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. % ./main main.c Actual Results: Received the relocation error: ./main: relocation error: ./libsize.so: undefined symbol: lstat Expected Results: The binary should have executed without the relocation error. Additional info: There is a work-around for this, though it is somewhat awkward. Modifying the size.c file to include the #define from sys/stat.h corrects the problem: ==== size.c ==== #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> static __inline__ int lstat (__const char *__path, struct stat *__statbuf) __THROW { return __lxstat (_STAT_VER, __path, __statbuf); } int size(char *file) { struct stat sbuf; if (lstat(file, &sbuf) < 0) { perror("lstat"); return 0; } fprintf(stdout, "File size: %d\n",sbuf.st_size); return sbuf.st_size; } Rebuild using the steps above, and everything works correctly.
The problem is in how you are building the shared library. Never ever use ld directly unless you know what you are doing. Use gcc -shared -o libsize.so size.o to link it instead. lstat etc. are not #define's, they are extern inline functions, but without optimizations (ie. how you are compiling it) they are not inlined. gcc driver during linking ensures the library is linked against all necessary libraries (like -lc, which actually expands to libc.so.6 dependency and libc_nonshared.a).