Page 1 of 1
Init calls and unused symbol removal
Posted: Thu Aug 08, 2013 3:10 pm
by JacobL
I have been trying to implement my own version of the Linux init call tables (__define_initcall in linux/init.h + associated sections in the linker script). It works fine with the default parameters to ld, but if I add --gc-sections in order to cleanup unreferenced symbols, these init function symbols also get removed. Which of course makes sense, since the symbols would not be directly referenced, only indirectly via variables from the linker script that marks the array borders.
My goal is to be able to register initialization functions in a decentralized manner in order to get a sharper separation between code modules.
I looked into the EXTERN declaration in the linker script, but from what I can tell, it can only be used on symbols, not sections. Is there a way to exclude entire input sections from being removed via --gc-sections?
Alternatively, is it possible to set something in the __define_initcall() macro that would cause the symbol it defines to be excluded from being removed?
I can of course set up a table somewhere that references these symbols, but that defeats the entire purpose of this exercise.
Re: Init calls and unused symbol removal
Posted: Fri Aug 09, 2013 5:15 am
by sortie
You could use a global variable with a constructor that registers the system call, or if you use C, you can use the GCC C extension that uses the same mechanism:
Code: Select all
__attribute__ ((constructor)) void initialize_foo_system_calls(void)
{
syscall_table[FOO] = sys_foo;
}
Though, you'll need to calls the constructors by calling the _init function during early boot as described in
Calling_Global_Constructors. I'm not sure how fitting this mechanism is for you, but it allows to you decentralized run code in modules.
Re: Init calls and unused symbol removal
Posted: Fri Aug 09, 2013 5:42 am
by pcmattman
The 'used' attribute is probably more useful:
Re: Init calls and unused symbol removal
Posted: Fri Aug 09, 2013 10:11 am
by JacobL
sortie:
The constructor concept is basically what I want to accomplish, without using C++. So it looks like this might be the way to go. I will give it a try in the weekend.
pcmattman:
I am already using the 'used' attribute, as the functions are declared as statics, and the compiler would warn + remove the code without it. But I cannot make it have any effect on which symbols are removed by --gc-sections in the linker.
Re: Init calls and unused symbol removal
Posted: Sat Aug 10, 2013 1:32 am
by Combuster
JacobL wrote:(...) as the functions are declared as statics (...)
Static means inaccessible from anything outside the same source file. That's not what you want, now is it?
Re: Init calls and unused symbol removal
Posted: Sat Aug 10, 2013 2:52 am
by Kevin
Inaccessible as in not making the name visible externally, but still accessible through pointers. This is probably what he wants.
Anyway, are the __attribute__((used)) on the functions or on the function pointers in the array? As you refer to the functions being static, it sounds like the former, but I think it should actually be the latter.
Re: Init calls and unused symbol removal
Posted: Sat Aug 10, 2013 3:06 am
by Combuster
Given that the compiler needs to be explicitly told not to remove a static function already implies there's no reference to it at all - including any of the expected nonstatic pointers.
Re: Init calls and unused symbol removal
Posted: Sat Aug 10, 2013 6:10 am
by JacobL
Thanks, I got it working. Turns out that all I needed was to add KEEP() around the sections containing the function pointers in my linker script. The example in
http://wiki.osdev.org/Calling_Global_Constructors showed this part.