components sequence and libc
Alexander Tormasov
a.tormasov at innopolis.ru
Sun Jul 5 01:07:55 CEST 2020
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_pool<Genode::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!
More information about the users
mailing list