From bbedd320b5d0bc75bb736ce12711ae283fbe2a77 Mon Sep 17 00:00:00 2001 From: Itamar Date: Sun, 20 Dec 2020 22:32:10 +0200 Subject: [PATCH] Toolchain+LibC: Fix usage of crt files We now configure the gcc spec files to use a different crt files for static & PIE binaries. This relieves us from the need to explicitly specify the desired crt0 file in cmake scripts. --- CMakeLists.txt | 4 ++-- Demos/DynamicObject/CMakeLists.txt | 1 - Libraries/LibC/CMakeLists.txt | 6 +++++- Libraries/LibELF/DynamicLoader.cpp | 31 +++++++++++++++++++++------- Meta/CMake/utils.cmake | 4 +--- Toolchain/Patches/gcc.patch | 2 +- Userland/CMakeLists.txt | 2 -- Userland/Tests/Kernel/CMakeLists.txt | 1 - Userland/Tests/LibC/CMakeLists.txt | 1 - 9 files changed, 32 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c83aed1948..180f1639d35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,8 +113,8 @@ add_compile_options(-ffile-prefix-map=${CMAKE_SOURCE_DIR}=.) add_compile_definitions(DEBUG SANITIZE_PTRS) set(CMAKE_CXX_FLAGS_STATIC "${CMAKE_CXX_FLAGS} -static") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostartfiles -pie -fpic") - +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pie -fpic") + add_link_options(--sysroot ${CMAKE_BINARY_DIR}/Root) include_directories(Libraries/LibC) diff --git a/Demos/DynamicObject/CMakeLists.txt b/Demos/DynamicObject/CMakeLists.txt index d1df1d0cbf6..06781c7c9f7 100644 --- a/Demos/DynamicObject/CMakeLists.txt +++ b/Demos/DynamicObject/CMakeLists.txt @@ -1,6 +1,5 @@ set(SOURCES main.cpp - ../../Libraries/LibC/crt0_shared.cpp ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostartfiles -lgcc_s -pie -fpic ") diff --git a/Libraries/LibC/CMakeLists.txt b/Libraries/LibC/CMakeLists.txt index b8bc5ec7600..0105d44ff5e 100644 --- a/Libraries/LibC/CMakeLists.txt +++ b/Libraries/LibC/CMakeLists.txt @@ -1,7 +1,6 @@ set(LIBC_SOURCES arpa/inet.cpp assert.cpp - crt0_shared.cpp ctype.cpp cxxabi.cpp dirent.cpp @@ -64,6 +63,11 @@ add_custom_command( TARGET crt0 COMMAND ${INSTALL_COMMAND} -D $ ${CMAKE_INSTALL_PREFIX}/usr/lib/crt0.o ) +add_library(crt0_shared STATIC crt0_shared.cpp) +add_custom_command( + TARGET crt0_shared + COMMAND ${INSTALL_COMMAND} -D $ ${CMAKE_INSTALL_PREFIX}/usr/lib/crt0_shared.o +) set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES}) diff --git a/Libraries/LibELF/DynamicLoader.cpp b/Libraries/LibELF/DynamicLoader.cpp index ff5f7028e6c..d3e901a1cfe 100644 --- a/Libraries/LibELF/DynamicLoader.cpp +++ b/Libraries/LibELF/DynamicLoader.cpp @@ -327,17 +327,32 @@ void DynamicLoader::do_relocations(size_t total_tls_size) } case R_386_GLOB_DAT: { auto symbol = relocation.symbol(); - if (!strcmp(symbol.name(), "__deregister_frame_info") || !strcmp(symbol.name(), "_ITM_registerTMCloneTable") - || !strcmp(symbol.name(), "_ITM_deregisterTMCloneTable") || !strcmp(symbol.name(), "__register_frame_info") - || !strcmp(symbol.name(), "__cxa_finalize") // __cxa_finalize will be called from libc's exit() - ) { - // We do not support these - break; - } VERBOSE("Global data relocation: '%s', value: %p\n", symbol.name(), symbol.value()); auto res = lookup_symbol(symbol); + if (!res.found) { + // We do not support these + // TODO: Can we tell gcc not to generate the piece of code that uses these? + // (--disable-tm-clone-registry flag in gcc conifugraion?) + if (!strcmp(symbol.name(), "__deregister_frame_info") || !strcmp(symbol.name(), "_ITM_registerTMCloneTable") + || !strcmp(symbol.name(), "_ITM_deregisterTMCloneTable") || !strcmp(symbol.name(), "__register_frame_info")) { + break; + } + + // The "__do_global_dtors_aux" function in libgcc_s.so needs this symbol, + // but we do not use that function so we don't actually need to resolve this symbol. + // The reason we can't resolve it here is that the symbol is defined in libc.so, + // but there's a circular dependecy between libgcc_s.so and libc.so, + // we deal with it by first loading libgcc_s and then libc. + // So we cannot find this symbol at this time (libc is not yet loaded). + if (m_filename == "libgcc_s.so" && !strcmp(symbol.name(), "__cxa_finalize")) { + break; + } + + // Symbol not found + ASSERT_NOT_REACHED(); + } VERBOSE("was symbol found? %d, address: 0x%x\n", res.found, res.address); - ASSERT(res.found); + VERBOSE("object: %s\n", m_filename.characters()); if (!res.found) { // TODO this is a hack diff --git a/Meta/CMake/utils.cmake b/Meta/CMake/utils.cmake index 093b16bbaed..46119f69751 100644 --- a/Meta/CMake/utils.cmake +++ b/Meta/CMake/utils.cmake @@ -28,8 +28,7 @@ function(serenity_lib target_name fs_name) serenity_install_headers(${target_name}) serenity_install_sources("Libraries/${target_name}") #add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) - add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES} ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) - #library_sources("{target_name}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) + add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) install(TARGETS ${target_name} DESTINATION usr/lib) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name}) serenity_generated_sources(${target_name}) @@ -67,7 +66,6 @@ endfunction() function(serenity_bin target_name) add_executable(${target_name} ${SOURCES}) - target_sources(${target_name} PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) install(TARGETS ${target_name} RUNTIME DESTINATION bin) serenity_generated_sources(${target_name}) endfunction() diff --git a/Toolchain/Patches/gcc.patch b/Toolchain/Patches/gcc.patch index 7cf7a59586f..f9e31b23223 100644 --- a/Toolchain/Patches/gcc.patch +++ b/Toolchain/Patches/gcc.patch @@ -115,7 +115,7 @@ diff -ruN a/gcc/config/serenity.h b/gcc/config/serenity.h +/* Files that are linked before user code. + The %s tells GCC to look for these files in the library directory. */ +#undef STARTFILE_SPEC -+#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti.o%s %{shared|pie:crtbeginS.o%s; :crtbegin.o%s}" ++#define STARTFILE_SPEC "%{static:crt0.o%s} crti.o%s %{!static: %{!fbuilding-libgcc:crt0_shared.o%s}} %{shared|pie:crtbeginS.o%s; :crtbegin.o%s}" + +/* Files that are linked after user code. */ +#undef ENDFILE_SPEC diff --git a/Userland/CMakeLists.txt b/Userland/CMakeLists.txt index 1ca0fe9afc8..537180a29cf 100644 --- a/Userland/CMakeLists.txt +++ b/Userland/CMakeLists.txt @@ -5,13 +5,11 @@ foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) if (CMD_NAME IN_LIST SPECIAL_TARGETS) add_executable("${CMD_NAME}-bin" ${CMD_SRC}) - target_sources("${CMD_NAME}-bin" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) target_link_libraries("${CMD_NAME}-bin" LibCore) install(TARGETS "${CMD_NAME}-bin" RUNTIME DESTINATION bin) install(CODE "execute_process(COMMAND mv ${CMD_NAME}-bin ${CMD_NAME} WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)") else () add_executable(${CMD_NAME} ${CMD_SRC}) - target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) target_link_libraries(${CMD_NAME} LibCore) install(TARGETS ${CMD_NAME} RUNTIME DESTINATION bin) endif() diff --git a/Userland/Tests/Kernel/CMakeLists.txt b/Userland/Tests/Kernel/CMakeLists.txt index c18d364cabf..cd9438dc4a8 100644 --- a/Userland/Tests/Kernel/CMakeLists.txt +++ b/Userland/Tests/Kernel/CMakeLists.txt @@ -3,7 +3,6 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC}) - target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) target_link_libraries(${CMD_NAME} LibCore) install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/Kernel) endforeach() diff --git a/Userland/Tests/LibC/CMakeLists.txt b/Userland/Tests/LibC/CMakeLists.txt index 8ce9b5c2b9d..799dfa9ff4e 100644 --- a/Userland/Tests/LibC/CMakeLists.txt +++ b/Userland/Tests/LibC/CMakeLists.txt @@ -3,7 +3,6 @@ file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp") foreach(CMD_SRC ${CMD_SOURCES}) get_filename_component(CMD_NAME ${CMD_SRC} NAME_WE) add_executable(${CMD_NAME} ${CMD_SRC}) - target_sources("${CMD_NAME}" PRIVATE ${CMAKE_SOURCE_DIR}/Libraries/LibC/crt0_shared.cpp) target_link_libraries(${CMD_NAME} LibCore) install(TARGETS ${CMD_NAME} RUNTIME DESTINATION usr/Tests/LibC) endforeach()