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
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
….
080483e9
….
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.
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
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