mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-20 22:23:16 +00:00
lx_emul: generate initcalls during build
Functions registered with 'module_init' (i.e., '__define_initcalls'), 'OF_DECLARE', and 'DECLARE_PCI_FIXUP_CLASS_FINAL' used to be static constructors and had be explicitly registered using 'exec_static_constructors' before executing any Linux code. With this commit we remove the constructor attributes from these functions and create a global function pointer in the form of __initptr_<name>_<id>_<counter>_<line number of macro> 'import-lx_emul_common.inc' will collect these '__initptr' symbols after the compile step and generate a 'lx_emul_register_initcalls' function that executes the functions pointed to. This step is now automatically performed in 'lx_emul_start_kernel'. This way a call to 'exec_static_constructors' can be omitted in case there are no other constructors in place. issue #5096
This commit is contained in:
parent
f9bff3bc7c
commit
1b4f7ae0d3
@ -211,3 +211,57 @@ GLOBAL_DEPS += $(wildcard $(addsuffix /linux/*.h,$(SHADOW_INC_DIR))) \
|
||||
GLOBAL_DEPS += $(wildcard $(addsuffix /linux/*.h,$(SPEC_SHADOW_INC_DIR))) \
|
||||
$(wildcard $(addsuffix /asm/*.h,$(SPEC_SHADOW_INC_DIR)))
|
||||
|
||||
|
||||
#
|
||||
# Generate initcall_table.c and create 'lx_emul_register_initcalls' which calls
|
||||
# global '__initptr_*' functions created by 'module_init'
|
||||
#
|
||||
|
||||
define print_file_header
|
||||
echo "/*" > $(2);
|
||||
echo " * \\brief Register initcalls from __initptr_*" >> $(2);
|
||||
echo " * \\author Automatically generated file - do no edit" >> $(2);
|
||||
echo " * \\date $(1)" >> $(2);
|
||||
echo " */" >> $(2);
|
||||
echo "" >> $(2);
|
||||
echo "" >> $(2);
|
||||
endef
|
||||
|
||||
define print_declaration
|
||||
echo "extern void * $(1);" >> $(2);
|
||||
endef
|
||||
|
||||
define print_function_start
|
||||
echo "" >> $(1)
|
||||
echo "void lx_emul_register_initcalls(void)" >> $(1);
|
||||
echo "{" >> $(1);
|
||||
echo " typedef void (*func)(void);" >> $(1);
|
||||
endef
|
||||
|
||||
define print_call
|
||||
echo " ((func)$(1))();" >> $(2);
|
||||
endef
|
||||
|
||||
define print_function_end
|
||||
echo "}" >> $(1);
|
||||
endef
|
||||
|
||||
|
||||
# 'module_init' calls should only be in C-sources
|
||||
WAIT_FOR_OBJECTS = $(addsuffix .o,$(basename $(filter-out initcall_table.c,$(SRC_C))))
|
||||
|
||||
# retrieve 'initptr_*' using nm from object files
|
||||
INITCALLS = $(sort $(shell $(NM) -U $(WAIT_FOR_OBJECTS) |\
|
||||
grep "__initptr" |\
|
||||
awk '{print $$3}'))
|
||||
|
||||
SRC_C += initcall_table.c
|
||||
|
||||
initcall_table.c: $(WAIT_FOR_OBJECTS)
|
||||
$(MSG_CONFIG)$@
|
||||
@$(call print_file_header,$(shell date +"%F"),$@)
|
||||
@$(foreach sym,$(INITCALLS),$(call print_declaration,$(sym),$@))
|
||||
@$(call print_function_start,$@)
|
||||
@$(foreach sym,$(INITCALLS),$(call print_call,$(sym),$@))
|
||||
@$(call print_function_end,$@)
|
||||
|
||||
|
@ -20,6 +20,9 @@ extern "C" {
|
||||
|
||||
void lx_emul_initcalls(void);
|
||||
|
||||
/* this function is generated into 'initcall_table.c' */
|
||||
void lx_emul_register_initcalls(void);
|
||||
|
||||
void lx_emul_register_initcall(int (*initcall)(void), const char * name);
|
||||
|
||||
void lx_emul_start_kernel(void * dtb);
|
||||
|
@ -27,9 +27,16 @@
|
||||
#undef ___define_initcall
|
||||
#undef __define_initcall
|
||||
|
||||
#define __define_initcall(fn, id) \
|
||||
static void __initcall_##fn##id(void)__attribute__((constructor)); \
|
||||
static void __initcall_##fn##id() { \
|
||||
lx_emul_register_initcall(fn, __func__); };
|
||||
/*
|
||||
* Define local register function and global pointer to function in the form
|
||||
* '__initptr_<function name>_<id>_<counter>_<line number of macro>'
|
||||
*/
|
||||
#define __define_initcall(fn, id) \
|
||||
static void __initcall_##fn##id(void) { \
|
||||
lx_emul_register_initcall(fn, __func__); } \
|
||||
\
|
||||
void * __PASTE(__initptr_##fn##id##_, \
|
||||
__PASTE(__COUNTER__, \
|
||||
__PASTE(_,__LINE__))) = __initcall_##fn##id;
|
||||
|
||||
#endif /* _LX_EMUL__SHADOW__LINUX__INIT_H_ */
|
||||
|
@ -21,15 +21,19 @@
|
||||
#undef OF_DECLARE_2
|
||||
|
||||
/* used to populate __clk_of_table */
|
||||
#define OF_DECLARE_1(table, name, compat, fn) \
|
||||
static void __of_declare_initcall_##name(void) __attribute__((constructor)); \
|
||||
static void __of_declare_initcall_##name() { \
|
||||
lx_emul_register_of_##table##_initcall(compat, fn); };
|
||||
#define OF_DECLARE_1(table, name, compat, fn) \
|
||||
static void __of_declare_initcall_##name(void) { \
|
||||
lx_emul_register_of_##table##_initcall(compat, fn); }; \
|
||||
void * __PASTE(__initptr_of_declare_initcall_##name##_, \
|
||||
__PASTE(__COUNTER__, \
|
||||
__PASTE(_, __LINE__))) = __of_declare_initcall_##name;
|
||||
|
||||
/* used to populate __irqchip_of_table */
|
||||
#define OF_DECLARE_2(table, name, compat, fn) \
|
||||
static void __of_declare_initcall_##name(void) __attribute__((constructor)); \
|
||||
static void __of_declare_initcall_##name() { \
|
||||
lx_emul_register_of_##table##_initcall(compat, fn); };
|
||||
#define OF_DECLARE_2(table, name, compat, fn) \
|
||||
static void __of_declare_initcall_##name(void) { \
|
||||
lx_emul_register_of_##table##_initcall(compat, fn); }; \
|
||||
void * __PASTE(__initptr_of_declare_initcall_##name##_, \
|
||||
__PASTE(__COUNTER__, \
|
||||
__PASTE(_, __LINE__))) = __of_declare_initcall_##name;
|
||||
|
||||
#endif /* _LX_EMUL__SHADOW__LINUX__OF_H_ */
|
||||
|
@ -14,9 +14,13 @@
|
||||
#undef DECLARE_PCI_FIXUP_CLASS_FINAL
|
||||
|
||||
#define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \
|
||||
class_shift, hook) \
|
||||
static void __pci_fixup_final_##hook(struct pci_dev *dev) __attribute__((constructor)); \
|
||||
static void __pci_fixup_final_##hook(struct pci_dev *dev) { \
|
||||
lx_emul_register_pci_fixup(hook, __func__); };
|
||||
class_shift, hook) \
|
||||
static void __pci_fixup_final_##hook(struct pci_dev *dev) { \
|
||||
lx_emul_register_pci_fixup(hook, __func__); }; \
|
||||
void * __PASTE(__initptr_pci_fixup_final_##hook##_, \
|
||||
__PASTE(__COUNTER__, \
|
||||
__PASTE(_, __LINE__))) = __pci_fixup_final_##hook;
|
||||
|
||||
|
||||
|
||||
#endif /* _LINUX__PCI_H_ */
|
||||
|
@ -52,6 +52,9 @@ extern "C" void lx_emul_start_kernel(void * dtb)
|
||||
{
|
||||
using namespace Lx_kit;
|
||||
|
||||
/* register 'module_init' calls and friends */
|
||||
lx_emul_register_initcalls();
|
||||
|
||||
new (env().heap) Task(lx_emul_init_task_function, dtb,
|
||||
lx_emul_init_task_struct, SWAPPER_PID, "swapper",
|
||||
env().scheduler, Task::TIME_HANDLER);
|
||||
|
@ -44,7 +44,7 @@ SRC_C += lx_emul/shadow/drivers/pci/search.c
|
||||
SRC_C += lx_emul/shadow/drivers/pci/setup-irq.c
|
||||
SRC_C += lx_emul/shadow/drivers/pci/setup-res.c
|
||||
SRC_CC += lx_emul/pci.cc
|
||||
SRC_CC += lx_emul/pci_bus.c
|
||||
SRC_C += lx_emul/pci_bus.c
|
||||
SRC_CC += lx_kit/device.cc
|
||||
SRC_CC += lx_kit/memory_dma.cc
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user