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.
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
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
Fantástico!
Fantastic!
Thanks!
Comment by Rodrigo Matos Palheta — December 15, 2010 @ 9:40 pm
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