Linking a C program directly with ld fails with undefined reference to `__libc_csu_fini`

Viewed 30741

I'm trying to compile a C program under Linux. However, out of curiosity, I'm trying to execute some steps by hand: I use:

  • the gcc frontend to produce assembler code
  • then run the GNU assembler to get an object file
  • and then link it with the C runtime to get a working executable.

Now I'm stuck with the linking part.

The program is a very basic "Hello world":

#include <stdio.h>
int main() {
   printf("Hello\n");
   return 0;
}

I use the following command to produce the assembly code:

gcc hello.c -S -masm=intel

I'm telling gcc to quit after compiling and dump the assembly code with Intel syntax.

Then I use th GNU assembler to produce the object file:

as -o hello.o hello.s

Then I try using ld to produce the final executable:

ld hello.o /usr/lib/libc.so /usr/lib/crt1.o -o hello

But I keep getting the following error message:

/usr/lib/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'

The symbols __libc_csu_fini/init seem to be a part of glibc, but I can't find them anywhere! I tried linking against libc statically (against /usr/lib/libc.a) with the same result.

What could the problem be?

8 Answers

Take it:

    $ echo 'main(){puts("ok");}' > hello.c
    $ gcc -c hello.c -o hello.o
    
    $ ld hello.o -o hello.exe /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o \
-dynamic-linker /lib/ld-linux.so.2 -lc
    
    $ ./hello.exe
    ok

Path to /usr/lib/crt*.o will when glibc configured with --prefix=/usr

Related