I would like to detect unused functions in my code by using the combination of -ffunctions-sections
compiler options, and the --gc-sections,--print-gc-sections
However, it shows false positive. Here is a simple reproducer :
mylib.c :
int plusone(int a)
{
return a + 1;
}
int myadd(int a, int b)
{
int c = plusone(a);
return c -1 +b;
}
main.c
#include <stdio.h>
#include "mylib.h"
int main(int argc, char*argv[])
{
int a = 1;
int b=3;
printf("%d\n", myadd(a,b));
return 0;
}
Compiling and linking script :
#!/bin/sh
gcc -c -o main.o -O2 -ffunction-sections -fdata-sections main.c
gcc -c -o mylib.o -O2 -ffunction-sections -fdata-sections mylib.c
gcc -o test -Wl,--gc-sections,--print-gc-sections main.o mylib.o
And here is the output :
/usr/bin/ld: removing unused section '.rodata.cst4' in file '/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o'
/usr/bin/ld: removing unused section '.data' in file '/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o'
/usr/bin/ld: removing unused section '.text.plusone' in file 'mylib.o'
From the code of mylib.c, we can see that the plusone function is NOT unused, yet the --print-gc-sections message tells the opposite.
How does it work ? Is GCC inlining the function when used inside mylib.c, AND keeping a non inlined copy if it is called outside of mylib.c ?
How to make this technique more useful for the goal of detecting unused code ?