diff --git a/repos/ports/src/virtualbox/libc.cc b/repos/ports/src/virtualbox/libc.cc index e75f8b954..0c9edb29a 100644 --- a/repos/ports/src/virtualbox/libc.cc +++ b/repos/ports/src/virtualbox/libc.cc @@ -28,6 +28,8 @@ #include "libc_errno.h" +/* Genode specific Vbox include */ +#include "vmm.h" /* libc memory allocator */ #include @@ -38,14 +40,46 @@ static const bool verbose = false; +/* + * We need an initial buffer currently, since the libc issues during + * initialization malloc (dup) calls to the one defined below. At this + * point we have not any env pointer. + * Additionally static constructors are executed currently before the libc + * is done with initialization and so we also have no Env pointer here. + */ +static char buffer[2048]; +static unsigned buffer_len = 0; + +static bool initial_memory(void * ptr) +{ + return buffer <= ptr && ptr < buffer + sizeof(buffer); +} + /* * We cannot use the libc's version of malloc because it does not satisfies * the alignment constraints asserted by 'Runtime/r3/alloc.cpp'. */ +static Libc::Mem_alloc_impl * memory() +{ + try { genode_env(); } catch (...) { return nullptr; } + + static Libc::Mem_alloc_impl mem( genode_env().rm(), genode_env().ram()); + return &mem; +} extern "C" void *malloc(::size_t size) { - return Libc::mem_alloc()->alloc(size, Genode::log2(RTMEM_ALIGNMENT)); + if (memory()) + return memory()->alloc(size, Genode::log2(RTMEM_ALIGNMENT)); + + void * ret = buffer + buffer_len; + buffer_len += (size + RTMEM_ALIGNMENT - 1) & ~(0ULL + RTMEM_ALIGNMENT - 1); + + if (buffer_len <= sizeof(buffer)) + return ret; + + struct Not_enough_initial_memory : Genode::Exception { }; + throw Not_enough_initial_memory(); } @@ -60,7 +94,8 @@ extern "C" void *calloc(::size_t nmemb, ::size_t size) extern "C" void free(void *ptr) { - Libc::mem_alloc()->free(ptr); + if (!initial_memory(ptr)) + memory()->free(ptr); } @@ -74,12 +109,16 @@ extern "C" void *realloc(void *ptr, ::size_t size) return 0; } - /* determine size of old block content (without header) */ - unsigned long old_size = Libc::mem_alloc()->size_at(ptr); + unsigned long old_size = size; - /* do not reallocate if new size is less than the current size */ - if (size <= old_size) - return ptr; + if (!initial_memory(ptr)) { + /* determine size of old block content (without header) */ + old_size = memory()->size_at(ptr); + + /* do not reallocate if new size is less than the current size */ + if (size <= old_size) + return ptr; + } /* allocate new block */ void *new_addr = malloc(size); diff --git a/repos/ports/src/virtualbox/sup.cc b/repos/ports/src/virtualbox/sup.cc index ddfa29800..3319252e8 100644 --- a/repos/ports/src/virtualbox/sup.cc +++ b/repos/ports/src/virtualbox/sup.cc @@ -25,9 +25,6 @@ #include #include -/* libc memory allocator */ -#include - struct Attached_gip : Genode::Attached_ram_dataspace { @@ -283,7 +280,13 @@ void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr) * PDMR3CritSectGetNop(). */ size_t const cbVM = RT_UOFFSETOF(VM, aCpus[cCpus]); - VM *pVM = (VM *)Libc::mem_alloc()->alloc(cbVM, Genode::log2(PAGE_SIZE)); + + static Genode::Attached_ram_dataspace vm(genode_env().ram(), + genode_env().rm(), + cbVM); + Assert (vm.size() >= cbVM); + + VM *pVM = vm.local_addr(); Genode::memset(pVM, 0, cbVM); /* diff --git a/repos/ports/src/virtualbox5/sup.cc b/repos/ports/src/virtualbox5/sup.cc index c046afb49..38e1a98fb 100644 --- a/repos/ports/src/virtualbox5/sup.cc +++ b/repos/ports/src/virtualbox5/sup.cc @@ -24,9 +24,6 @@ #include #include -/* libc memory allocator */ -#include - #include "vmm.h" enum { @@ -286,7 +283,13 @@ void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr) * PDMR3CritSectGetNop(). */ size_t const cbVM = RT_UOFFSETOF(VM, aCpus[cCpus]); - VM *pVM = (VM *)Libc::mem_alloc()->alloc(cbVM, Genode::log2(PAGE_SIZE)); + + static Genode::Attached_ram_dataspace vm(genode_env().ram(), + genode_env().rm(), + cbVM); + Assert (vm.size() >= cbVM); + + VM *pVM = vm.local_addr(); Genode::memset(pVM, 0, cbVM); /*