I have a number of *.c files, including a bit of inline assembly, which form the entire program. ("program" being a shared object which gets executed via the _init function) There are no other source libraries. I have a memcpy.c and a memset.c, both containing the obvious functions. This is based on klibc (bare-bones Linux C library) with the assembly files replaced with *.c files.
No matter what attributes I place on the functions, either in the *.c or *.h files, the compiler produces undefined references to memset and memcpy. Though gcc certainly compiles these functions, it seems to forget this. I don't think an undefined reference should even be possible with the -fwhole-program option; this supposedly tells the compiler that I'm giving the WHOLE program. The gcc version: $ gcc -v Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux Thread model: posix gcc version 4.1.1 20060828 (Red Hat 4.1.1-20) The compile command line, with numerous unrelated *.c files chopped out of the middle: gcc -m32 -std=gnu99 -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.1.1/include -D__KLIBC__ -Iinclude -Iinclude/bits32 -Iinclude/arch/i386 -mregparm=3 -D_REGPARM=3 -Wstrict-prototypes -Wmissing-prototypes -msoft-float -fPIC -fomit-frame-pointer -march=pentium2 -Os -fno-common -mtune=nocona -Wstrict-aliasing=2 -fvisibility=hidden -W -Wall -Wshadow -g3 -fwhole-program --combine -c *** various things *** klibc/strcpy.c klibc/strncpy.c klibc/memcpy.c klibc/memset.c klibc/malloc.c klibc/mmap.c klibc/pause.c klibc/raise.c klibc/sleep.c klibc/sigaction.c klibc/strspn.c klibc/strxspn.c klibc/libgcc/__udivdi3.c klibc/libgcc/__umoddi3.c klibc/libgcc/__udivmoddi4.c -o bigblob.pic The link command line: gcc -m32 -shared -Wl,-O9 -Wl,-warn-common -Wl,-soname,libfoo.so.1 -Wl,-z,initfirst -nostartfiles -nodefaultlibs -nostdlib -o tmp.so bigblob.pic Examining the result: nm tmp.so | grep -i '.* u .*' U memcpy U memset Last of all, here is the memcpy function, showing some of the many attributes that I have tried: ///////////////////////////////////////////////////////// #include <string.h> #include <stdint.h> //void *memcpy(void *restrict dst, const void *restrict src, size_t n) __attribute__(( /*externally_visible, unused, noinline,*/ regparm(0) )); void *memcpy(void *restrict dst, const void *restrict src, size_t n) { const char *p = src; char *q = dst; #if defined(__i386__) size_t nl = n >> 2; asm volatile ("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb":"+c" (nl), "+S"(p), "+D"(q) :"r"(n & 3)); #elif defined(__x86_64__) size_t nq = n >> 3; asm volatile ("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb":"+c" (nq), "+S"(p), "+D"(q) :"r"((uint32_t) (n & 7))); #else while (n--) { *q++ = *p++; } #endif return dst; } -- Summary: forgotten memcpy and memset with -fwhole-program -- combine Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: acahalan at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29159