Embedded Freaks..

February 10, 2009

Removing Unused Functions/Dead Codes with GCC/GNU-ld

Filed under: embedded-tips — Tags: — kunilkuda @ 10:25 am

I was suprised to know that GCC failed to remove the dead codes from my program. Here’s an example:

kunil@cerpelai:~/Temp$ vi test.c
#include <stdio.h>

void unusedFunction(void) {
printf("This is a dead code\n");

int main(void) {
printf("Hello world\n");
return 0;

kunil@cerpelai:~/Temp$ gcc -Os test.c -o test.elf

If you take a look carefully on the ELF binary, you can see that GCC still includes the “unusedFunction()”, although nothing refers to it.

kunil@cerpelai:~/Temp$ objdump -d test.elf

test.elf:     file format elf32-i386
080483c4 <main>:
080483e9 <unusedFunction>:

So I was wondering if there’s something wrong with GCC (or GNU-ld), or should I add something to remove it.
After googling a while, I found this link, which exactly explains how to do it. So, to repeat the link, to remove the dead/unused functions:

  • Compile with “-fdata-sections” to keep the data in separate data sections and “-ffunction-sections” to keep functions in separate sections, so they (data and functions) can be discarded if unused.
  • Link with “–gc-sections” to remove unused sections.

So, the above example should be compiled with:

kunil@cerpelai:~/Temp$ gcc -Os -fdata-sections -ffunction-sections test.c -o test.elf -Wl,--gc-sections

And dead codes now is really really dead.

Btw, “–gc-sections” is architecture dependent. Your architecture’s GNU-ld may or may not support it. I have tested it with avr-ld and Ubuntu Intrepid ld. Both supports “–gc-sections” option.


  1. I’ve tried to run the same (using WinAVR GCC release 2009-03-14)

    Unfortunately, i still see the dead code. I define a dummy function never called from main(). I don’t get any error message so seemingly the command is correct but the dummy function is kept in the final binary.

    Any ideas ?

    Comment by maup — October 26, 2009 @ 10:34 pm

  2. Ask people who maintain AVR’s GCC ? It works for i386/x86 GCC and ARM GCC.

    Comment by kunilkuda — November 13, 2009 @ 5:51 pm

  3. maup, –gc-sections has exceptions. From ld manual:
    “… The section containing the entry symbol and all sections containing symbols undefined on the command-line will be kept, as will sections containing symbols referenced by dynamic objects…”
    Probably, your dummy functions is in same file as main() function or whatever gcc considers to be entry point in your program

    Comment by Artem — April 13, 2010 @ 10:24 pm

  4. Fantástico!



    Comment by Rodrigo Matos Palheta — December 15, 2010 @ 9:40 pm

  5. Oh, boy. How on earth compiler can know it is a dead code? I mean, really. What if I load that binary dynamically and call that function?
    Learn to declare local functions as “static”, then at least compiler will get an idea of what you mean.

    Comment by Vlad — July 1, 2011 @ 11:12 am

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: