On Wed, Jan 09, 2013 at 10:13:51AM +0100, Franck Jullien wrote: > 2013/1/9 Sascha Hauer <[email protected]>: > > On Wed, Jan 09, 2013 at 10:02:32AM +0100, Franck Jullien wrote: > >> Hi, > >> > >> I have a question not directly related to Barebox but I think I can > >> find some answer here: ) > >> > >> I would like to use initcalls in a Linux user's land program on a x86 > >> target. > >> > >> I'm doing something like this: > >> > >> #ifndef _INIT_H > >> #define _INIT_H > >> > >> typedef int (*initcall_t)(void); > >> > >> extern initcall_t __start_target, __stop_target; > >> > >> #define target_initcall(fn) static initcall_t _##fn \ > >> __attribute__((used)) \ > >> __attribute__ ((section("target"))) = fn > >> > >> #endif > >> > >> then: > >> > >> initcall_t *initcall; > >> > >> for (initcall = &__start_target; > >> initcall < &__stop_target; initcall++) { > >> printf("initcall-> %p\n", *initcall); > >> ret = (*initcall)(); > >> if (ret) > >> printf("initcall %p failed: %d\n", *initcall, ret); > >> } > >> > >> Everything looks fine except the linker removes the function > >> "initcalled" because it is not > >> referenced anywhere and this is normal. > >> > >> I have not modified the linker script (I'm using the default one). I'm > >> using auto generated > >> __start_target and __stop_target symbols generated by the linker. > >> > >> My question is: why does it work in barebox ? For example, in > >> nios2/generic.c we have only > >> static function and initcalls. So why the linker does optimize out > >> those functions ? Is it > >> because we have initcall corresponding sections in the linker script ? > > > > Yes. In nios2 this is: > > > > __barebox_initcalls_start = .; > > .barebox_initcalls : { INITCALLS } > > __barebox_initcalls_end = .; > > > > With INITCALLS being defined as: > > > > #define INITCALLS \ > > KEEP(*(.initcall.0)) \ > > KEEP(*(.initcall.1)) \ > > KEEP(*(.initcall.2)) \ > > KEEP(*(.initcall.3)) \ > > KEEP(*(.initcall.4)) \ > > KEEP(*(.initcall.5)) \ > > KEEP(*(.initcall.6)) \ > > KEEP(*(.initcall.7)) \ > > KEEP(*(.initcall.8)) \ > > KEEP(*(.initcall.9)) \ > > KEEP(*(.initcall.10)) \ > > KEEP(*(.initcall.11)) > > > > The 'KEEP' keyword keeps the linker from throwing away these. > > > > Sascha > > > > -- > > Pengutronix e.K. | | > > Industrial Linux Solutions | http://www.pengutronix.de/ | > > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > > Thanks Sascha, I missed this one..... > > So is there no way I can do what I want without modification to the > default linker script. > I searched for a gcc attibute equivalent to KEEP but it doesn't seems to > exist.
No, and this wouldn't be enough anyway. You also have to tell the linker that it shall put all functions matching .initcall.* in a separate section. Otherwise they would end up in the regular sections. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list [email protected] http://lists.infradead.org/mailman/listinfo/barebox
