mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-01 04:36:13 +00:00
When rebasing my local branch on top of sculpt-21.10 tag I've noticed two problems. The code in new_delete.cc does not include new header file. This works fine with GCC, but fails with clang because std::align_val_t type is not defined anywhere according to clang. It looks like GCC pulls this header indirectly somehow. The second problem can be seen if one disallows undefined symbols in executables and shared_libraries. This can be seen with both GCC and clang by adding --no-undefined to LD_OPT. With such change in place core fails to link due to: ld.lld: error: undefined symbol: operator delete(void*, std::align_val_t) >>> referenced by thread.h:448 (/home/tworaz/devel/genode/repos/base-hw/src/core/kernel/thread.h:448) >>> thread.o:(Kernel::Core_main_thread::~Core_main_thread()) in archive debug/core-hw-virt_qemu.a >>> referenced by thread.h:448 (/home/tworaz/devel/genode/repos/base-hw/src/core/kernel/thread.h:448) >>> thread.o:(non-virtual thunk to Kernel::Core_main_thread::~Core_main_thread()) in archive debug/core-hw-virt_qemu.a >>> did you mean: operator delete(void*, unsigned long, std::align_val_t) >>> defined in: debug/core-hw-virt_qemu.a(supc++.o) If the code would somehow manage call such undefined symbol it'd crash. Since I generally prefer link time failures to runtime crashes I link all genode binaries with --no-undefined. To fix this problem just add a dummy implementation of missing delete operator. Fixes #4298
99 lines
3.2 KiB
C++
99 lines
3.2 KiB
C++
/*
|
|
* \brief New and delete are special
|
|
* \author Norman Feske
|
|
* \date 2006-04-07
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2017 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/log.h>
|
|
#include <base/allocator.h>
|
|
#include <base/sleep.h>
|
|
|
|
/* C++ runtime includes */
|
|
#include <new>
|
|
|
|
using Genode::size_t;
|
|
using Genode::Allocator;
|
|
using Genode::Deallocator;
|
|
using Genode::sleep_forever;
|
|
|
|
|
|
static void *try_alloc(Allocator *alloc, size_t size)
|
|
{
|
|
if (!alloc)
|
|
throw Allocator::Out_of_memory();
|
|
|
|
return alloc->alloc(size);
|
|
}
|
|
|
|
|
|
void *operator new (__SIZE_TYPE__ s, Allocator *a) { return try_alloc(a, s); }
|
|
void *operator new [] (__SIZE_TYPE__ s, Allocator *a) { return try_alloc(a, s); }
|
|
void *operator new (__SIZE_TYPE__ s, Allocator &a) { return a.alloc(s); }
|
|
void *operator new [] (__SIZE_TYPE__ s, Allocator &a) { return a.alloc(s); }
|
|
|
|
|
|
static void try_dealloc(void *ptr, Deallocator &dealloc)
|
|
{
|
|
/*
|
|
* Log error and block on the attempt to use an allocator that relies on
|
|
* the size argument.
|
|
*/
|
|
if (dealloc.need_size_for_free()) {
|
|
Genode::error("C++ runtime: delete called with allocator, which needs "
|
|
"'size' on free. Blocking before leaking memory...");
|
|
sleep_forever();
|
|
}
|
|
|
|
/* size not required, so call with dummy size */
|
|
dealloc.free(ptr, 0);
|
|
}
|
|
|
|
|
|
void operator delete (void *ptr, Deallocator *dealloc) { try_dealloc(ptr, *dealloc); }
|
|
void operator delete (void *ptr, Deallocator &dealloc) { try_dealloc(ptr, dealloc); }
|
|
|
|
|
|
/*
|
|
* The 'delete (void *)' operator gets referenced by compiler generated code,
|
|
* so it must be publicly defined in the 'cxx' library. These compiler
|
|
* generated calls seem to get executed only subsequently to explicit
|
|
* 'delete (void *)' calls in application code, which are not supported by the
|
|
* 'cxx' library, so the 'delete (void *)' implementation in the 'cxx' library
|
|
* does not have to do anything. Applications should use the 'delete (void *)'
|
|
* implementation of the 'stdcxx' library instead. To make this possible, the
|
|
* 'delete (void *)' implementation in the 'cxx' library must be 'weak'.
|
|
*/
|
|
__attribute__((weak)) void operator delete (void *) noexcept
|
|
{
|
|
Genode::error("cxx: operator delete (void *) called - not implemented. "
|
|
"A working implementation is available in the 'stdcxx' library.");
|
|
}
|
|
|
|
|
|
__attribute__((weak)) void operator delete (void *, unsigned long)
|
|
{
|
|
Genode::error("cxx: operator delete (void *, unsigned long) called - not implemented. "
|
|
"A working implementation is available in the 'stdcxx' library.");
|
|
}
|
|
|
|
|
|
__attribute__((weak)) void operator delete (void *, unsigned long, std::align_val_t)
|
|
{
|
|
Genode::error("cxx: operator delete (void *, unsigned long, std::align_val_t) called - not implemented. "
|
|
"A working implementation is available in the 'stdcxx' library.");
|
|
}
|
|
|
|
__attribute__((weak)) void operator delete (void *, std::align_val_t) noexcept
|
|
{
|
|
Genode::error("cxx: operator delete (void *, std::align_val_t) called - not implemented. "
|
|
"A working implementation is available in the 'stdcxx' library.");
|
|
}
|