Guilherme Bernal
Guilherme Bernal

Reputation: 8313

Linking libgcc into a -nostdlib compilation

I'm trying to produce a executable without dependency on libc (or any other). First I have done this:

// test.c
void _start()
{
    // write(1, "hello!\n", 7);
    asm ("int $0x80"::"a"(4), "b"(1), "c"("hello!\n"), "d"(7));

    // exit(0);
    asm ("int $0x80"::"a"(1), "b"(0));
}

Compiling with gcc -m32 -nostdlib test.c -o test:

hello

So far so good. Later I attempted to use some more "advanced" C like long long. On 32-bit platforms (my case) this requires libgcc:

// test.c
void _start()
{
    volatile long long int a = 10;
    volatile long long int b = 5;
    volatile int c = a/b; // Implemented as a call to '__divdi3'
}

This fails compilation with undefined reference to '__divdi3'. Seems correct as I didn't actually told it to link. But adding the flag -static-libgcc does not fix the issue! Why?

Note that I cannot link dynamically to libgcc. The following must hold true:

$ ldd test
    not a dynamic executable

I'm compiling from 64-bit Ubuntu 14.04 with gcc 4.8.2 (nothing fancy).

Upvotes: 3

Views: 4406

Answers (1)

Guilherme Bernal
Guilherme Bernal

Reputation: 8313

Ended up finding the solution myself. Seems like gcc wasn't able to find the library and didn't bother complaining about it. I ran the following:

$ locate libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/32/libgcc.a
/usr/lib/gcc/x86_64-linux-gnu/4.8/x32/libgcc.a

Then instead of giving -static-libgcc to the compiler, I changed the flags to this:

gcc -m32 -nostdlib test.c -o test -L/usr/lib/gcc/x86_64-linux-gnu/4.8/32 -lgcc

And it compiles and runs just fine!


The -L is redundant. The following also works:

gcc -m32 -nostdlib test.c -o test -lgcc

Upvotes: 3

Related Questions