I am trying to run application which have libc component and my own golang part. I use nova kernel on x86_64 version.
I found that during the process of linker initialization of components I have uninitiated variable:
#0 Genode::Stack::size (this=0x401fef28, size=0x40000) at /media/psf/Home/gen/20.05/repos/base/src/lib/base/thread.cc:34 #1 0x00000000000fb094 in Linker::Binary::call_entry_point (env=..., this=0x15e010 <unmanaged_singleton<Linker::Binary, 8, Genode::Env&, Genode::Heap&, Linker::Config const&, char const*>(Genode::Env&, Genode::Heap&, Linker::Config const&, char const*&&)::object_space>) at /media/psf/Home/gen/20.05/repos/base/src/lib/ldso/main.cc:436 #2 Component::construct (env=...) at /media/psf/Home/gen/20.05/repos/base/src/lib/ldso/main.cc:825 #3 0x000000000007cf7f in (anonymous namespace)::Constructor_component::construct (this=0x400fec10) at /media/psf/Home/gen/20.05/repos/base/src/lib/base/entrypoint.cc:319 #4 Genode::Meta::call_member<Genode::Meta::Empty, (anonymous namespace)::Constructor_component, Genode::Meta::Empty> (func=<optimized out>, server=...) at /media/psf/Home/gen/20.05/repos/base/include/util/meta.h:464 #5 (anonymous namespace)::Constructor::Rpc_construct::serve<(anonymous namespace)::Constructor_component, Genode::Meta::Empty> (args=<synthetic pointer>..., server=...) at /media/psf/Home/gen/20.05/repos/base/src/lib/base/entrypoint.cc:293 #6 Genode::Rpc_dispatcher<(anonymous namespace)::Constructor, (anonymous namespace)::Constructor_component>::_do_serve<(anonymous namespace)::Constructor::Rpc_construct> (args=<synthetic pointer>..., this=0x400fec98) at /media/psf/Home/gen/20.05/repos/base/include/base/rpc_server.h:146 #7 Genode::Rpc_dispatcher<(anonymous namespace)::Constructor, (anonymous namespace)::Constructor_component>::_do_dispatch<Genode::Meta::Type_list<(anonymous namespace)::Constructor::Rpc_construct> > (in=..., out=..., opcode=..., this=0x400fec98) at /media/psf/Home/gen/20.05/repos/base/include/base/rpc_server.h:180 #8 Genode::Rpc_dispatcher<(anonymous namespace)::Constructor, (anonymous namespace)::Constructor_component>::dispatch (in=..., out=..., opcode=..., this=0x400fec98) at /media/psf/Home/gen/20.05/repos/base/include/base/rpc_server.h:235 #9 Genode::Rpc_object<(anonymous namespace)::Constructor, (anonymous namespace)::Constructor_component>::dispatch (this=0x400fec10, opcode=..., in=..., out=...) at /media/psf/Home/gen/20.05/repos/base/include/base/rpc_server.h:272 #10 0x000000000009d08d in Genode::Rpc_entrypoint::<lambda(Genode::Rpc_object_base*)>::operator() (obj=0x400fec10, __closure=<synthetic pointer>) at /media/psf/Home/gen/20.05/repos/base-nova/src/lib/base/rpc_entrypoint.cc:177 #11 Genode::Object_poolGenode::Rpc_object_base::apply<Genode::Rpc_entrypoint::_activation_entry()::<lambda(Genode::Rpc_object_base*)> > (func=..., capid=<optimized out>, this=0x12e4b0 Genode::bootstrap_component()::startup+528) at /media/psf/Home/gen/20.05/repos/base/include/base/object_pool.h:147 #12 Genode::Rpc_entrypoint::_activation_entry () at /media/psf/Home/gen/20.05/repos/base-nova/src/lib/base/rpc_entrypoint.cc:180 #13 0x0000000000000000 in ?? ()
code #1 contains the following: void call_entry_point(Env &env) { /* apply the component-provided stack size */ if (Elf::Addr addr = lookup_symbol("_ZN9Component10stack_sizeEv")) {
/* call 'Component::stack_size()' */ size_t const stack_size = ((size_t(*)())addr)();
/* expand stack according to the component's needs */ Thread::myself()->stack_size(stack_size); } … it found _ZN9Component10stack_sizeEv function for libc and then call the following function #0 from base/src/lib/base/thread.cc:
void Stack::size(size_t const size) { /* check if the stack needs to be enhanced */ size_t const stack_size = (addr_t)_stack - _base; if (stack_size >= size) { return; }
/* check if the stack enhancement fits the stack region */ enum { UTCB_SIZE = sizeof(Native_utcb), PAGE_SIZE_LOG2 = 12, PAGE_SIZE = (1UL << PAGE_SIZE_LOG2), }; addr_t const stack_slot_base = Stack_allocator::addr_to_base(this); size_t const ds_size = align_addr(size - stack_size, PAGE_SIZE_LOG2); if (_base - ds_size < stack_slot_base) throw Thread::Stack_too_large();
/* allocate and attach backing store for the stack enhancement */ addr_t const ds_addr = _base - ds_size - stack_area_virtual_base(); try { Ram_allocator * const ram = env_stack_area_ram_allocator; Ram_dataspace_capability const ds_cap = ram->alloc(ds_size); … here I found that env_stack_area_ram_allocator is null, not initialized!
in core base/src/core/stack_area.cc I found part which probably should be called before previous code: void Genode::init_stack_area() { static Stack_area_region_map rm; env_stack_area_region_map = &rm;
static Stack_area_ram_allocator ram; env_stack_area_ram_allocator = &ram; }
seems that this initializer should be called before libc component initializer (it belong to different component)?
Nesessary initialization probably happens in class constructor of class Genode::Core_env : public Env_deprecated, Noncopyable base/src/core/include/core_env.h
seems that something wrong in link sequence.
Question: ======== how I can fix the order of different component initialization? I probably need class Genode::Core_ to be initialized first as a part of general code of core-nova.o. may be I missed something like crt*.o in link? crt0.o definitely present in $libs/startup-nova/startup-nova.lib.a…
on previous version I found some magical sequence which works after some manipulations with link order, but now with 20.05 it is not working any more for me.
Some info about my code:
in my code dummy.cc I have function (C style) main and component constructor void Libc::Component::construct(Libc::Env &env) { // Genode::Heap heap(env.ram(), env.rm()); // _verbose = false; static int c = 1; static char * myname = "GolangApp"; int r = 0; Libc::with_libc([&r] () { r = main(c, &myname); }); env.parent().exit(r); }
my current link command line: libs=/media/psf/Home/gen/20.05/build/x86_64/var/libcache; genode-x86-gcc -B /media/psf/Home/gen/20.05/build/x86_64/../tool_chain-19.05/x86/gcc/gcc/ -Wl,-melf_x86_64 -Wl,-gc-sections -Wl,-z -Wl,max-page-size=0x1000 -Wl,--dynamic-list=/media/psf/Home/gen/20.05/repos/base/src/ld/genode_dyn.dl -nostdlib -Wl,-nostdlib -Wl,-Ttext=0x01000000 -m64 -mcmodel=large -Wl,--dynamic-linker=ld.lib.so -Wl,--eh-frame-hdr -Wl,-rpath-link=. -Wl,-T -Wl,/media/psf/Home/gen/20.05/repos/base/src/ld/genode_dyn.ld -Wl,--whole-archive -Wl,--start-group dummy.o main.o myacontext.o mycontext.o $libs/base-nova-common/base-nova-common.lib.a $libs/base-nova/base-nova.lib.a $libs/startup-nova/startup-nova.lib.a $libs/timeout/timeout.lib.a ld.lib.so libc.lib.so libm.lib.so vfs.lib.so -Wl,--no-whole-archive -Wl,--end-group /media/psf/Home/gen/20.05/build/x86_64/var/libcache/libc-gen/libc-gen.lib.a /media/psf/Home/gen/20.05/build/x86_64/var/libcache/libgo/libgobegin.a /media/psf/Home/gen/20.05/build/x86_64/var/libcache/libgo/libgolibbegin.a /media/psf/Home/gen/20.05/build/x86_64/var/libcache/libgo/libgo.a /media/psf/Home/gen/20.05/build/x86_64/var/libcache/libc-stdlib/libc-stdlib.lib.a /media/psf/Home/gen/20.05/build/x86_64/var/libcache/cxx/cxx.lib.a /media/psf/Home/gen/20.05/build/x86_64/../tool_chain-19.05/x86/gcc/x86_64-pc-elf/64/libgcc/libgcc_eh.a /media/psf/Home/gen/20.05/build/x86_64/../tool_chain-19.05/x86/gcc/x86_64-pc-elf/64/libgcc/libgcc.a
Thanks!