diff --git a/Libraries/CMakeLists.txt b/Libraries/CMakeLists.txt index 9bce4e6bbd..3954f99c43 100644 --- a/Libraries/CMakeLists.txt +++ b/Libraries/CMakeLists.txt @@ -2,7 +2,6 @@ add_subdirectory(LibAudio) add_subdirectory(LibC) add_subdirectory(LibCore) add_subdirectory(LibCrypto) -add_subdirectory(LibCxx) add_subdirectory(LibDebug) add_subdirectory(LibDesktop) add_subdirectory(LibGemini) diff --git a/Libraries/LibC/CMakeLists.txt b/Libraries/LibC/CMakeLists.txt index d5e94d1b96..d27a5b4719 100644 --- a/Libraries/LibC/CMakeLists.txt +++ b/Libraries/LibC/CMakeLists.txt @@ -3,7 +3,7 @@ set(LIBC_SOURCES assert.cpp crt0.cpp ctype.cpp - cxaatexit.cpp + cxxabi.cpp dirent.cpp dlfcn.cpp fcntl.cpp @@ -51,6 +51,8 @@ file(GLOB AK_SOURCES "../../AK/*.cpp") file(GLOB ELF_SOURCES "../LibELF/*.cpp") set(ELF_SOURCES ${ELF_SOURCES} ../LibELF/Arch/i386/plt_trampoline.S) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSERENITY_LIBC_BUILD") + add_library(crt0 STATIC crt0.cpp) add_custom_command( TARGET crt0 @@ -60,4 +62,4 @@ add_custom_command( set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES}) serenity_libc(LibC c) target_link_libraries(LibC crt0) -add_dependencies(LibC LibM LibCxx) +add_dependencies(LibC LibM) diff --git a/Libraries/LibC/cxaatexit.cpp b/Libraries/LibC/cxxabi.cpp similarity index 99% rename from Libraries/LibC/cxaatexit.cpp rename to Libraries/LibC/cxxabi.cpp index 1b59e1d32c..68c9e33f3e 100644 --- a/Libraries/LibC/cxaatexit.cpp +++ b/Libraries/LibC/cxxabi.cpp @@ -25,6 +25,7 @@ */ #include +#include #include #include diff --git a/Libraries/LibCxx/CMakeLists.txt b/Libraries/LibCxx/CMakeLists.txt deleted file mode 100644 index f9cec683bb..0000000000 --- a/Libraries/LibCxx/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(SOURCES - CxaGuard.cpp -) - -# Shhh don't worry gcc, we are totally libstdc++ -serenity_libc(LibCxx stdc++) -target_link_libraries(LibCxx LibC) diff --git a/Libraries/LibCxx/CxaGuard.cpp b/Libraries/LibCxx/CxaGuard.cpp deleted file mode 100644 index dc8b011a43..0000000000 --- a/Libraries/LibCxx/CxaGuard.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2020, Andrew Kaster - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -// Static variable guard logic, using futexes -// Written while looking at libc++ from a distance ;) This is super tricky... -// From itanium spec: Get passed a pointer to a 64 bit guard "object" -// [ 1 guard byte (checked by compiler), 7 bytes to work with ] -class CxaGuard { -public: - enum GuardState : uint8_t { - NotInitialized = 0, - DoneInit = 1, - InitInProgress = 2, - WaitingOnInit = 4 - }; - - CxaGuard(uint64_t* guard_pointer) - : m_full_guard_var(guard_pointer) - , m_compiler_guard_byte((uint8_t*)guard_pointer) - , m_local_state_byte(&((uint8_t*)guard_pointer)[1]) - { - } - - int acquire() - { - // Someone else already initailzied this by storing to the 'really done' slot - if (GuardState::NotInitialized != m_compiler_guard_byte.load(AK::memory_order_acquire)) - return 0; - - // Time to begin the waiting game.. - while (true) { - // Try to claim initialization for this thread from the initial state - uint8_t last_state = GuardState::NotInitialized; - if (m_local_state_byte.compare_exchange_strong(last_state, GuardState::InitInProgress, AK::memory_order_acq_rel)) - return 1; // Tell compiler-generated code to init the variable - - // Someone else set the state to done, we're done here - if (last_state == DoneInit) - return 0; - - // Someone else set InitInProgress, time to wait (maybe) - if (last_state & GuardState::InitInProgress) { - // Try to set the in progress + done bits - if ((last_state & GuardState::WaitingOnInit) == 0) { - if (!m_local_state_byte.compare_exchange_strong(last_state, (GuardState::InitInProgress | GuardState::WaitingOnInit), AK::memory_order_acq_rel)) { - if (last_state == GuardState::DoneInit) - return 0; - if (last_state == GuardState::NotInitialized) - continue; // start over, and try to initialize in this thread - // else wait, someone else set the wait bit before us - } - } - // State is InitInProgress | WaitingOnInit, time to sleep - wait_on_futex(); - } - } - } - - void release() - { - // Store the value the compiler will look at, we're done! yay - m_compiler_guard_byte.store(GuardState::DoneInit, AK::memory_order_release); - - // Set the value other threads chilling in our loop will look at to done - uint8_t old_local_state = m_local_state_byte.exchange(GuardState::DoneInit, AK::memory_order_acq_rel); - - // Wake up sleepy heads, the variable is initialized! - if (old_local_state & GuardState::WaitingOnInit) - wake_futex(); - } - - void abort() - { - uint8_t old_local_state = m_local_state_byte.exchange(GuardState::NotInitialized, AK::memory_order_acq_rel); - - // Wake up sleepy heads, someone else gets to try... - if (old_local_state & GuardState::WaitingOnInit) - wake_futex(); - } - -private: - void wait_on_futex() - { - int futex_value = (GuardState::InitInProgress | GuardState::WaitingOnInit) << 8; - futex((int32_t*)m_full_guard_var, FUTEX_WAIT, futex_value, nullptr); - } - - void wake_futex() - { - futex((int32_t*)m_full_guard_var, FUTEX_WAKE, INT32_MAX, nullptr); - } - - void* m_full_guard_var; - AtomicRef m_compiler_guard_byte; - AtomicRef m_local_state_byte; // we'll load and set this atomically - - // Note that we're not using 6/8 bytes of the guard object... -}; - -extern "C" { - -int __cxa_guard_acquire(uint64_t* guard_object) -{ - CxaGuard g(guard_object); - return g.acquire(); -} - -void __cxa_guard_release(uint64_t* guard_object) -{ - CxaGuard g(guard_object); - g.release(); -} - -void __cxa_guard_abort(uint64_t* guard_object) -{ - CxaGuard g(guard_object); - g.abort(); -} - -} // extern "C" diff --git a/Toolchain/BuildIt.sh b/Toolchain/BuildIt.sh index b50ed23f22..ab499897c4 100755 --- a/Toolchain/BuildIt.sh +++ b/Toolchain/BuildIt.sh @@ -230,7 +230,7 @@ pushd "$DIR/Build/" pushd "$BUILD" cmake .. "$MAKE" LibC - install -D Libraries/LibC/libc.a Libraries/LibM/libm.a Libraries/LibCxx/libstdc++.a Root/usr/lib/ + install -D Libraries/LibC/libc.a Libraries/LibM/libm.a Root/usr/lib/ SRC_ROOT=$(realpath "$DIR"/..) for header in "$SRC_ROOT"/Libraries/Lib{C,M}/**/*.h; do target=$(echo "$header" | sed -e "s@$SRC_ROOT/Libraries/LibC@@" -e "s@$SRC_ROOT/Libraries/LibM@@") @@ -239,6 +239,11 @@ pushd "$DIR/Build/" unset SRC_ROOT popd + echo "XXX build libstdc++" + "$MAKE" all-target-libstdc++-v3 || exit 1 + echo "XXX install libstdc++" + "$MAKE" install-target-libstdc++-v3 || exit 1 + if [ "$(uname -s)" = "OpenBSD" ]; then cd "$DIR/Local/libexec/gcc/i686-pc-serenity/$GCC_VERSION" && ln -sf liblto_plugin.so.0.0 liblto_plugin.so fi