Is it somehow possible to discard a function/symbol from an output file (.exe/.elf) even if it could be called?
Let's say, a third party library does something like this:
int lib_func_get(int c) {
if (c < 5) {
return foo();
} else {
return bar()
}
}
And you know for sure, c is never < 5, then I would like to omit/remove foo() from my executable to reduce the binary size.
How can I do this? Maybe with the help of the linker script and discarding .text.foo?
GCC's linker has a similar section for this, /DISCARD/, but the linking fails because the function is used:
refers [symbol], which is defined in a discarded section
The background of my question is reducing the binary size of embedded applications, especially bootloaders, where you cannot recompile a third party library or the library is part of the toolchain (libgcc e.g.) and you don't want to modify and rebuild the whole toolchain.
I know, this is may be a hacky approach but I would like to do this.
CodePudding user response:
In cases where the issue is local the best approach would be to provide a compiler hint:
#define ASSUME(cond) do { \
if (!(cond)) \
__builtin_unreachable(); \
} while (0)
int lib_func_get(int c) {
ASSUME(c >= 5);
if (c < 5) {
return foo();
} else {
return bar()
}
}
This would drop both function definition and surrounding code.
Otherwise you can override the symbol at link time:
$ gcc tmp.c -Wl,--defsym=printf=0
$ objdump -d tmp.c | grep printf
113d: e8 be ee ff ff callq 0 <printf>
CodePudding user response:
Is it somehow possible to discard a function/symbol from an output file (.exe/.elf) even if it could be called?
No.
you know for sure, c is never < 5, then I would like to omit/remove foo() ... How can I do this?
So refactor the code and remove the call to foo()
.
Mark the symbol as weak and replace it with an implementation that calls abort, or if you are really brave, just returns. Similarly, you can use --wrap
. For example:
objcopy --weak-symbols=foo the_lib_with_foo.o the_lib_with_weak_foo.o
echo 'void foo() { return; }' | gcc -xc - -o foo.o
gcc foo.o the_lib_with_weak_foo.o -o the_exe.out