Search code examples
cgcclinkerglibcld

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


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?


Solution

  • I found another post which contained a clue: -dynamic-linker /lib/ld-linux.so.2.

    Try this:

    $ gcc hello.c -S -masm=intel
    $ as -o hello.o hello.s
    $ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o hello.o -lc /usr/lib/crtn.o
    $ ./hello
    hello, world
    $