You are not logged in.

#1 2008-12-30 01:55:05

LiteHacker
Member
Registered: 2008-11-27
Posts: 38
Website

Statically compiling with ld

Hello all,

I've been trying to figure out how to get ld to compile statically. Now so far I haven't seen a method that works with ld alone, so I keep on using gcc instead.
In gcc in order to pass an argument to ld, you do "-Wl," ...so if I wanted to write "-s" to ld, I would write "-Wl,-s" to gcc.

I have found that gcc does not automatically remove unused functions. In order to remove unused functions, you do something like this:

gcc main.c -o main -fdata-sections -ffunction-sections -Wl,--gc-sections -Wl,-s

It works by providing extra information with fdata-sections and ffunction-sections... and then having ld remove it with --gc-sections.

At some point, I decided to statically compile a sample hello world program:

#include <stdio.h>

int main()
{
    puts("Hello, World!");
    return 0;
}

..comes out to 574,593 bytes... to allocate memory, print a message, and leave... in assembly this takes me at most 500 bytes (and that is if I do a LOT of memory allocating stuff and support unicode :P). So I'm thinking, maybe if I remove all the useless functions using the above method, I can drastically reduce the size?
...however in order to do such a thing, I need the linker to do the static work as it is the one removing the extra functions.

I tried doing the following:

gcc main.c -o main -Wl,-static

...and it gives me the following:

/usr/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status

...I have no idea what is this libgcc_s ...I tried looking in /usr/lib/gcc/*/ ..there is no libgcc_s there, only libgcc and libgcc_eh

I tried making a link between libgcc.a and libgcc_s.a but got the following:

/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioputs.o): In function `puts':
(.text+0x16d): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioputs.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(syslog.o): In function `closelog':
(.text+0xcd): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(syslog.o): In function `openlog':
(.text+0x382): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(syslog.o): In function `__vsyslog_chk':
(.text+0x8b8): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(syslog.o): In function `__vsyslog_chk':
(.text+0x8ca): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(syslog.o):(.eh_frame+0x166): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(backtrace.o): In function `backtrace':
(.text+0x55): undefined reference to `_Unwind_Backtrace'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(backtrace.o): In function `backtrace_helper':
(.text+0xff): undefined reference to `_Unwind_GetIP'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(backtrace.o): In function `backtrace_helper':
(.text+0x124): undefined reference to `_Unwind_GetGR'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(backtrace.o): In function `backtrace_helper':
(.text+0x12f): undefined reference to `_Unwind_GetCFA'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(vfprintf_chk.o): In function `__vfprintf_chk':
(.text+0x106): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(vfprintf_chk.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofclose.o): In function `fclose':
(.text+0x1a7): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofclose.o):(.eh_frame+0x166): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofflush.o): In function `fflush':
(.text+0xec): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofflush.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioftell.o): In function `ftell':
(.text+0x1ab): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioftell.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofwrite.o): In function `fwrite':
(.text+0x14c): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iofwrite.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioseekoff.o): In function `_IO_seekoff':
(.text+0x1fc): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ioseekoff.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(wfileops.o): In function `_IO_wfile_underflow':
(.text+0xcae): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(wfileops.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(fileops.o): In function `_IO_file_underflow':
(.text+0x1101): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(fileops.o): In function `_IO_file_fopen':
(.text+0x21b1): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(fileops.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iogetdelim.o): In function `getdelim':
(.text+0x278): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(iogetdelim.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(fseek.o): In function `fseek':
(.text+0xf2): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(fseek.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ftello.o): In function `ftello':
(.text+0x1ab): undefined reference to `_Unwind_Resume'
/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/../../../libc.a(ftello.o):(.eh_frame+0xde): undefined reference to `__gcc_personality_v0'
collect2: ld returned 1 exit status

Does anybody know what's wrong? Anybody ever try something like this before?

LiteHacker

Offline

#2 2008-12-30 07:36:39

string
Member
Registered: 2008-11-03
Posts: 286

Re: Statically compiling with ld

gcc main.c -o main -static

Offline

#3 2008-12-30 10:17:30

wuischke
Member
From: Suisse Romande
Registered: 2007-01-06
Posts: 630

Re: Statically compiling with ld

I'm afraid you have to compile a version of libc (preferable dietlibc or uClibc) using -fdata-sections and -ffunction-sections  and link against this version or removing unused sections won't work properly (also use the headers of this libc when compiling).

Just execute a nm main and you'll see it linked many functions you don't need.

Offline

Board footer

Powered by FluxBB