diff --git a/CMakeLists.txt b/CMakeLists.txt index 048be86..62fcda5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,29 +12,17 @@ set(CUSTOM_LIBC_PATH CACHE PATH "") set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(third-party) -get_third_party(glog) set(WITH_GFLAGS OFF CACHE INTERNAL "" FORCE) set(WITH_UNWIND OFF) set(BUILD_SHARED_LIBS OFF) -add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/glog - ${CMAKE_CURRENT_BINARY_DIR}/glog EXCLUDE_FROM_ALL) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/glog - ${CMAKE_CURRENT_BINARY_DIR}/glog/src) add_definitions(-DC10_USE_GLOG=1) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/raw_write) add_library(tls_secure tls_secure.cc) -add_executable(sloader sloader.cc dyn_loader.cc libc_mapping.cc sloader_dl.cc - utils.cc sloader_static.map) -target_link_libraries(sloader glog tls_secure) -target_compile_options(sloader PUBLIC -Wall -Werror) -target_link_options(sloader PUBLIC -static -Wl,-verbose -T - ${CMAKE_CURRENT_SOURCE_DIR}/sloader_static.map) - if(CUSTOM_LIBC_PATH) execute_process( COMMAND ${CMAKE_CXX_COMPILER} --print-file-name=crtbegin.o @@ -49,11 +37,10 @@ if(CUSTOM_LIBC_PATH) OUTPUT_VARIABLE LIBSTDCXX OUTPUT_STRIP_TRAILING_WHITESPACE) - add_executable(sloader_custom_libc sloader.cc dyn_loader.cc libc_mapping.cc - sloader_dl.cc utils.cc sloader_static.map) + add_executable(sloader sloader.cc dyn_loader.cc libc_mapping.cc sloader_dl.cc + utils.cc sloader_static.map) target_link_libraries( - sloader_custom_libc - glog + sloader ${CUSTOM_LIBC_PATH}/lib/crt1.o ${CUSTOM_LIBC_PATH}/lib/crti.o ${CRT_BEGIN} @@ -67,9 +54,9 @@ if(CUSTOM_LIBC_PATH) ${CRT_END} ${CUSTOM_LIBC_PATH}/lib/crtn.o tls_secure) - target_compile_options(sloader_custom_libc PUBLIC -Wall -Werror) + target_compile_options(sloader PUBLIC -Wall -Werror) target_link_options( - sloader_custom_libc + sloader BEFORE PUBLIC -nostdlib @@ -78,6 +65,13 @@ if(CUSTOM_LIBC_PATH) -Wl,-verbose -T ${CMAKE_CURRENT_SOURCE_DIR}/sloader_static.map) +else() + add_executable(sloader sloader.cc dyn_loader.cc libc_mapping.cc sloader_dl.cc + utils.cc sloader_static.map) + target_link_libraries(sloader tls_secure) + target_compile_options(sloader PUBLIC -Wall -Werror) + target_link_options(sloader PUBLIC -static -Wl,-verbose -T + ${CMAKE_CURRENT_SOURCE_DIR}/sloader_static.map) endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake diff --git a/debian-Dockerfile b/debian-Dockerfile index cff7f63..86e8480 100644 --- a/debian-Dockerfile +++ b/debian-Dockerfile @@ -1,14 +1,15 @@ FROM debian:12.2 ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y ninja-build cmake gcc g++ git python3 python3-distutils python3-dev python3-pip nasm clang-format libcap-dev tmux zsh neovim +RUN apt-get update +RUN apt-get install -y ninja-build cmake gcc g++ git python3 python3-distutils python3-dev python3-pip nasm clang-format libcap-dev tmux zsh neovim ccache gawk bison # RUN pip3 install torch==1.13.0+cpu -f https://download.pytorch.org/whl/torch_stable.html COPY . /sloader WORKDIR /sloader -# TODO -# RUN ./run-format.sh +RUN ./scripts/clone_glibc.sh glibc-2.36 +RUN ./scripts/build_glibc.sh RUN rm -rf build RUN mkdir build -RUN cmake -GNinja -S . -B build -RUN cmake --build build +RUN cmake -GNinja -S . -B build -DCUSTOM_LIBC_PATH=/sloader/glibc-install +RUN cmake --build build -j $(nproc) RUN cd build && ctest --output-on-failure -j $(nproc) RUN ./make-sloader-itself.sh diff --git a/dyn_loader.cc b/dyn_loader.cc index 1ba6278..76fa1a4 100644 --- a/dyn_loader.cc +++ b/dyn_loader.cc @@ -64,7 +64,8 @@ std::vector read_ldsoconf() { ELFBinary::ELFBinary(const std::filesystem::path path) : path_(path) { int fd = open(path_.c_str(), O_RDONLY); - CHECK(fd >= 0) << path_; + LOG(INFO) << LOG_KEY(path_) << LOG_KEY(fd); + CHECK(fd >= 0); size_t size = lseek(fd, 0, SEEK_END); CHECK_GT(size, 8UL + 16UL); @@ -598,6 +599,7 @@ Elf64_Addr DynLoader::TLSSymOffset(const std::string& name) { return (reinterpret_cast(sloader_dummy_to_secure_tls_space) + 4096 - addr); } LOG(FATAL) << "Cannot find " << name; + std::abort(); } void DynLoader::Relocate() { @@ -703,6 +705,7 @@ void DynLoader::Relocate() { size = sym.st_size; } else { LOG(FATAL) << "Cannot find " << name; + std::abort(); break; } void* dest = reinterpret_cast(bin.base_addr() + r.r_offset); diff --git a/misc/build_glibc.sh b/misc/build_glibc.sh deleted file mode 100755 index 6163a96..0000000 --- a/misc/build_glibc.sh +++ /dev/null @@ -1,5 +0,0 @@ -#! /bin/bash -eux - -cd $(git rev-parse --show-toplevel)/glibc-build -LD_LIBRARY_PATH="" bear -- make all -j 20 -LD_LIBRARY_PATH="" bear -- make install -j 20 diff --git a/scripts/build_glibc.sh b/scripts/build_glibc.sh new file mode 100755 index 0000000..4d7a786 --- /dev/null +++ b/scripts/build_glibc.sh @@ -0,0 +1,10 @@ +#! /bin/bash -eux + +cd $(git rev-parse --show-toplevel)/glibc-build +if which bear; then + LD_LIBRARY_PATH="" bear -- make all -j 20 + LD_LIBRARY_PATH="" bear -- make install -j 20 +else + LD_LIBRARY_PATH="" make all -j $(nproc) + LD_LIBRARY_PATH="" make install -j $(nproc) +fi diff --git a/misc/clone_glibc.sh b/scripts/clone_glibc.sh similarity index 66% rename from misc/clone_glibc.sh rename to scripts/clone_glibc.sh index b3d457a..d96d6a6 100755 --- a/misc/clone_glibc.sh +++ b/scripts/clone_glibc.sh @@ -2,14 +2,21 @@ cd $(git rev-parse --show-toplevel) +if [[ $# -ne 1 ]] +then + echo "Usage: $0 " + exit 1 +fi +GLIBC_VERSION=$1 + if [[ ! -d glibc ]] then - git clone git@github.com:akawashiro/glibc.git + git clone --depth 1 --no-single-branch https://github.com/akawashiro/glibc.git pushd glibc git remote add upstream https://sourceware.org/git/glibc.git git fetch --all - git checkout glibc-2.35 + git checkout ${GLIBC_VERSION} popd fi diff --git a/sloader.cc b/sloader.cc index 0b1026f..05ecffb 100644 --- a/sloader.cc +++ b/sloader.cc @@ -30,15 +30,14 @@ Elf64_Half GetEType(const std::filesystem::path& filepath) { size_t mapped_size = (size + 0xfff) & ~0xfff; char* p = (char*)mmap(NULL, mapped_size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); - CHECK(p != MAP_FAILED) << LOG_BITS(mapped_size) << LOG_BITS(size) << LOG_KEY(filepath); + LOG(FATAL) << LOG_BITS(mapped_size) << LOG_BITS(size) << LOG_KEY(filepath); + CHECK(p != MAP_FAILED); Elf64_Ehdr* ehdr = reinterpret_cast(p); return ehdr->e_type; } int main(int argc, char* const argv[], char** envp) { - google::InitGoogleLogging(argv[0]); - std::string argv0 = argv[1]; std::filesystem::path fullpath; @@ -56,7 +55,7 @@ int main(int argc, char* const argv[], char** envp) { } LOG(INFO) << LOG_KEY(fullpath); - CHECK(std::filesystem::exists(fullpath)) << fullpath; + CHECK(std::filesystem::exists(fullpath)); std::vector args; for (int i = 1; i < argc; i++) { @@ -74,5 +73,6 @@ int main(int argc, char* const argv[], char** envp) { GetDynLoader()->Run(); } else { LOG(FATAL) << "Unsupported etype = " << LOG_KEY(etype); + std::abort(); } } diff --git a/utils.cc b/utils.cc index bf58643..657a749 100644 --- a/utils.cc +++ b/utils.cc @@ -133,8 +133,6 @@ std::string ShowSTB(unsigned char bind) { return "STB_HIPROC"; default: { return std::to_string(bind); - // LOG(FATAL) << LOG_KEY(bind); - // std::abort(); } } } diff --git a/utils.h b/utils.h index 26ab2d2..363f677 100644 --- a/utils.h +++ b/utils.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include @@ -9,6 +8,28 @@ #include #include +class nullstream : public std::ostream { +public: + nullstream() : std::ostream(nullptr) {} +}; +inline nullstream null; + +#define CHECK(x) \ + if (!(x)) { \ + std::cerr << "CHECK failed: " << #x << std::endl; \ + exit(1); \ + } +#define CHECK_GT(x, y) CHECK((x) > (y)) +#define CHECK_LT(x, y) CHECK((x) < (y)) +#define CHECK_EQ(x, y) CHECK((x) == (y)) +#define CHECK_NE(x, y) CHECK((x) != (y)) +#define CHECK_GE(x, y) CHECK((x) >= (y)) +#define CHECK_LE(x, y) CHECK((x) <= (y)) +/* Replace null with std::cout to enable logging */ +#define LOG(loglevel) \ + null << #loglevel << " " << __FILE__ << ":" << __LINE__ << " " \ + << " " + #define LOG_KEY_VALUE(key, value) " " << key << "=" << value #define LOG_KEY(key) LOG_KEY_VALUE(#key, key) #define LOG_64BITS(key) LOG_KEY_VALUE(#key, HexString(key, 16))