├── .clang-format
├── .dockerignore
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── CMakeLists.txt
├── CTestCustom.cmake
├── LICENSE
├── README.md
├── build-pytorch.sh
├── cmake
└── third-party.cmake
├── ehframe_builder.h
├── elf_binary.cc
├── elf_binary.h
├── feature_unit_tests
├── call_once-g++-aarch64
│ ├── .gitignore
│ ├── fuga.cc
│ ├── hoge.cc
│ ├── main.cc
│ └── test.sh
├── call_once-g++
│ ├── .gitignore
│ ├── fuga.cc
│ ├── hoge.cc
│ ├── main.cc
│ └── test.sh
├── delete-unused-PT_DYNAMIC
│ ├── answer
│ │ └── .gitkeep
│ ├── base.c
│ ├── base.h
│ ├── base2.c
│ ├── base2.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── dynamic_cast-g++-aarch64
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── dynamic_cast-g++
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── exception-g++-aarch64
│ ├── fuga.cc
│ ├── fuga.h
│ ├── hoge.cc
│ ├── hoge.h
│ ├── main.cc
│ └── test.sh
├── exception-g++
│ ├── fuga.cc
│ ├── fuga.h
│ ├── hoge.cc
│ ├── hoge.h
│ ├── main.cc
│ └── test.sh
├── exception-str-g++-aarch64
│ ├── fuga.cc
│ ├── fuga.h
│ ├── hoge.cc
│ ├── hoge.h
│ ├── main.cc
│ └── test.sh
├── exe.cc
├── extern
│ ├── hoge.c
│ ├── main.c
│ └── test.sh
├── global-write-aarch64
│ ├── hoge.c
│ ├── main.c
│ └── test.sh
├── hello-g++-aarch64
│ ├── .gitignore
│ ├── hello.cc
│ └── test.sh
├── hello-g++
│ ├── .gitignore
│ ├── hello.cc
│ └── test.sh
├── hello-gcc-aarch64
│ ├── hello.c
│ └── test.sh
├── hello-gcc
│ ├── .gitignore
│ ├── hello.c
│ └── test.sh
├── inheritance-g++-aarch64
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── inheritance-g++
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── just-return-g++-aarch64
│ ├── return.cc
│ └── test.sh
├── just-return-g++
│ ├── return.cc
│ └── test.sh
├── just-return-gcc-aarch64
│ ├── .gitignore
│ ├── return.c
│ └── test.sh
├── just-return-gcc
│ ├── .gitignore
│ ├── return.c
│ └── test.sh
├── mprotect-aarch64
│ ├── .gitignore
│ ├── base.c
│ ├── base.h
│ ├── main.c
│ ├── mprotect_check.c
│ ├── mprotect_check.h
│ └── test.sh
├── mprotect
│ ├── .gitignore
│ ├── base.c
│ ├── base.h
│ ├── main.c
│ ├── mprotect_check.c
│ ├── mprotect_check.h
│ └── test.sh
├── renamer
│ ├── .gitignore
│ ├── fugafuga.c
│ ├── hoge.c
│ ├── mapping
│ ├── test.sh
│ └── use_fugafuga.c
├── run-all-tests.sh
├── setjmp-gcc-aarch64
│ ├── .gitignore
│ ├── hoge.c
│ ├── hoge.h
│ ├── main.c
│ └── test.sh
├── setjmp-gcc
│ ├── .gitignore
│ ├── hoge.c
│ ├── hoge.h
│ ├── main.c
│ └── test.sh
├── simple-lib-g++-aarch64
│ ├── .gitignore
│ ├── libmax.cc
│ ├── libmax.h
│ ├── main.cc
│ └── test.sh
├── simple-lib-g++
│ ├── .gitignore
│ ├── libmax.cc
│ ├── libmax.h
│ ├── main.cc
│ └── test.sh
├── simple-lib-gcc-aarch64
│ ├── .gitignore
│ ├── libmax.c
│ ├── libmax.h
│ ├── main.c
│ └── test.sh
├── simple-lib-gcc
│ ├── .gitignore
│ ├── libmax.c
│ ├── libmax.h
│ ├── main.c
│ └── test.sh
├── static-in-class-g++-aarch64
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── static-in-class-g++
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── static-in-function-g++-aarch64
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── static-in-function-g++
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── stb_gnu_unique_tls-aarch64
│ ├── .gitignore
│ ├── main.cc
│ ├── test.sh
│ └── unique.cc
├── stb_gnu_unique_tls
│ ├── .gitignore
│ ├── main.cc
│ ├── test.sh
│ └── unique.cc
├── tls-bss-g++-aarch64
│ ├── main.cc
│ └── test.sh
├── tls-bss-g++
│ ├── main.cc
│ └── test.sh
├── tls-bss-gcc-aarch64
│ ├── main.c
│ └── test.sh
├── tls-bss-gcc
│ ├── main.c
│ └── test.sh
├── tls-conflict-aarch64
│ ├── fuga.cc
│ ├── hoge.cc
│ ├── main.cc
│ └── test.sh
├── tls-dlopen-gcc-aarch64
│ ├── .gitignore
│ ├── lib.c
│ ├── main.c
│ └── test.sh
├── tls-dlopen-gcc
│ ├── .gitignore
│ ├── lib.c
│ ├── main.c
│ └── test.sh
├── tls-gcc-aarch64
│ ├── main.c
│ └── test.sh
├── tls-gcc
│ ├── main.c
│ └── test.sh
├── tls-lib-gcc-aarch64
│ ├── answer
│ │ └── .gitkeep
│ ├── base.c
│ ├── base.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── tls-lib-gcc-without-base-aarch64
│ ├── base.c
│ ├── base.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── tls-lib-gcc-without-base
│ ├── base.c
│ ├── base.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── tls-lib-gcc
│ ├── answer
│ │ └── .gitkeep
│ ├── base.c
│ ├── base.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── tls-multiple-lib-gcc-aarch64
│ ├── answer
│ │ └── .gitkeep
│ ├── base.c
│ ├── base.h
│ ├── base2.c
│ ├── base2.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ └── test.sh
├── tls-multiple-lib-gcc
│ ├── answer
│ │ └── .gitkeep
│ ├── base.c
│ ├── base.h
│ ├── base2.c
│ ├── base2.h
│ ├── lib.c
│ ├── lib.h
│ ├── main.c
│ ├── original
│ │ └── .gitkeep
│ ├── sold_out
│ │ └── .gitkeep
│ └── test.sh
├── tls-multiple-module-g++-aarch64
│ ├── .gitignore
│ ├── fuga.cc
│ ├── fuga.h
│ ├── fugahoge.cc
│ ├── hoge.cc
│ ├── hoge.h
│ ├── main.cc
│ └── test.sh
├── tls-multiple-module-g++
│ ├── .gitignore
│ ├── fuga.cc
│ ├── fuga.h
│ ├── fugahoge.cc
│ ├── hoge.cc
│ ├── hoge.h
│ ├── main.cc
│ └── test.sh
├── tls-thread-g++-aarch64
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── tls-thread-g++
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── typeid-g++-aarch64
│ ├── .gitignore
│ ├── fuga.h
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── typeid-g++
│ ├── .gitignore
│ ├── lib.cc
│ ├── lib.h
│ ├── main.cc
│ └── test.sh
├── unique_ptr-aarch64
│ ├── .gitignore
│ ├── hoge.cc
│ ├── main.cc
│ └── test.sh
├── version-gcc-aarch64
│ ├── .gitignore
│ ├── libmax1.c
│ ├── libmax1.h
│ ├── libmax2.c
│ ├── libmax2.def
│ ├── libmax2.h
│ ├── test.sh
│ ├── vertest1.c
│ └── vertest2.c
└── version-gcc
│ ├── .gitignore
│ ├── libmax1.c
│ ├── libmax1.h
│ ├── libmax2.c
│ ├── libmax2.def
│ ├── libmax2.h
│ ├── test.sh
│ ├── vertest1.c
│ └── vertest2.c
├── fedora-latest.Dockerfile
├── hash.cc
├── hash.h
├── ldsoconf.cc
├── ldsoconf.h
├── libtorch_test
├── CMakeLists.txt
├── torch_test.cc
├── torch_test.h
├── torch_test_main.cc
└── torch_test_main_dlopen.cc
├── mprotect_builder.cc
├── mprotect_builder.h
├── print_dtrela.cc
├── print_dynsymtab.cc
├── print_ehframe.cc
├── print_tls.cc
├── print_version.cc
├── pybind_libtorch_test
├── CMakeLists.txt
├── numpy.cc
└── test_soldout_modules.py
├── pybind_test
├── CMakeLists.txt
├── README.md
├── add.cc
├── numpy.cc
├── object.cc
└── test_soldout_modules.py
├── renamer_main.cc
├── renamer_test
├── .gitignore
├── fugafuga.c
├── hoge.c
├── mapping
├── test.sh
└── use_fugafuga.c
├── run-docker-tests.sh
├── run-format.sh
├── shdr_builder.cc
├── shdr_builder.h
├── sold.cc
├── sold.h
├── sold_main.cc
├── strtab_builder.cc
├── strtab_builder.h
├── symtab_builder.cc
├── symtab_builder.h
├── tests
├── CMakeLists.txt
├── base.cc
├── base.h
├── exe.cc
├── lib.cc
├── lib.h
└── runtest.sh
├── third_party
├── glog.cmake
└── pybind11.cmake
├── tools
├── listup_duplicated_syms.py
├── raw_write.h
├── relocation-list-up.sh
├── resolve_addr.py
├── search-symbol.sh
└── tracer.cc
├── ubuntu18.04-gpu.Dockerfile
├── ubuntu18.04.Dockerfile
├── ubuntu20.04.Dockerfile
├── ubuntu22.04.Dockerfile
├── utils.cc
├── utils.h
├── version_builder.cc
└── version_builder.h
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | AccessModifierOffset: -4
3 | ColumnLimit: 140
4 | IndentWidth: 4
5 | DerivePointerAlignment: false
6 | PointerAlignment: Left
7 | IncludeBlocks: Preserve
8 | AllowShortFunctionsOnASingleLine: Inline
9 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | build/*
2 | myenv/*
3 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build and test
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build:
7 |
8 | runs-on: ubuntu-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 | - name: Install requirements
13 | run: sudo apt install ninja-build g++-aarch64-linux-gnu qemu qemu-system-aarch64 qemu-user
14 | - name: Install Python packages
15 | run: pip install pytest numpy cmake-format
16 | - name: format
17 | run: ./run-format.sh
18 | - name: CMake
19 | run: mkdir build && cd build && cmake -GNinja -DSOLD_PYBIND_TEST=ON ..
20 | - name: Build
21 | run: cmake --build build
22 | - name: Test
23 | run: cd build && ctest --output-on-failure
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | *.so
3 | *.original
4 | *.soldout
5 | *.o
6 | *.out
7 | pytorch
8 | pytorch-build
9 | pytorch-install
10 | .cache
11 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4)
2 | project(sold LANGUAGES CXX)
3 |
4 | set(CMAKE_CXX_STANDARD 14)
5 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
6 |
7 | if(NOT CMAKE_BUILD_TYPE)
8 | set(CMAKE_BUILD_TYPE "RelWithDebInfo")
9 | endif()
10 |
11 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
12 |
13 | include(third-party)
14 | get_third_party(glog)
15 | set(WITH_GFLAGS OFF CACHE INTERNAL "" FORCE)
16 | add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/glog ${CMAKE_CURRENT_BINARY_DIR}/glog EXCLUDE_FROM_ALL)
17 | include_directories(${CMAKE_CURRENT_BINARY_DIR}/glog ${CMAKE_CURRENT_BINARY_DIR}/glog/src)
18 | add_definitions(-DC10_USE_GLOG=1)
19 |
20 | add_library(
21 | sold_lib
22 | sold.cc
23 | elf_binary.cc
24 | hash.cc
25 | ldsoconf.cc
26 | mprotect_builder.cc
27 | strtab_builder.cc
28 | symtab_builder.cc
29 | shdr_builder.cc
30 | utils.cc
31 | version_builder.cc
32 | )
33 |
34 | add_executable(
35 | sold
36 | sold_main.cc
37 | )
38 | target_link_libraries(sold sold_lib glog)
39 |
40 | add_executable(
41 | print_dtrela
42 | print_dtrela.cc
43 | )
44 | add_executable(renamer renamer_main.cc)
45 | target_link_libraries(renamer sold_lib glog)
46 |
47 | target_link_libraries(print_dtrela sold_lib glog)
48 |
49 | add_executable(
50 | print_dynsymtab
51 | print_dynsymtab.cc
52 | )
53 | target_link_libraries(print_dynsymtab sold_lib glog)
54 |
55 | add_executable(
56 | print_tls
57 | print_tls.cc
58 | )
59 | target_link_libraries(print_tls sold_lib glog)
60 |
61 | add_executable(
62 | print_version
63 | print_version.cc
64 | )
65 | target_link_libraries(print_version sold_lib glog)
66 |
67 | add_executable(
68 | print_ehframe
69 | print_ehframe.cc
70 | )
71 | target_link_libraries(print_ehframe sold_lib glog)
72 |
73 | add_subdirectory(tests)
74 |
75 |
76 | configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_CURRENT_BINARY_DIR})
77 | include(CTest)
78 |
79 | if(BUILD_TESTING)
80 | add_custom_target(feature_unit_tests ALL COMMAND "rsync" "-au" "${CMAKE_CURRENT_SOURCE_DIR}/feature_unit_tests" "${CMAKE_CURRENT_BINARY_DIR}")
81 | add_custom_target(renamer_test ALL COMMAND "rsync" "-au" "${CMAKE_CURRENT_SOURCE_DIR}/renamer_test" "${CMAKE_CURRENT_BINARY_DIR}")
82 | foreach(t exe hash)
83 | add_custom_target(
84 | test_${t}_out ALL
85 | COMMAND "${CMAKE_CURRENT_BINARY_DIR}/sold" "${CMAKE_CURRENT_BINARY_DIR}/tests/test_${t}" -o "${CMAKE_CURRENT_BINARY_DIR}/tests/test_${t}_out" --section-headers
86 | DEPENDS sold test_${t}
87 | )
88 |
89 | add_test(
90 | NAME ${t}_test
91 | COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tests/test_${t}_out
92 | )
93 | endforeach()
94 | add_test(
95 | NAME feature_unit_tests
96 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/feature_unit_tests"
97 | COMMAND run-all-tests.sh
98 | )
99 | add_test(
100 | NAME renamer
101 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/renamer_test"
102 | COMMAND test.sh)
103 | endif()
104 |
105 | if(SOLD_PYBIND_TEST)
106 | get_third_party(pybind11)
107 | add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/pybind11 ${CMAKE_CURRENT_BINARY_DIR}/pybind11 EXCLUDE_FROM_ALL)
108 | add_subdirectory(pybind_test)
109 | endif()
110 |
111 | if(SOLD_LIBTORCH_TEST)
112 | add_subdirectory(libtorch_test)
113 | endif()
114 |
115 | if(SOLD_PYBIND_TEST AND SOLD_LIBTORCH_TEST)
116 | add_subdirectory(pybind_libtorch_test)
117 | endif()
118 |
--------------------------------------------------------------------------------
/CTestCustom.cmake:
--------------------------------------------------------------------------------
1 | set(CTEST_CUSTOM_TESTS_IGNORE
2 | demangle
3 | logging
4 | signalhandler
5 | stacktrace
6 | stl_logging
7 | symbolize
8 | )
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sold
2 | `sold` is a linker software which links a shared objects and its depending
3 | shared objects. For example,
4 | ```bash
5 | % ldd libhoge.so
6 | libfuga.so (0x00007fb6550b2000)
7 | % sold -i libhoge.so -o libhoge2.so
8 | % ldd libhoge2.so
9 | %
10 | ```
11 | `sold` works only for shared objects not for executables. Sorry.
12 |
13 | ## Branches
14 | - `master`: I am developing on this branch.
15 | - `stable`: Stable version of master for our internal use.
16 |
17 | ## Requirements
18 | `sold` works only on Linux on x86-64 and aarch64 architectures.
19 |
20 | ## How to build
21 | ```bash
22 | git clone https://github.com/akawashiro/sold.git
23 | cd sold
24 | mkdir -p build
25 | cd build
26 | cmake ..
27 | make
28 | ```
29 | Now you can see the `sold` in `build` directory.
30 |
31 | ## How to use
32 | ```bash
33 | sold -i [INPUT] -o [OUTPUT]
34 | ```
35 | Options
36 | - `--section-headers`: Emit section headers. Output shared objects work without section headers but they are useful for debugging.
37 | - `--check-output`: Check integrity of the output by parsing it again.
38 | - `--exclude-so`: Specify a shared object not to combine.
39 |
40 | # Renamer
41 | `renamer` is software to rename symbols in shared objects. You can rename symbols in shared objects like the following.
42 | ```
43 | % cat mapping
44 | hoge fugafuga
45 | % renamer libhoge_original.so --output libhoge_renamed.so --rename-mapping-file mapping
46 | ```
47 |
48 | ## Requirements & How to build
49 | Just same as `sold`.
50 |
51 | ## How to use
52 | ```bash
53 | renamer [INPUT] --output [OUTPUT] --rename-mapping-file [MAPPING]
54 | ```
55 | All lines in [MAPPING] must be a space separated pair of the old name of a symbol and the new name.
56 |
57 | # For developers
58 | Please run "./run-format.sh" before merging to master branch.
59 |
60 | ## TODO
61 | - Executables
62 | - TLS in executables
63 | - Initial exec and local exec
64 | - x86-32
65 | - Test Fedora linux in CI
66 |
67 | ## Integration test with practical libraries
68 | ### pybind test
69 | The purpose of this test is to check `sold` can preserve the complex ABI.
70 | ```bash
71 | git clone https://github.com/akawashiro/sold.git
72 | cd sold
73 | mkdir -p build
74 | cmake -S . -B build -DSOLD_PYBIND_TEST=ON -G Ninja
75 | cmake --build build
76 | ctest --test-dir build
77 | ```
78 | ## libtorch test
79 | Note: You can generate libtorch using `./build-pytorch.sh`. This script install libtorch to `sold/pytorch-install`.
80 | ```
81 | git clone https://github.com/akawashiro/sold.git
82 | cd sold
83 | mkdir -p build
84 | cmake -B build -S . -DCMAKE_PREFIX_PATH=/absolute/path/to/libtorch/dir -DSOLD_LIBTORCH_TEST=ON -GNinja
85 | cmake --build build
86 | ctest --test-dir build
87 | ```
88 | ## pybind + libtorch test
89 | Note: You can generate libtorch using `./build-pytorch.sh`. This script install libtorch to `sold/pytorch-install`.
90 | ```
91 | git clone https://github.com/akawashiro/sold.git
92 | cd sold
93 | mkdir -p build
94 | cmake -DCMAKE_PREFIX_PATH=/absolute/path/to/libtorch/dir -DSOLD_LIBTORCH_TEST=ON -DSOLD_PYBIND_TEST=ON -GNinja -B build -S .
95 | cmake --build build
96 | ctest --test-dir build
97 | ```
98 |
99 |
100 | ## Test with Docker
101 | ```
102 | sudo docker build -f ubuntu18.04.Dockerfile .
103 | sudo docker build -f ubuntu20.04.Dockerfile .
104 | sudo docker build -f ubuntu22.04.Dockerfile .
105 | sudo docker build -f fedora-latest.Dockerfile .
106 | ```
107 |
--------------------------------------------------------------------------------
/build-pytorch.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | # git clone --branch v1.13.0 git@github.com:pytorch/pytorch.git pytorch
4 | # pushd pytorch
5 | # git submodule update --init --recursive
6 | # popd
7 |
8 | BUILD_DIR=$(pwd)/pytorch-build
9 | INSTALL_DIR=$(pwd)/pytorch-install
10 | mkdir -p ${BUILD_DIR}
11 | mkdir -p ${INSTALL_DIR}
12 | cmake -S pytorch -B ${BUILD_DIR} -G Ninja \
13 | -DBUILD_SHARED_LIBS:BOOL=ON \
14 | -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo \
15 | -DPYTHON_EXECUTABLE:PATH=`which python3` \
16 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
17 | -DUSE_CUDA=OFF \
18 | -DUSE_CUDNN=OFF \
19 | -DUSE_ROCM=OFF \
20 | -DUSE_NCCL=OFF \
21 | -DUSE_NNPACK=OFF \
22 | -DCMAKE_CXX_COMPILER_LAUNCHER=sccache \
23 | -DCMAKE_INSTALL_PREFIX:PATH=${INSTALL_DIR}
24 | cmake --build pytorch-build -- -j12 install
25 |
--------------------------------------------------------------------------------
/cmake/third-party.cmake:
--------------------------------------------------------------------------------
1 | # Download and unpack a third-party library at configure time
2 | # The original code is at the README of google-test:
3 | # https://github.com/google/googletest/tree/master/googletest
4 | function(get_third_party name)
5 | configure_file(
6 | "${PROJECT_SOURCE_DIR}/third_party/${name}.cmake"
7 | "${CMAKE_CURRENT_BINARY_DIR}/${name}-download/CMakeLists.txt")
8 | execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
9 | RESULT_VARIABLE result
10 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${name}-download")
11 | if(result)
12 | message(FATAL_ERROR "CMake step for ${name} failed: ${result}")
13 | endif()
14 | execute_process(COMMAND ${CMAKE_COMMAND} --build .
15 | RESULT_VARIABLE result
16 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${name}-download")
17 | if(result)
18 | message(FATAL_ERROR "Build step for ${name} failed: ${result}")
19 | endif()
20 | endfunction()
21 |
--------------------------------------------------------------------------------
/ehframe_builder.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #pragma once
17 |
18 | #include "utils.h"
19 |
20 | class EHFrameBuilder {
21 | public:
22 | EHFrameBuilder() {
23 | eh_frame_header_.version = 0x1;
24 | eh_frame_header_.eh_frame_ptr_enc = DW_EH_PE_sdata4 + DW_EH_PE_pcrel;
25 | eh_frame_header_.fde_count_enc = DW_EH_PE_udata4;
26 | eh_frame_header_.table_enc = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
27 | eh_frame_header_.eh_frame_ptr = 0;
28 | eh_frame_header_.fde_count = 0;
29 | eh_frame_header_.table = std::vector();
30 | }
31 |
32 | void Emit(FILE* fp) {
33 | Write(fp, eh_frame_header_.version);
34 | Write(fp, eh_frame_header_.eh_frame_ptr_enc);
35 | Write(fp, eh_frame_header_.fde_count_enc);
36 | Write(fp, eh_frame_header_.table_enc);
37 | Write(fp, eh_frame_header_.eh_frame_ptr);
38 | Write(fp, eh_frame_header_.fde_count);
39 | for (const EHFrameHeader::FDETableEntry te : eh_frame_header_.table) {
40 | Write(fp, te.initial_loc);
41 | Write(fp, te.fde_ptr);
42 | }
43 | }
44 |
45 | uintptr_t Size() const {
46 | return sizeof(eh_frame_header_.version) + sizeof(eh_frame_header_.eh_frame_ptr_enc) + sizeof(eh_frame_header_.fde_count_enc) +
47 | sizeof(eh_frame_header_.table_enc) + sizeof(eh_frame_header_.eh_frame_ptr) + sizeof(eh_frame_header_.fde_count) +
48 | eh_frame_header_.fde_count *
49 | (sizeof(EHFrameHeader::FDETableEntry::fde_ptr) + sizeof(EHFrameHeader::FDETableEntry::initial_loc));
50 | }
51 |
52 | void Add(const std::string& name, const EHFrameHeader& efh, const uintptr_t efh_vaddr, const uintptr_t load_offset,
53 | const uintptr_t new_efh_vaddr) {
54 | LOG(INFO) << "EHFrameBuilder" << SOLD_LOG_BITS(efh.version) << SOLD_LOG_DWEHPE(efh.eh_frame_ptr_enc)
55 | << SOLD_LOG_DWEHPE(efh.fde_count_enc) << SOLD_LOG_DWEHPE(efh.table_enc) << SOLD_LOG_BITS(efh.eh_frame_ptr)
56 | << SOLD_LOG_BITS(efh.fde_count);
57 | for (const auto te : efh.table) {
58 | LOG(INFO) << "EHFrameBuilder" << SOLD_LOG_BITS(te.fde_ptr) << SOLD_LOG_BITS(te.initial_loc);
59 | }
60 |
61 | eh_frame_header_.fde_count += efh.fde_count;
62 | for (const auto te : efh.table) {
63 | EHFrameHeader::FDETableEntry new_te;
64 | new_te.fde_ptr = static_cast(efh_vaddr) + te.fde_ptr + static_cast(load_offset) - new_efh_vaddr;
65 | new_te.initial_loc = static_cast(efh_vaddr) + te.initial_loc + static_cast(load_offset) - new_efh_vaddr;
66 | eh_frame_header_.table.emplace_back(new_te);
67 | VLOG(3) << "EHFrameBuilder" << SOLD_LOG_BITS(new_te.fde_ptr) << SOLD_LOG_BITS(new_te.initial_loc);
68 | }
69 | }
70 |
71 | uint32_t fde_count() const { return eh_frame_header_.fde_count; }
72 |
73 | private:
74 | EHFrameHeader eh_frame_header_;
75 | };
76 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libfuga.so
2 | libfuga.so.original
3 | libfuga.so.soldout
4 | libhoge.so
5 | main
6 | sold.*
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++-aarch64/fuga.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void thread_proc();
4 |
5 | void fuga() {
6 | std::thread t1(thread_proc);
7 | std::thread t2(thread_proc);
8 | std::thread t3(thread_proc);
9 |
10 | t1.join();
11 | t2.join();
12 | t3.join();
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | std::once_flag once;
6 |
7 | void init() {
8 | std::cout << "initialize" << std::endl;
9 | }
10 |
11 | void thread_proc() {
12 | std::call_once(once, init);
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | void fuga();
2 |
3 | int main() {
4 | fuga();
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-g++ -fPIC -shared -Wl,-soname,libhoge.so -o libhoge.so hoge.cc
4 | aarch64-linux-gnu-g++ -fPIC -shared -Wl,-soname,libfuga.so -o libfuga.so fuga.cc libhoge.so
5 | LD_LIBRARY_PATH=. aarch64-linux-gnu-g++ -o main main.cc libfuga.so libhoge.so -pthread
6 |
7 | mv libfuga.so libfuga.so.original
8 | GLOG_log_dir=. LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libfuga.so.original -o libfuga.so.soldout --section-headers --custom-library-path /usr/aarch64-linux-gnu/lib
9 | ln -sf libfuga.so.soldout libfuga.so
10 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++/.gitignore:
--------------------------------------------------------------------------------
1 | libfuga.so
2 | libfuga.so.original
3 | libfuga.so.soldout
4 | libhoge.so
5 | main
6 | sold.*
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++/fuga.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void thread_proc();
4 |
5 | void fuga() {
6 | std::thread t1(thread_proc);
7 | std::thread t2(thread_proc);
8 | std::thread t3(thread_proc);
9 |
10 | t1.join();
11 | t2.join();
12 | t3.join();
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++/hoge.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | std::once_flag once;
6 |
7 | void init() {
8 | std::cout << "initialize" << std::endl;
9 | }
10 |
11 | void thread_proc() {
12 | std::call_once(once, init);
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++/main.cc:
--------------------------------------------------------------------------------
1 | void fuga();
2 |
3 | int main() {
4 | fuga();
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/call_once-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | g++ -fPIC -shared -Wl,-soname,libhoge.so -o libhoge.so hoge.cc
4 | g++ -fPIC -shared -Wl,-soname,libfuga.so -o libfuga.so fuga.cc libhoge.so
5 | LD_LIBRARY_PATH=. g++ -o main main.cc libfuga.so -pthread
6 |
7 | mv libfuga.so libfuga.so.original
8 | GLOG_log_dir=. LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libfuga.so.original -o libfuga.so.soldout --section-headers
9 | ln -sf libfuga.so.soldout libfuga.so
10 | LD_LIBRARY_PATH=. ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/answer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/delete-unused-PT_DYNAMIC/answer/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/base.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_i = 3;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/base2.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_j = 100;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/base2.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_j;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/lib.c:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
7 | int return_tls_j() {
8 | return thread_local_j;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/lib.h:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 | #include "base2.h"
3 |
4 | int return_tls_i();
5 | int return_tls_j();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("i = %d\n", return_tls_i());
6 | printf("j = %d\n", return_tls_j());
7 | return 0;
8 | }
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/delete-unused-PT_DYNAMIC/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/delete-unused-PT_DYNAMIC/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/delete-unused-PT_DYNAMIC/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o base.o base.c
4 | gcc -fPIC -c -o base2.o base2.c
5 | gcc -fPIC -c -o lib.o lib.c
6 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
7 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base2.so -o original/base2.so base2.o
8 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base2.so original/base.so
9 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o answer/lib.so lib.o base2.o base.o
10 |
11 | # Without sold
12 | # LD_LIBRARY_PATH=original gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base2.so original/base.so
13 | # LD_LIBRARY_PATH=original ./main.out
14 |
15 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --delete-unused-DT_STRTAB
16 |
17 | LD_LIBRARY_PATH=sold_out gcc -Wl,--hash-style=gnu -o main.out main.c sold_out/lib.so
18 | LD_LIBRARY_PATH=sold_out ./main.out
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | lib.o
2 | lib.so
3 | lib.so.original
4 | lib.so.soldout
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class Base {
5 | public:
6 | virtual ~Base() {}
7 | };
8 | class Sub1 : public Base {};
9 | class Sub2 : public Base {};
10 |
11 | void TryDowncast() {
12 | Base* base = new Sub1;
13 | Sub2* sub2 = dynamic_cast(base);
14 | if (sub2 == nullptr) {
15 | std::cout << "Downcast failed" << std::endl;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | void TryDowncast();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int main() {
4 | TryDowncast();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 | echo ----------- Use sold -----------
13 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
14 |
15 | # Use original
16 | ln -sf lib.so.original lib.so
17 | echo ----------- Use original -----------
18 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++/.gitignore:
--------------------------------------------------------------------------------
1 | lib.o
2 | lib.so
3 | lib.so.original
4 | lib.so.soldout
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class Base {
5 | public:
6 | virtual ~Base() {}
7 | };
8 | class Sub1 : public Base {};
9 | class Sub2 : public Base {};
10 |
11 | void TryDowncast() {
12 | Base* base = new Sub1;
13 | Sub2* sub2 = dynamic_cast(base);
14 | if (sub2 == nullptr) {
15 | std::cout << "Downcast failed" << std::endl;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++/lib.h:
--------------------------------------------------------------------------------
1 | void TryDowncast();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int main() {
4 | TryDowncast();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/dynamic_cast-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 | echo ----------- Use sold -----------
13 | LD_LIBRARY_PATH=. ./main
14 |
15 | # Use original
16 | ln -sf lib.so.original lib.so
17 | echo ----------- Use original -----------
18 | LD_LIBRARY_PATH=. ./main
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/fuga.cc:
--------------------------------------------------------------------------------
1 | #include "fuga.h"
2 |
3 | void throw_exception_fuga() {
4 | throw std::runtime_error("fuga");
5 | }
6 |
7 | void catch_exception_fuga() {
8 | try {
9 | throw_exception_fuga();
10 | } catch (std::exception& e) {
11 | std::cout << e.what() << std::endl;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/fuga.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_fuga();
6 | void catch_exception_fuga();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 | #include "fuga.h"
3 |
4 | void throw_exception_hoge() {
5 | throw std::runtime_error("hoge");
6 | }
7 |
8 | void catch_exception_hoge() {
9 | try {
10 | throw_exception_hoge();
11 | } catch (std::exception& e) {
12 | std::cout << e.what() << std::endl;
13 | }
14 |
15 | try {
16 | throw_exception_fuga();
17 | } catch (std::exception& e) {
18 | std::cout << e.what() << std::endl;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_hoge();
6 | void catch_exception_hoge();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int main() {
4 | std::cout << "catch_exception" << std::endl;
5 | catch_exception_hoge();
6 |
7 | std::cout << "throw_exception" << std::endl;
8 | try {
9 | throw_exception_hoge();
10 | } catch (std::exception& e) {
11 | std::cout << e.what() << std::endl;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -shared -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | aarch64-linux-gnu-g++ -fPIC -shared -o libhoge.so.original -Wl,-soname,libhoge.so hoge.cc libfuga.so
5 | aarch64-linux-gnu-g++ main.cc -o main.out libhoge.so.original libfuga.so
6 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
7 |
8 | # Use sold
9 | ln -sf libhoge.so.soldout libhoge.so
10 | # Use original
11 | # ln -sf libhoge.so.original libhoge.so
12 |
13 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/fuga.cc:
--------------------------------------------------------------------------------
1 | #include "fuga.h"
2 |
3 | void throw_exception_fuga() {
4 | throw std::runtime_error("fuga");
5 | }
6 |
7 | void catch_exception_fuga() {
8 | try {
9 | throw_exception_fuga();
10 | } catch (std::exception& e) {
11 | std::cout << e.what() << std::endl;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/fuga.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_fuga();
6 | void catch_exception_fuga();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/hoge.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 | #include "fuga.h"
3 |
4 | void throw_exception_hoge() {
5 | throw std::runtime_error("hoge");
6 | }
7 |
8 | void catch_exception_hoge() {
9 | try {
10 | throw_exception_hoge();
11 | } catch (std::exception& e) {
12 | std::cout << e.what() << std::endl;
13 | }
14 |
15 | try {
16 | throw_exception_fuga();
17 | } catch (std::exception& e) {
18 | std::cout << e.what() << std::endl;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_hoge();
6 | void catch_exception_hoge();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int main() {
4 | std::cout << "catch_exception" << std::endl;
5 | catch_exception_hoge();
6 |
7 | std::cout << "throw_exception" << std::endl;
8 | try {
9 | throw_exception_hoge();
10 | } catch (std::exception& e) {
11 | std::cout << e.what() << std::endl;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -shared -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | g++ -fPIC -shared -o libhoge.so.original -Wl,-soname,libhoge.so hoge.cc libfuga.so
5 | g++ main.cc -o main.out libhoge.so.original libfuga.so
6 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --check-output
7 |
8 | # Use sold
9 | ln -sf libhoge.so.soldout libhoge.so
10 | # Use original
11 | # ln -sf libhoge.so.original libhoge.so
12 |
13 | LD_LIBRARY_PATH=. ./main.out
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/fuga.cc:
--------------------------------------------------------------------------------
1 | #include "fuga.h"
2 |
3 | void throw_exception_fuga() {
4 | std::cout << "QWERHOGETYUIOPASDFGHJKLZXCVBNM" << std::endl;
5 | throw std::runtime_error("fuga");
6 | }
7 |
8 | void catch_exception_fuga() {
9 | try {
10 | std::cout << "QWERTYUIOPASDFGHJKLZXCVBNM" << std::endl;
11 | throw_exception_fuga();
12 | } catch (std::exception& e) {
13 | std::cout << "QWERHOGETYUIOPASDFGHJKLZXCVBNM" << std::endl;
14 | std::cout << e.what() << std::endl;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/fuga.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_fuga();
6 | void catch_exception_fuga();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 | #include "fuga.h"
3 |
4 | void throw_exception_hoge() {
5 | throw std::runtime_error("hoge");
6 | }
7 |
8 | void catch_exception_hoge() {
9 | try {
10 | std::cout << "QWERTYUIOPASDFGHJKLZXCVBNM" << std::endl;
11 | throw_exception_hoge();
12 | } catch (std::exception& e) {
13 | std::cout << e.what() << std::endl;
14 | }
15 |
16 | try {
17 | std::cout << "QWERTYUIOPASDFGHJKLZXCVBNM" << std::endl;
18 | throw_exception_fuga();
19 | } catch (std::exception& e) {
20 | std::cout << e.what() << std::endl;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void throw_exception_hoge();
6 | void catch_exception_hoge();
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int main() {
4 | std::cout << "catch_exception" << std::endl;
5 | catch_exception_hoge();
6 |
7 | std::cout << "throw_exception" << std::endl;
8 | try {
9 | throw_exception_hoge();
10 | } catch (std::exception& e) {
11 | std::cout << e.what() << std::endl;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exception-str-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -shared -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | aarch64-linux-gnu-g++ -fPIC -shared -o libhoge.so.original -Wl,-soname,libhoge.so hoge.cc libfuga.so
5 | aarch64-linux-gnu-g++ main.cc -o main libhoge.so.original libfuga.so
6 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
7 |
8 | # Use sold
9 | ln -sf libhoge.so.soldout libhoge.so
10 | # Use original
11 | # ln -sf libhoge.so.original libhoge.so
12 |
13 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/exe.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "lib.h"
5 |
6 | static int g_init;
7 | __attribute__((constructor)) static void init() {
8 | puts("Constructor in exe");
9 | g_init = 42;
10 | }
11 |
12 | __attribute__((destructor)) static void quit() {
13 | puts("Destructor in exe");
14 | }
15 |
16 | int main(int argc, char** argv) {
17 | int is_exe = (argc == 1);
18 |
19 | puts("Start main");
20 | if (lib_add_42_via_base(10) != 52) abort();
21 | if (in_both_lib_and_base() != 100) abort();
22 |
23 | // fprintf(stderr, "Use stderr from main\n");
24 | lib_use_stderr();
25 |
26 | if (g_init != 42) abort();
27 | // TODO(hamaji): Fix .init_array for the main binary.
28 | if (!is_exe) {
29 | if (lib_init_value() != 43) abort();
30 | if (lib_base_init_value() != 44) abort();
31 | puts("Constructors are OK");
32 | }
33 |
34 | if (lib_base_global() != 98) abort();
35 |
36 | if (lib_base_vf() != 1234) abort();
37 |
38 | if (lib_base_thread_var() != 121) abort();
39 | if (lib_base_thread_var_reloc() != 42) abort();
40 | if (lib_thread_var() != 111) abort();
41 | if (lib_thread_var_reloc() != 32) abort();
42 |
43 | puts("OK");
44 | }
45 |
--------------------------------------------------------------------------------
/feature_unit_tests/extern/hoge.c:
--------------------------------------------------------------------------------
1 | int hoge_var = 0xdeadbeef;
2 |
3 | void inc() {
4 | hoge_var++;
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/extern/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | extern int hoge_var;
5 | int fuga_var = 0xaaaaaaaa;
6 | void inc();
7 |
8 | int main() {
9 | printf("hoge_var = %x &hoge_var = %x\n", hoge_var, &hoge_var);
10 | printf("hoge_var = %x &hoge_var = %x\n", *((&hoge_var - 1)), (&hoge_var - 1));
11 | printf("hoge_var = %x &hoge_var = %x\n", *((&hoge_var - 2)), (&hoge_var - 2));
12 | assert(hoge_var == 0xdeadbeef);
13 | inc();
14 | printf("hoge_var = %x &hoge_var = %x\n", hoge_var, &hoge_var);
15 | assert(hoge_var == 0xdeadbeef + 1);
16 | hoge_var = 3;
17 | return 0;
18 | }
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/extern/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | pushd ~/sold/build
4 | ninja
5 | popd
6 | gcc hoge.c -fPIC -shared -Wl,-soname,libhoge.so -o libhoge.so
7 | gcc main.c libhoge.so -rdynamic -export-dynamic
8 | # GLOG_logtostderr=1 ../../build/print_dynsymtab libhoge.so
9 |
10 | GLOG_log_dir=. LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold a.out -o a.out.soldout --section-headers
11 | GLOG_logtostderr=1 LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold a.out -o a.out.soldout --section-headers
12 | ./a.out.soldout
13 |
--------------------------------------------------------------------------------
/feature_unit_tests/global-write-aarch64/hoge.c:
--------------------------------------------------------------------------------
1 | int hoge;
2 | __thread int hoge_th;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/global-write-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | extern int hoge;
4 |
5 | int main() {
6 | hoge = 10;
7 | printf("hoge = %d\n", hoge);
8 | }
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/global-write-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-gcc -fPIC -shared -o libhoge.so -Wl,-soname,libhoge.so hoge.c
4 | aarch64-linux-gnu-gcc -o main main.c libhoge.so
5 |
6 | mv libhoge.so libhoge.so.original
7 | $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
8 | ln -sf libhoge.so.soldout libhoge.so
9 |
10 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | hello
2 | hello.out
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++-aarch64/hello.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | std::cout << "Hello World!" << std::endl;
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | aarch64-linux-gnu-g++ hello.cc -o hello
4 | $(git rev-parse --show-toplevel)/build/sold hello -o hello.out --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
5 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./hello.out
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++/.gitignore:
--------------------------------------------------------------------------------
1 | hello
2 | hello.out
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++/hello.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | std::cout << "Hello World!" << std::endl;
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | g++ hello.cc -o hello
4 | $(git rev-parse --show-toplevel)/build/sold hello -o hello.out --section-headers --check-output
5 | ./hello.out
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-gcc-aarch64/hello.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | puts("Hello World!\n");
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | aarch64-linux-gnu-gcc hello.c -o hello
4 | $(git rev-parse --show-toplevel)/build/sold hello -o hello.out --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
5 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./hello.out
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | hello
2 | hello.out
3 | test.sh
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-gcc/hello.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | puts("Hello World!\n");
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/hello-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | gcc hello.c -o hello
4 | $(git rev-parse --show-toplevel)/build/sold hello -o hello.out --section-headers --check-output
5 | ./hello.out
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | hello
2 | hello.out
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | void B::Speak() {
4 | std::cout << "I am B." << std::endl;
5 | }
6 |
7 | void C::Speak() {
8 | std::cout << "I am C." << std::endl;
9 | }
10 |
11 | void JustHelloFun() {
12 | std::cout << "Hello from lib" << std::endl;
13 |
14 | B* bptr = new B;
15 | C* cptr = new C;
16 |
17 | A* aptr = bptr;
18 | aptr->Speak();
19 | aptr = cptr;
20 | aptr->Speak();
21 |
22 | delete bptr;
23 | delete cptr;
24 | }
25 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class A {
4 | public:
5 | virtual void Speak(){};
6 | };
7 |
8 | class B : public A {
9 | public:
10 | void Speak() override;
11 | int a;
12 | int b;
13 | };
14 |
15 | class C : public A {
16 | public:
17 | void Speak() override;
18 | };
19 |
20 | void JustHelloFun();
21 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 | #include
5 |
6 | void JustHelloFunMain() {
7 | std::cout << "Hello from main" << std::endl;
8 |
9 | B* bptr = new B;
10 | C* cptr = new C;
11 |
12 | A* aptr = bptr;
13 | aptr->Speak();
14 | aptr = cptr;
15 | aptr->Speak();
16 |
17 | delete bptr;
18 | delete cptr;
19 |
20 | std::unique_ptr buptr = std::make_unique();
21 | std::unique_ptr cuptr = std::make_unique();
22 | buptr->Speak();
23 | cuptr->Speak();
24 |
25 | std::shared_ptr bsptr = std::make_unique();
26 | std::shared_ptr csptr = std::make_unique();
27 | bsptr->Speak();
28 | csptr->Speak();
29 | }
30 |
31 | void CallSpeak(A* aptr) {
32 | aptr->Speak();
33 | }
34 |
35 | int main() {
36 | std::cout << "Before JustHelloFun" << std::endl;
37 | JustHelloFun();
38 | std::cout << "After JustHelloFun\n" << std::endl;
39 |
40 | std::cout << "Before JustHelloFunMain" << std::endl;
41 | JustHelloFunMain();
42 | std::cout << "After JustHelloFunMain\n" << std::endl;
43 |
44 | std::cout << "Before constructors" << std::endl;
45 | B b;
46 | C c;
47 | std::cout << "After constructors\n" << std::endl;
48 |
49 | std::cout << "Before member functions" << std::endl;
50 | b.Speak();
51 | c.Speak();
52 | std::cout << "After member functions\n" << std::endl;
53 |
54 | std::cout << "Before CallSpeak" << std::endl;
55 | CallSpeak(&b);
56 | CallSpeak(&c);
57 | std::cout << "After CallSpeak" << std::endl;
58 | return 0;
59 | }
60 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++/.gitignore:
--------------------------------------------------------------------------------
1 | hello
2 | hello.out
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | void B::Speak() {
4 | std::cout << "I am B." << std::endl;
5 | }
6 |
7 | void C::Speak() {
8 | std::cout << "I am C." << std::endl;
9 | }
10 |
11 | void JustHelloFun() {
12 | std::cout << "Hello from lib" << std::endl;
13 |
14 | B* bptr = new B;
15 | C* cptr = new C;
16 |
17 | A* aptr = bptr;
18 | aptr->Speak();
19 | aptr = cptr;
20 | aptr->Speak();
21 |
22 | delete bptr;
23 | delete cptr;
24 | }
25 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++/lib.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | class A {
4 | public:
5 | virtual void Speak(){};
6 | };
7 |
8 | class B : public A {
9 | public:
10 | void Speak() override;
11 | int a;
12 | int b;
13 | };
14 |
15 | class C : public A {
16 | public:
17 | void Speak() override;
18 | };
19 |
20 | void JustHelloFun();
21 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 | #include
5 |
6 | void JustHelloFunMain() {
7 | std::cout << "Hello from main" << std::endl;
8 |
9 | B* bptr = new B;
10 | C* cptr = new C;
11 |
12 | A* aptr = bptr;
13 | aptr->Speak();
14 | aptr = cptr;
15 | aptr->Speak();
16 |
17 | delete bptr;
18 | delete cptr;
19 |
20 | std::unique_ptr buptr = std::make_unique();
21 | std::unique_ptr cuptr = std::make_unique();
22 | buptr->Speak();
23 | cuptr->Speak();
24 |
25 | std::shared_ptr bsptr = std::make_unique();
26 | std::shared_ptr csptr = std::make_unique();
27 | bsptr->Speak();
28 | csptr->Speak();
29 | }
30 |
31 | void CallSpeak(A* aptr) {
32 | aptr->Speak();
33 | }
34 |
35 | int main() {
36 | std::cout << "Before JustHelloFun" << std::endl;
37 | JustHelloFun();
38 | std::cout << "After JustHelloFun\n" << std::endl;
39 |
40 | std::cout << "Before JustHelloFunMain" << std::endl;
41 | JustHelloFunMain();
42 | std::cout << "After JustHelloFunMain\n" << std::endl;
43 |
44 | std::cout << "Before constructors" << std::endl;
45 | B b;
46 | C c;
47 | std::cout << "After constructors\n" << std::endl;
48 |
49 | std::cout << "Before member functions" << std::endl;
50 | b.Speak();
51 | c.Speak();
52 | std::cout << "After member functions\n" << std::endl;
53 |
54 | std::cout << "Before CallSpeak" << std::endl;
55 | CallSpeak(&b);
56 | CallSpeak(&c);
57 | std::cout << "After CallSpeak" << std::endl;
58 | return 0;
59 | }
60 |
--------------------------------------------------------------------------------
/feature_unit_tests/inheritance-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-g++-aarch64/return.cc:
--------------------------------------------------------------------------------
1 | int main() {
2 | return 0;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | aarch64-linux-gnu-g++ return.cc -o return.out
4 | $(git rev-parse --show-toplevel)/build/sold return.out -o return.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
5 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./return.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-g++/return.cc:
--------------------------------------------------------------------------------
1 | int main() {
2 | return 0;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | g++ return.cc -o return.out
4 | $(git rev-parse --show-toplevel)/build/sold return.out -o return.soldout --section-headers --check-output
5 | ./return.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | return
2 | return.out
3 | return.soldout
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc-aarch64/return.c:
--------------------------------------------------------------------------------
1 | int main() {
2 | return 0;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | aarch64-linux-gnu-gcc return.c -o return.out
4 | $(git rev-parse --show-toplevel)/build/sold return.out -o return.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
5 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./return.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | return.c
2 | test.sh
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc/return.c:
--------------------------------------------------------------------------------
1 | int main() {
2 | return 0;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/just-return-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | gcc return.c -o return.out
4 | $(git rev-parse --show-toplevel)/build/sold return.out -o return.soldout --section-headers --check-output
5 | ./return.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | base.so
2 | main
3 | mprotect_check.so
4 | mprotect_check.so.original
5 | mprotect_check.so.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/base.c:
--------------------------------------------------------------------------------
1 |
2 | int func(int a, int b) {
3 | return a + b;
4 | }
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/base.h:
--------------------------------------------------------------------------------
1 | int func(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include "mprotect_check.h"
2 |
3 | int main() {
4 | check();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/mprotect_check.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "base.h"
4 |
5 | void check() {
6 | int x = func(1, 2);
7 | char str[1024];
8 | FILE* fp = fopen("/proc/self/maps", "r");
9 | while ((fgets(str, 256, fp)) != NULL) {
10 | printf("%s", str);
11 | }
12 | fclose(fp);
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/mprotect_check.h:
--------------------------------------------------------------------------------
1 | void check();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | aarch64-linux-gnu-gcc -shared -fPIC base.c -o base.so -Wl,-soname,base.so
4 | aarch64-linux-gnu-gcc -shared -fPIC mprotect_check.c base.so -o mprotect_check.so
5 | aarch64-linux-gnu-gcc main.c mprotect_check.so -o main
6 |
7 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i mprotect_check.so -o mprotect_check.so.soldout --custom-library-path /usr/aarch64-linux-gnu/lib
8 | mv mprotect_check.so mprotect_check.so.original
9 | ln -sf mprotect_check.so.soldout mprotect_check.so
10 | # ln -sf mprotect_check.so.original mprotect_check.so
11 |
12 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
13 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/.gitignore:
--------------------------------------------------------------------------------
1 | base.so
2 | main
3 | mprotect_check.so
4 | mprotect_check.so.original
5 | mprotect_check.so.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/base.c:
--------------------------------------------------------------------------------
1 |
2 | int func(int a, int b) {
3 | return a + b;
4 | }
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/base.h:
--------------------------------------------------------------------------------
1 | int func(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/main.c:
--------------------------------------------------------------------------------
1 | #include "mprotect_check.h"
2 |
3 | int main() {
4 | check();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/mprotect_check.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "base.h"
4 |
5 | void check() {
6 | int x = func(1, 2);
7 | char str[1024];
8 | FILE* fp = fopen("/proc/self/maps", "r");
9 | while ((fgets(str, 256, fp)) != NULL) {
10 | printf("%s", str);
11 | }
12 | fclose(fp);
13 | }
14 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/mprotect_check.h:
--------------------------------------------------------------------------------
1 | void check();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/mprotect/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | gcc -shared -fPIC base.c -o base.so -Wl,-soname,base.so
4 | gcc -shared -fPIC mprotect_check.c base.so -o mprotect_check.so
5 | gcc main.c mprotect_check.so -o main
6 |
7 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i mprotect_check.so -o mprotect_check.so.soldout
8 | mv mprotect_check.so mprotect_check.so.original
9 | ln -sf mprotect_check.so.soldout mprotect_check.so
10 | # ln -sf mprotect_check.so.original mprotect_check.so
11 |
12 | LD_LIBRARY_PATH=. ./main
13 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/.gitignore:
--------------------------------------------------------------------------------
1 | libfugafuga.so
2 | libhoge_original.so
3 | libhoge_renamed.so
4 | libhoge.so
5 | use_fugafuga
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/fugafuga.c:
--------------------------------------------------------------------------------
1 | int fugafuga(int a, int b) {
2 | return a - b;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/hoge.c:
--------------------------------------------------------------------------------
1 | int hoge(int a, int b) {
2 | return a + b;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/mapping:
--------------------------------------------------------------------------------
1 | hoge fugafuga
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | gcc -fPIC -fpic -shared -o libhoge_original.so hoge.c -Wl,-soname,libhoge.so
4 | gcc -fPIC -fpic -shared -o libfugafuga.so fugafuga.c -Wl,-soname,libhoge.so
5 | ln -sf libfugafuga.so libhoge.so
6 | gcc -o use_fugafuga use_fugafuga.c libhoge.so
7 | ../../build/renamer libhoge_original.so --output libhoge_renamed.so --rename-mapping-file mapping
8 | ln -sf libhoge_renamed.so libhoge.so
9 | LD_LIBRARY_PATH=. ./use_fugafuga
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/renamer/use_fugafuga.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // Although `fugafuga` in fugafuga.c is subtraction, `hoge` in hoge.c is
5 | // addition. renamer renames `hoge` to `fugafuga`.
6 | int fugafuga(int a, int b);
7 |
8 | int main() {
9 | int a = fugafuga(1, 2);
10 | assert(a == 3);
11 | return 0;
12 | }
13 |
--------------------------------------------------------------------------------
/feature_unit_tests/run-all-tests.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -u
2 |
3 | unexpected_failed_tests=
4 | unexpected_succeeded_tests=
5 |
6 | # TODO(akawashiro): extern
7 | for dir in hello-g++ hello-gcc just-return-g++ just-return-gcc simple-lib-g++ simple-lib-gcc version-gcc tls-lib-gcc tls-lib-gcc-without-base tls-multiple-lib-gcc tls-thread-g++ call_once-g++ inheritance-g++ typeid-g++ dynamic_cast-g++ tls-dlopen-gcc static-in-function-g++ static-in-class-g++ tls-multiple-module-g++ exception-g++ stb_gnu_unique_tls setjmp-gcc tls-bss-gcc tls-bss-g++ hello-g++-aarch64 hello-gcc-aarch64 just-return-g++-aarch64 simple-lib-g++-aarch64 simple-lib-gcc-aarch64 version-gcc-aarch64 tls-bss-gcc-aarch64 tls-bss-g++-aarch64 just-return-gcc-aarch64 setjmp-gcc-aarch64 exception-g++-aarch64 typeid-g++-aarch64 inheritance-g++-aarch64 dynamic_cast-g++-aarch64 static-in-class-g++-aarch64 static-in-function-g++-aarch64 tls-lib-gcc-aarch64 stb_gnu_unique_tls-aarch64 tls-multiple-module-g++-aarch64 tls-dlopen-gcc-aarch64 call_once-g++-aarch64 tls-thread-g++-aarch64 tls-lib-gcc-without-base-aarch64 delete-unused-PT_DYNAMIC
8 | do
9 | pushd `pwd`
10 | cd $dir
11 | echo =========== $dir ===========
12 | ./test.sh
13 | if [ "$?" -ne 0 ];then
14 | if [ -z "${unexpected_failed_tests}" ];then
15 | unexpected_failed_tests=${dir}
16 | else
17 | unexpected_failed_tests=${unexpected_failed_tests},${dir}
18 | fi
19 | fi
20 | popd
21 | done
22 |
23 | # TODO(akawashiro): tls-multiple-lib-gcc-aarch64 fails on CI although it succeeds in containers.
24 | # for dir in tls-multiple-lib-gcc-aarch64
25 | # do
26 | # pushd `pwd`
27 | # cd $dir
28 | # echo =========== $dir ===========
29 | # ./test.sh
30 | # if [ "$?" -eq 0 ];then
31 | # if [ -z "${unexpected_succeeded_tests}" ];then
32 | # unexpected_succeeded_tests=${dir}
33 | # else
34 | # unexpected_succeeded_tests=${unexpected_succeeded_tests},${dir}
35 | # fi
36 | # fi
37 | # popd
38 | # done
39 |
40 | echo Unexpected failed tests: ${unexpected_failed_tests}
41 | echo Unexpected succeeded tests: ${unexpected_succeeded_tests}
42 |
43 | if [ -z "${unexpected_failed_tests}" ]
44 | then
45 | exit 0
46 | else
47 | exit 1
48 | fi
49 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libhoge.so
2 | libhoge.so.original
3 | libhoge.so.soldout
4 | main
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc-aarch64/hoge.c:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int counter = 0;
4 | jmp_buf buf;
5 |
6 | void setjmp_longjmp_in_function() {
7 | int x = 1;
8 | setjmp(buf); // set the jump position using buf
9 | printf("x = %d\n", x); // Prints a number
10 | x++;
11 | if (x <= 5) longjmp(buf, 1); // Jump to the point located by setjmp
12 | }
13 |
14 | void call_longjmp() {
15 | if (counter <= 5) longjmp(buf, 1); // Jump to the point located by setjmp
16 | }
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc-aarch64/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | extern int counter;
5 | extern jmp_buf buf;
6 |
7 | void setjmp_longjmp_in_function();
8 | void call_longjmp();
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int main() {
4 | printf("call setjmp_longjmp_in_function\n");
5 | setjmp_longjmp_in_function();
6 |
7 | printf("call longjmp\n");
8 | counter = 0;
9 |
10 | setjmp(buf); // set the jump position using buf
11 | printf("counter = %d\n", counter); // Prints a number
12 | counter++;
13 | call_longjmp();
14 | return 0;
15 | }
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-gcc -shared -fPIC -Wl,-soname,libhoge.so -o libhoge.so hoge.c
4 | aarch64-linux-gnu-gcc -o main main.c libhoge.so
5 |
6 | mv libhoge.so libhoge.so.original
7 | $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --custom-library-path /usr/aarch64-linux-gnu/lib
8 |
9 | # Use sold
10 | ln -sf libhoge.so.soldout libhoge.so
11 |
12 | # Use original
13 | # ln -sf lib.so.original lib.so
14 |
15 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | libhoge.so
2 | libhoge.so.original
3 | libhoge.so.soldout
4 | main
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc/hoge.c:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int counter = 0;
4 | jmp_buf buf;
5 |
6 | void setjmp_longjmp_in_function() {
7 | int x = 1;
8 | setjmp(buf); // set the jump position using buf
9 | printf("x = %d\n", x); // Prints a number
10 | x++;
11 | if (x <= 5) longjmp(buf, 1); // Jump to the point located by setjmp
12 | }
13 |
14 | void call_longjmp() {
15 | if (counter <= 5) longjmp(buf, 1); // Jump to the point located by setjmp
16 | }
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | extern int counter;
5 | extern jmp_buf buf;
6 |
7 | void setjmp_longjmp_in_function();
8 | void call_longjmp();
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | int main() {
4 | printf("call setjmp_longjmp_in_function\n");
5 | setjmp_longjmp_in_function();
6 |
7 | printf("call longjmp\n");
8 | counter = 0;
9 |
10 | setjmp(buf); // set the jump position using buf
11 | printf("counter = %d\n", counter); // Prints a number
12 | counter++;
13 | call_longjmp();
14 | return 0;
15 | }
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/setjmp-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | gcc -shared -fPIC -Wl,-soname,libhoge.so -o libhoge.so hoge.c
4 | gcc -o main main.c libhoge.so
5 |
6 | mv libhoge.so libhoge.so.original
7 | $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers
8 |
9 | # Use sold
10 | ln -sf libhoge.so.soldout libhoge.so
11 |
12 | # Use original
13 | # ln -sf lib.so.original lib.so
14 |
15 | LD_LIBRARY_PATH=. ./main
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.o
2 | libmax.so
3 | main
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++-aarch64/libmax.cc:
--------------------------------------------------------------------------------
1 | int max(int a, int b) {
2 | return (a < b) ? b : a;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++-aarch64/libmax.h:
--------------------------------------------------------------------------------
1 | int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax.h"
3 |
4 | int main() {
5 | std::cout << "max(1,2) = " << max(1, 2) << std::endl;
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o libmax.o libmax.cc
4 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so libmax.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main.out main.cc libmax.so
6 |
7 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
8 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.soldout
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.o
2 | libmax.so
3 | main
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++/libmax.cc:
--------------------------------------------------------------------------------
1 | int max(int a, int b) {
2 | return (a < b) ? b : a;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++/libmax.h:
--------------------------------------------------------------------------------
1 | int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax.h"
3 |
4 | int main() {
5 | std::cout << "max(1,2) = " << max(1, 2) << std::endl;
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o libmax.o libmax.cc
4 | g++ -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so libmax.o
5 | g++ -Wl,--hash-style=gnu -o main.out main.cc libmax.so
6 |
7 | GLOG_logtostderr=1 LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --check-output
8 | LD_LIBRARY_PATH=. ./main.soldout
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.o
2 | libmax.so
3 | main
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc-aarch64/libmax.c:
--------------------------------------------------------------------------------
1 | int max(int a, int b) {
2 | return (a < b) ? b : a;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc-aarch64/libmax.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax.h"
3 |
4 | int main() {
5 | printf("max(1,2) = %d\n", max(1, 2));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o libmax.o libmax.c
4 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so libmax.o
5 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main.out main.c libmax.so
6 |
7 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
8 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.soldout
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.o
2 | libmax.so
3 | main
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc/libmax.c:
--------------------------------------------------------------------------------
1 | int max(int a, int b) {
2 | return (a < b) ? b : a;
3 | }
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc/libmax.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax.h"
3 |
4 | int main() {
5 | printf("max(1,2) = %d\n", max(1, 2));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/simple-lib-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o libmax.o libmax.c
4 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so libmax.o
5 | gcc -Wl,--hash-style=gnu -o main.out main.c libmax.so
6 |
7 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --check-output
8 | LD_LIBRARY_PATH=. ./main.soldout
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int X::i_static = 42;
4 | double X::d_static = 42.00;
5 |
6 | double func() {
7 | X x;
8 | return x.f();
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | class X {
2 | public:
3 | double f() { return i_static + d_static; }
4 |
5 | private:
6 | static int i_static;
7 | static double d_static;
8 | };
9 |
10 | double func();
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << func() << std::endl;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int X::i_static = 42;
4 | double X::d_static = 42.00;
5 |
6 | double func() {
7 | X x;
8 | return x.f();
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++/lib.h:
--------------------------------------------------------------------------------
1 | class X {
2 | public:
3 | double f() { return i_static + d_static; }
4 |
5 | private:
6 | static int i_static;
7 | static double d_static;
8 | };
9 |
10 | double func();
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << func() << std::endl;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-class-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | main
2 | lib.so.original
3 | lib.so.soldout
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int func() {
4 | static int v = 0;
5 | v++;
6 | return v;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | int func();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << func() << std::endl;
7 | std::cout << func() << std::endl;
8 | std::cout << func() << std::endl;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -lpthread -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so -lpthread
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++/.gitignore:
--------------------------------------------------------------------------------
1 | main
2 | lib.so.original
3 | lib.so.soldout
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int func() {
4 | static int v = 0;
5 | v++;
6 | return v;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++/lib.h:
--------------------------------------------------------------------------------
1 | int func();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << func() << std::endl;
7 | std::cout << func() << std::endl;
8 | std::cout << func() << std::endl;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/static-in-function-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -lpthread -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main.out main.cc lib.so -lpthread
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. ./main.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libunique.so
2 | libunique.so.original
3 | libunique.so.soldout
4 | main
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | int fn();
2 |
3 | int main() {
4 | int x = fn();
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-g++ -std=c++17 -fPIC -shared unique.cc -o libunique.so
4 | aarch64-linux-gnu-g++ -std=c++17 -o main main.cc libunique.so
5 |
6 | mv libunique.so libunique.so.original
7 | $(git rev-parse --show-toplevel)/build/sold -i libunique.so.original -o libunique.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
8 | ln -sf libunique.so.soldout libunique.so
9 |
10 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls-aarch64/unique.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | // OK
4 | // No symbol
5 | // int inline_fn() {
6 | // thread_local int c = 0;
7 | // return c++;
8 | // }
9 |
10 | // OK
11 | // No symbol
12 | // static int inline_fn() {
13 | // thread_local int c = 0;
14 | // return c++;
15 | // }
16 |
17 | // OK
18 | // OBJECT UNIQUE
19 | // Deleted by sold
20 | // inline int inline_fn() {
21 | // static int c = 0;
22 | // return c++;
23 | // }
24 |
25 | // NG
26 | // TLS UNIQUE
27 | inline int inline_fn() {
28 | thread_local int c = 0;
29 | return c++;
30 | }
31 |
32 | // NG
33 | // TLS UNIQUE
34 | // inline thread_local int x = 10;
35 | // int inline_fn() {
36 | // return x;
37 | // }
38 |
39 | // NG
40 | // TLS UNIQUE
41 | // inline int inline_fn() {
42 | // static thread_local int c = 0;
43 | // return c++;
44 | // }
45 |
46 | int fn() {
47 | printf("%d\n", inline_fn());
48 | printf("%d\n", inline_fn());
49 | return 0;
50 | }
51 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls/.gitignore:
--------------------------------------------------------------------------------
1 | libunique.so
2 | libunique.so.original
3 | libunique.so.soldout
4 | main
5 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls/main.cc:
--------------------------------------------------------------------------------
1 | int fn();
2 |
3 | int main() {
4 | int x = fn();
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | g++ -std=c++17 -fPIC -shared unique.cc -o libunique.so
4 | g++ -std=c++17 -o main main.cc libunique.so
5 |
6 | mv libunique.so libunique.so.original
7 | $(git rev-parse --show-toplevel)/build/sold -i libunique.so.original -o libunique.so.soldout --section-headers --check-output
8 | ln -sf libunique.so.soldout libunique.so
9 |
10 | LD_LIBRARY_PATH=. ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/stb_gnu_unique_tls/unique.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | // OK
4 | // No symbol
5 | // int inline_fn() {
6 | // thread_local int c = 0;
7 | // return c++;
8 | // }
9 |
10 | // OK
11 | // No symbol
12 | // static int inline_fn() {
13 | // thread_local int c = 0;
14 | // return c++;
15 | // }
16 |
17 | // OK
18 | // OBJECT UNIQUE
19 | // Deleted by sold
20 | // inline int inline_fn() {
21 | // static int c = 0;
22 | // return c++;
23 | // }
24 |
25 | // NG
26 | // TLS UNIQUE
27 | inline int inline_fn() {
28 | thread_local int c = 0;
29 | return c++;
30 | }
31 |
32 | // NG
33 | // TLS UNIQUE
34 | // inline thread_local int x = 10;
35 | // int inline_fn() {
36 | // return x;
37 | // }
38 |
39 | // NG
40 | // TLS UNIQUE
41 | // inline int inline_fn() {
42 | // static thread_local int c = 0;
43 | // return c++;
44 | // }
45 |
46 | int fn() {
47 | printf("%d\n", inline_fn());
48 | printf("%d\n", inline_fn());
49 | return 0;
50 | }
51 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | thread_local int tls_bss_i;
4 |
5 | int main() {
6 | tls_bss_i = 2;
7 | printf("tls_bss_i = %d\n", tls_bss_i);
8 | printf("tls_bss_i = %d\n", tls_bss_i + 10);
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -o main.out main.cc
4 | $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --custom-library-path /usr/aarch64-linux-gnu/lib
5 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | thread_local int tls_bss_i;
4 |
5 | int main() {
6 | tls_bss_i = 2;
7 | printf("tls_bss_i = %d\n", tls_bss_i);
8 | printf("tls_bss_i = %d\n", tls_bss_i + 10);
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -o main.out main.cc
4 | $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers
5 | ./main.soldout
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | __thread int tls_bss_i;
4 |
5 | int main() {
6 | tls_bss_i = 2;
7 | printf("tls_bss_i = %d\n", tls_bss_i);
8 | printf("tls_bss_i = %d\n", tls_bss_i + 10);
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main.out main.c
4 |
5 | $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers --custom-library-path /usr/aarch64-linux-gnu/lib
6 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.soldout
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | __thread int tls_bss_i;
4 |
5 | int main() {
6 | tls_bss_i = 2;
7 | printf("tls_bss_i = %d\n", tls_bss_i);
8 | printf("tls_bss_i = %d\n", tls_bss_i + 10);
9 | return 0;
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-bss-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -Wl,--hash-style=gnu -o main.out main.c
4 |
5 | $(git rev-parse --show-toplevel)/build/sold main.out -o main.soldout --section-headers
6 | ./main.soldout
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-conflict-aarch64/fuga.cc:
--------------------------------------------------------------------------------
1 | thread_local int fuga;
2 | thread_local int dummy;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-conflict-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | extern thread_local int dummy;
2 | extern thread_local int fuga;
3 | thread_local int hoge;
4 |
5 | void fn() {
6 | dummy = 10;
7 | fuga = 10;
8 | }
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-conflict-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | extern thread_local int hoge;
4 | extern thread_local int fuga;
5 |
6 | int main() {
7 | hoge = 42;
8 | fuga = 10;
9 | printf("hoge = %d, fuga = %d\n", hoge, fuga);
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-conflict-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-g++ -fPIC -shared -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | aarch64-linux-gnu-g++ -fPIC -shared -o libhoge.so -Wl,-soname,libhoge.so hoge.cc libfuga.so
5 | aarch64-linux-gnu-g++ -o main main.cc libhoge.so
6 |
7 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | lib.so
2 | lib.so.original
3 | lib.so.soldout
4 | main
5 |
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc-aarch64/lib.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | __thread int tls_with_init_value = 0;
4 | __thread int tls_without_init_value;
5 |
6 | void show_tls_variables() {
7 | tls_with_init_value = 10;
8 | tls_without_init_value = 10;
9 | printf("tls_with_init_value = %d, tls_without_init_value = %d\n", tls_with_init_value, tls_without_init_value);
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main() {
5 | void* handle = dlopen("lib.so", RTLD_LAZY);
6 | if (handle != NULL) {
7 | void (*func)() = (void (*)())dlsym(handle, "show_tls_variables");
8 | func();
9 |
10 | int* tls_with_init_value_p = (int*)dlsym(handle, "tls_with_init_value");
11 | int* tls_without_init_value_p = (int*)dlsym(handle, "tls_without_init_value");
12 |
13 | printf("*tls_with_init_value_p = %d, *tls_without_init_value_p = %d\n", *tls_with_init_value_p, *tls_without_init_value_p);
14 |
15 | } else {
16 | printf("Cannot open lib.so\n");
17 | }
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o lib.o lib.c
4 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main main.c -ldl
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | lib.so
2 | lib.so.original
3 | lib.so.soldout
4 | main
5 |
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc/lib.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | __thread int tls_with_init_value = 0;
4 | __thread int tls_without_init_value;
5 |
6 | void show_tls_variables() {
7 | tls_with_init_value = 10;
8 | tls_without_init_value = 10;
9 | printf("tls_with_init_value = %d, tls_without_init_value = %d\n", tls_with_init_value, tls_without_init_value);
10 | }
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main() {
5 | void* handle = dlopen("lib.so", RTLD_LAZY);
6 | if (handle != NULL) {
7 | void (*func)() = (void (*)())dlsym(handle, "show_tls_variables");
8 | func();
9 |
10 | int* tls_with_init_value_p = (int*)dlsym(handle, "tls_with_init_value");
11 | int* tls_without_init_value_p = (int*)dlsym(handle, "tls_without_init_value");
12 |
13 | printf("*tls_with_init_value_p = %d, *tls_without_init_value_p = %d\n", *tls_with_init_value_p, *tls_without_init_value_p);
14 |
15 | } else {
16 | printf("Cannot open lib.so\n");
17 | }
18 | return 0;
19 | }
20 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-dlopen-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o lib.o lib.c
4 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | gcc -Wl,--hash-style=gnu -o main main.c -ldl
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. ./main
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // thread_local int tls_bss_i;
5 | static int global_x;
6 | thread_local int tls_data_j = 3;
7 |
8 | int main() {
9 | // tls_bss_i = 2;
10 | // printf("tls_bss_i = %d\n", tls_bss_i);
11 | global_x = 2;
12 | printf("global_x = %d\n", global_x);
13 | printf("tls_data_j = %d\n", tls_data_j);
14 | return 0;
15 | }
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main main.c
4 |
5 | $(git rev-parse --show-toplevel)/build/sold main -o main.out --section-headers --custom-library-path /usr/aarch64-linux-gnu/lib
6 | qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // thread_local int tls_bss_i;
5 | static int global_x;
6 | thread_local int tls_data_j = 3;
7 |
8 | int main() {
9 | // tls_bss_i = 2;
10 | // printf("tls_bss_i = %d\n", tls_bss_i);
11 | global_x = 2;
12 | printf("global_x = %d\n", global_x);
13 | printf("tls_data_j = %d\n", tls_data_j);
14 | return 0;
15 | }
16 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -Wl,--hash-style=gnu -o main main.c
4 |
5 | $(git rev-parse --show-toplevel)/build/sold main -o main.out --section-headers
6 | ./main.out
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/answer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-aarch64/answer/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/base.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_i = 3;
2 | __thread int thread_local_j;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 | extern __thread int thread_local_j;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/lib.c:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | int return_tls_i();
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("i = %d\n", return_tls_i());
6 | thread_local_j = 3;
7 | printf("j = %d\n", thread_local_j);
8 | return 0;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-aarch64/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-aarch64/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o lib.o lib.c
4 | aarch64-linux-gnu-gcc -fPIC -c -o base.o base.c
5 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
6 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base.so
7 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o answer/lib.so lib.o base.o
8 |
9 | # Without sold
10 | # LD_LIBRARY_PATH=original gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base.so
11 | # LD_LIBRARY_PATH=original ./main.out
12 |
13 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --check-output aarch64-linux-gnu-gcc
14 |
15 | LD_LIBRARY_PATH=sold_out aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main.out main.c sold_out/lib.so
16 | LD_LIBRARY_PATH=sold_out qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
17 |
18 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/base.c:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | __thread int thread_local_i = 3;
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/lib.c:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | int return_tls_i();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("j = %d\n", return_tls_i());
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-without-base-aarch64/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-without-base-aarch64/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o lib.o lib.c
4 | aarch64-linux-gnu-gcc -fPIC -c -o base.o base.c
5 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
6 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base.so
7 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base.so
8 |
9 | cp original/base.so sold_out/base.so
10 |
11 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --exclude-so base.so --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
12 | LD_LIBRARY_PATH=sold_out qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
13 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/base.c:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | __thread int thread_local_i = 3;
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/lib.c:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/lib.h:
--------------------------------------------------------------------------------
1 | int return_tls_i();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("j = %d\n", return_tls_i());
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-without-base/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc-without-base/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc-without-base/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o lib.o lib.c
4 | gcc -fPIC -c -o base.o base.c
5 |
6 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
7 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base.so
8 |
9 | gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base.so
10 |
11 | cp original/base.so sold_out/base.so
12 |
13 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --exclude-so base.so --check-output
14 | LD_LIBRARY_PATH=sold_out ./main.out
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/answer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc/answer/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/base.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_i = 3;
2 | __thread int thread_local_j;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 | extern __thread int thread_local_j;
3 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/lib.c:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/lib.h:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 |
3 | int return_tls_i();
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("i = %d\n", return_tls_i());
6 | thread_local_j = 3;
7 | printf("j = %d\n", thread_local_j);
8 | return 0;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-lib-gcc/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-lib-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o lib.o lib.c
4 | gcc -fPIC -c -o base.o base.c
5 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
6 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base.so
7 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o answer/lib.so lib.o base.o
8 |
9 | # Without sold
10 | # LD_LIBRARY_PATH=original gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base.so
11 | # LD_LIBRARY_PATH=original ./main.out
12 |
13 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --check-output
14 |
15 | LD_LIBRARY_PATH=sold_out gcc -Wl,--hash-style=gnu -o main.out main.c sold_out/lib.so
16 | LD_LIBRARY_PATH=sold_out ./main.out
17 |
18 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/answer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-multiple-lib-gcc-aarch64/answer/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/base.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_i = 3;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/base2.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_j = 100;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/base2.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_j;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/lib.c:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
7 | int return_tls_j() {
8 | return thread_local_j;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 | #include "base2.h"
3 |
4 | int return_tls_i();
5 | int return_tls_j();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("i = %d\n", return_tls_i());
6 | printf("j = %d\n", return_tls_j());
7 | return 0;
8 | }
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-multiple-lib-gcc-aarch64/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o base.o base.c
4 | aarch64-linux-gnu-gcc -fPIC -c -o base2.o base2.c
5 | aarch64-linux-gnu-gcc -fPIC -c -o lib.o lib.c
6 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
7 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base2.so -o original/base2.so base2.o
8 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base2.so original/base.so
9 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o answer/lib.so lib.o base2.o base.o
10 |
11 | # Without sold
12 | # LD_LIBRARY_PATH=original gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base2.so original/base.so
13 | # LD_LIBRARY_PATH=original ./main.out
14 |
15 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
16 |
17 | LD_LIBRARY_PATH=sold_out aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o main.out main.c sold_out/lib.so
18 | LD_LIBRARY_PATH=sold_out qemu-aarch64 -L /usr/aarch64-linux-gnu ./main.out
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/answer/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-multiple-lib-gcc/answer/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/base.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_i = 3;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/base.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_i;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/base2.c:
--------------------------------------------------------------------------------
1 | __thread int thread_local_j = 100;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/base2.h:
--------------------------------------------------------------------------------
1 | extern __thread int thread_local_j;
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/lib.c:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int return_tls_i() {
4 | return thread_local_i;
5 | }
6 |
7 | int return_tls_j() {
8 | return thread_local_j;
9 | }
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/lib.h:
--------------------------------------------------------------------------------
1 | #include "base.h"
2 | #include "base2.h"
3 |
4 | int return_tls_i();
5 | int return_tls_j();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "lib.h"
3 |
4 | int main() {
5 | printf("i = %d\n", return_tls_i());
6 | printf("j = %d\n", return_tls_j());
7 | return 0;
8 | }
9 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/original/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-multiple-lib-gcc/original/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/sold_out/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/akawashiro/sold/3ef99b72cf319481269e2e9adc473ef2ea8dcabe/feature_unit_tests/tls-multiple-lib-gcc/sold_out/.gitkeep
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-lib-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o base.o base.c
4 | gcc -fPIC -c -o base2.o base2.c
5 | gcc -fPIC -c -o lib.o lib.c
6 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base.so -o original/base.so base.o
7 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,base2.so -o original/base2.so base2.o
8 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o original/lib.so lib.o original/base2.so original/base.so
9 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o answer/lib.so lib.o base2.o base.o
10 |
11 | # Without sold
12 | # LD_LIBRARY_PATH=original gcc -Wl,--hash-style=gnu -o main.out main.c original/lib.so original/base2.so original/base.so
13 | # LD_LIBRARY_PATH=original ./main.out
14 |
15 | LD_LIBRARY_PATH=original $(git rev-parse --show-toplevel)/build/sold original/lib.so -o sold_out/lib.so --section-headers --check-output
16 |
17 | LD_LIBRARY_PATH=sold_out gcc -Wl,--hash-style=gnu -o main.out main.c sold_out/lib.so
18 | LD_LIBRARY_PATH=sold_out ./main.out
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libfugahoge.so.original
2 | libfugahoge.so.soldout
3 | libfuga.so
4 | libhoge.so
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/fuga.cc:
--------------------------------------------------------------------------------
1 | #include "fuga.h"
2 |
3 | namespace {
4 | thread_local uint64_t fuga_data = 0xDEADBEEFDEADBEEF;
5 | thread_local uint64_t fuga_bss;
6 | } // namespace
7 |
8 | uint64_t get_fuga_data() {
9 | return fuga_data;
10 | }
11 |
12 | uint64_t get_fuga_bss() {
13 | return fuga_bss;
14 | }
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/fuga.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void show_fuga();
4 | uint64_t get_fuga_data();
5 | uint64_t get_fuga_bss();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/fugahoge.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "fuga.h"
6 | #include "hoge.h"
7 |
8 | extern "C" void show_fuga_hoge() {
9 | uint64_t fuga_data = get_fuga_data();
10 | uint64_t fuga_bss = get_fuga_bss();
11 | uint64_t hoge_data = get_hoge_data();
12 | uint64_t hoge_bss = get_hoge_bss();
13 |
14 | std::cout << std::hex << "fuga_data = " << fuga_data << ", fuga_bss = " << fuga_bss << std::endl
15 | << "hoge_data = " << hoge_data << ", hoge_bss = " << hoge_bss << std::endl;
16 |
17 | assert(fuga_data == 0xDEADBEEFDEADBEEF && fuga_bss == 0 && hoge_data == 0xABCDEFABCDEFABCD && hoge_bss == 0);
18 | }
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | namespace {
4 | thread_local uint64_t hoge_data = 0xABCDEFABCDEFABCD;
5 | thread_local uint64_t hoge_bss;
6 | } // namespace
7 |
8 | uint64_t get_hoge_data() {
9 | return hoge_data;
10 | }
11 |
12 | uint64_t get_hoge_bss() {
13 | return hoge_bss;
14 | }
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void show_hoge();
4 | uint64_t get_hoge_data();
5 | uint64_t get_hoge_bss();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << "---------- libfugahoge.so.original ----------" << std::endl;
7 | void* handle = dlopen("./libfugahoge.so.original", RTLD_LAZY);
8 | if (handle == NULL) {
9 | std::cout << "Cannot find libfugahoge.so.original" << std::endl;
10 | return 0;
11 | }
12 | int (*show_fuga_hoge)() = (int (*)())dlsym(handle, "show_fuga_hoge");
13 | if (show_fuga_hoge == NULL) {
14 | std::cout << "Cannot find show_fuga_hoge" << std::endl;
15 | return 0;
16 | }
17 | show_fuga_hoge();
18 |
19 | std::cout << "---------- libfugahoge.so.soldout ----------" << std::endl;
20 | handle = dlopen("./libfugahoge.so.soldout", RTLD_LAZY);
21 | if (handle == NULL) {
22 | std::cout << "Cannot find libfugahoge.so.soldout" << std::endl;
23 | return 0;
24 | }
25 | show_fuga_hoge = (int (*)())dlsym(handle, "show_fuga_hoge");
26 | if (show_fuga_hoge == NULL) {
27 | std::cout << "Cannot find show_fuga_hoge" << std::endl;
28 | return 0;
29 | }
30 | show_fuga_hoge();
31 | return 0;
32 | }
33 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -shared -fPIC -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | aarch64-linux-gnu-g++ -shared -fPIC -o libhoge.so -Wl,-soname,libhoge.so hoge.cc
5 | aarch64-linux-gnu-g++ -shared -fPIC -o libfugahoge.so.original fugahoge.cc libfuga.so libhoge.so
6 | aarch64-linux-gnu-g++ -o main main.cc -ldl
7 |
8 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libfugahoge.so.original -o libfugahoge.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/.gitignore:
--------------------------------------------------------------------------------
1 | libfugahoge.so.original
2 | libfugahoge.so.soldout
3 | libfuga.so
4 | libhoge.so
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/fuga.cc:
--------------------------------------------------------------------------------
1 | #include "fuga.h"
2 |
3 | namespace {
4 | thread_local uint64_t fuga_data = 0xDEADBEEFDEADBEEF;
5 | thread_local uint64_t fuga_bss;
6 | } // namespace
7 |
8 | uint64_t get_fuga_data() {
9 | return fuga_data;
10 | }
11 |
12 | uint64_t get_fuga_bss() {
13 | return fuga_bss;
14 | }
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/fuga.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void show_fuga();
4 | uint64_t get_fuga_data();
5 | uint64_t get_fuga_bss();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/fugahoge.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | #include "fuga.h"
6 | #include "hoge.h"
7 |
8 | extern "C" void show_fuga_hoge() {
9 | uint64_t fuga_data = get_fuga_data();
10 | uint64_t fuga_bss = get_fuga_bss();
11 | uint64_t hoge_data = get_hoge_data();
12 | uint64_t hoge_bss = get_hoge_bss();
13 |
14 | std::cout << std::hex << "fuga_data = " << fuga_data << ", fuga_bss = " << fuga_bss << std::endl
15 | << "hoge_data = " << hoge_data << ", hoge_bss = " << hoge_bss << std::endl;
16 |
17 | assert(fuga_data == 0xDEADBEEFDEADBEEF && fuga_bss == 0 && hoge_data == 0xABCDEFABCDEFABCD && hoge_bss == 0);
18 | }
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/hoge.cc:
--------------------------------------------------------------------------------
1 | #include "hoge.h"
2 |
3 | namespace {
4 | thread_local uint64_t hoge_data = 0xABCDEFABCDEFABCD;
5 | thread_local uint64_t hoge_bss;
6 | } // namespace
7 |
8 | uint64_t get_hoge_data() {
9 | return hoge_data;
10 | }
11 |
12 | uint64_t get_hoge_bss() {
13 | return hoge_bss;
14 | }
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/hoge.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | void show_hoge();
4 | uint64_t get_hoge_data();
5 | uint64_t get_hoge_bss();
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 |
5 | int main() {
6 | std::cout << "---------- libfugahoge.so.original ----------" << std::endl;
7 | void* handle = dlopen("./libfugahoge.so.original", RTLD_LAZY);
8 | if (handle == NULL) {
9 | std::cout << "Cannot find libfugahoge.so.original" << std::endl;
10 | return 0;
11 | }
12 | int (*show_fuga_hoge)() = (int (*)())dlsym(handle, "show_fuga_hoge");
13 | if (show_fuga_hoge == NULL) {
14 | std::cout << "Cannot find show_fuga_hoge" << std::endl;
15 | return 0;
16 | }
17 | show_fuga_hoge();
18 |
19 | std::cout << "---------- libfugahoge.so.soldout ----------" << std::endl;
20 | handle = dlopen("./libfugahoge.so.soldout", RTLD_LAZY);
21 | if (handle == NULL) {
22 | std::cout << "Cannot find libfugahoge.so.soldout" << std::endl;
23 | return 0;
24 | }
25 | show_fuga_hoge = (int (*)())dlsym(handle, "show_fuga_hoge");
26 | if (show_fuga_hoge == NULL) {
27 | std::cout << "Cannot find show_fuga_hoge" << std::endl;
28 | return 0;
29 | }
30 | show_fuga_hoge();
31 | return 0;
32 | }
33 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-multiple-module-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -shared -fPIC -o libfuga.so -Wl,-soname,libfuga.so fuga.cc
4 | g++ -shared -fPIC -o libhoge.so -Wl,-soname,libhoge.so hoge.cc
5 | g++ -shared -fPIC -o libfugahoge.so.original fugahoge.cc libfuga.so libhoge.so
6 | g++ -o main main.cc -ldl
7 |
8 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -i libfugahoge.so.original -o libfugahoge.so.soldout --section-headers --check-output
9 |
10 | LD_LIBRARY_PATH=. ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | main
2 | lib.so.original
3 | lib.so.soldout
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int create_id() {
4 | thread_local int current_id = 0;
5 | return current_id++;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int create_id();
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "lib.h"
4 |
5 | int main() {
6 | int t1_id1, t1_id2;
7 | std::thread t1([&t1_id1, &t1_id2] {
8 | t1_id1 = create_id();
9 | t1_id2 = create_id();
10 | });
11 |
12 | int t2_id1, t2_id2;
13 | std::thread t2([&t2_id1, &t2_id2] {
14 | t2_id1 = create_id();
15 | t2_id2 = create_id();
16 | });
17 |
18 | t1.join();
19 | t2.join();
20 |
21 | std::cout << "t1_id1=" << t1_id1 << " t1_id2=" << t1_id2 << " t2_id1=" << t2_id1 << " t2_id2=" << t2_id2 << std::endl;
22 | }
23 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -lpthread -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main main.cc lib.so -lpthread
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 |
13 | # Use original
14 | # ln -sf lib.so.original lib.so
15 |
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++/.gitignore:
--------------------------------------------------------------------------------
1 | main
2 | lib.so.original
3 | lib.so.soldout
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int create_id() {
4 | thread_local int current_id = 0;
5 | return current_id++;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++/lib.h:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int create_id();
4 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "lib.h"
4 |
5 | int main() {
6 | int t1_id1, t1_id2;
7 | std::thread t1([&t1_id1, &t1_id2] {
8 | t1_id1 = create_id();
9 | t1_id2 = create_id();
10 | });
11 |
12 | int t2_id1, t2_id2;
13 | std::thread t2([&t2_id1, &t2_id2] {
14 | t2_id1 = create_id();
15 | t2_id2 = create_id();
16 | });
17 |
18 | t1.join();
19 | t2.join();
20 |
21 | std::cout << "t1_id1=" << t1_id1 << " t1_id2=" << t1_id2 << " t2_id1=" << t2_id1 << " t2_id2=" << t2_id2 << std::endl;
22 | }
23 |
--------------------------------------------------------------------------------
/feature_unit_tests/tls-thread-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -lpthread -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main main.cc lib.so -lpthread
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 | # $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers
10 |
11 | # Use sold
12 | ln -sf lib.so.soldout lib.so
13 |
14 | # Use original
15 | # ln -sf lib.so.original lib.so
16 |
17 | LD_LIBRARY_PATH=. ./main
18 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | lib.o
2 | lib.so
3 | lib.so.original
4 | lib.so.soldout
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/fuga.h:
--------------------------------------------------------------------------------
1 | struct BaseFuga {
2 | public:
3 | virtual void f() {}
4 | };
5 |
6 | struct DerivedFuga : public BaseFuga {};
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/lib.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class Base {
5 | public:
6 | virtual void f() {}
7 | };
8 |
9 | class Derived : public Base {};
10 |
11 | void PrintTypeid() {
12 | Base b;
13 | Derived d;
14 | Base* p1 = &b;
15 | Base* p2 = &d;
16 |
17 | std::cout << typeid(b).name() << "\n"
18 | << typeid(d).name() << "\n"
19 | << typeid(p1).name() << "\n"
20 | << typeid(*p1).name() << "\n"
21 | << typeid(p2).name() << "\n"
22 | << typeid(*p2).name() << std::endl;
23 | }
24 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/lib.h:
--------------------------------------------------------------------------------
1 | void PrintTypeid();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int main() {
4 | PrintTypeid();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-g++ -fPIC -c -o lib.o lib.cc
4 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | aarch64-linux-gnu-g++ -Wl,--hash-style=gnu -o main main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 | echo ----------- Use sold -----------
13 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
14 |
15 | # Use original
16 | ln -sf lib.so.original lib.so
17 | echo ----------- Use original -----------
18 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++/.gitignore:
--------------------------------------------------------------------------------
1 | lib.o
2 | lib.so
3 | lib.so.original
4 | lib.so.soldout
5 | main
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++/lib.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | class Base {
5 | public:
6 | virtual void f() {}
7 | };
8 |
9 | class Derived : public Base {};
10 |
11 | void PrintTypeid() {
12 | Base b;
13 | Derived d;
14 | Base* p1 = &b;
15 | Base* p2 = &d;
16 |
17 | std::cout << typeid(b).name() << "\n"
18 | << typeid(d).name() << "\n"
19 | << typeid(p1).name() << "\n"
20 | << typeid(*p1).name() << "\n"
21 | << typeid(p2).name() << "\n"
22 | << typeid(*p2).name() << std::endl;
23 | }
24 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++/lib.h:
--------------------------------------------------------------------------------
1 | void PrintTypeid();
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++/main.cc:
--------------------------------------------------------------------------------
1 | #include "lib.h"
2 |
3 | int main() {
4 | PrintTypeid();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/typeid-g++/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | g++ -fPIC -c -o lib.o lib.cc
4 | g++ -Wl,--hash-style=gnu -shared -Wl,-soname,lib.so -o lib.so lib.o
5 | g++ -Wl,--hash-style=gnu -o main main.cc lib.so
6 |
7 | mv lib.so lib.so.original
8 | $(git rev-parse --show-toplevel)/build/sold -i lib.so.original -o lib.so.soldout --section-headers --check-output
9 |
10 | # Use sold
11 | ln -sf lib.so.soldout lib.so
12 | echo ----------- Use sold -----------
13 | LD_LIBRARY_PATH=. ./main
14 |
15 | # Use original
16 | ln -sf lib.so.original lib.so
17 | echo ----------- Use original -----------
18 | LD_LIBRARY_PATH=. ./main
19 |
--------------------------------------------------------------------------------
/feature_unit_tests/unique_ptr-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libhoge.so
2 | libhoge.so.original
3 | libhoge.so.soldout
4 | main
5 | sold.*
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/unique_ptr-aarch64/hoge.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | struct X {
5 | X(int v) : var(v){};
6 | int var;
7 | int fn() { return var; }
8 | };
9 |
10 | void fn() {
11 | auto up = std::make_unique(42);
12 | auto p = up.release();
13 | printf("%d\n", p->fn());
14 | }
15 |
--------------------------------------------------------------------------------
/feature_unit_tests/unique_ptr-aarch64/main.cc:
--------------------------------------------------------------------------------
1 | void fn();
2 |
3 | int main() {
4 | fn();
5 | }
6 |
--------------------------------------------------------------------------------
/feature_unit_tests/unique_ptr-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | aarch64-linux-gnu-g++ -fPIC -shared -o libhoge.so -Wl,-soname,libhoge.so hoge.cc
4 | aarch64-linux-gnu-g++ -o main main.cc libhoge.so
5 |
6 | mv libhoge.so libhoge.so.original
7 | GLOG_log_dir=. $(git rev-parse --show-toplevel)/build/sold -i libhoge.so.original -o libhoge.so.soldout --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
8 | ln -sf libhoge.so.soldout libhoge.so
9 |
10 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./main
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.so
2 | libmax.so.1
3 | libmax.so.2
4 | libmax1.o
5 | libmax2.o
6 | vertest1
7 | vertest1.out
8 | vertest2
9 | vertest2.out
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/libmax1.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int max(int a, int b) {
4 | printf("max__1 @ libmax1\n");
5 | return (a > b ? a : b);
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/libmax1.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/libmax2.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int max__1(int a, int b) {
4 | printf("max__1 @ libmax2\n");
5 | return (a > b ? a : b);
6 | }
7 |
8 | int max__2(int a, int b, int c) {
9 | printf("max__2 @ libmax2\n");
10 | int r = a > b ? a : b;
11 | r = r > c ? r : c;
12 | return r;
13 | }
14 |
15 | __asm__(".symver max__1,max@LIBMAX_1.0");
16 | __asm__(".symver max__2,max@@LIBMAX_2.0");
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/libmax2.def:
--------------------------------------------------------------------------------
1 | LIBMAX_1.0{
2 | global:
3 | max*;
4 | local: *;
5 | };
6 | LIBMAX_2.0{
7 | global:
8 | max*;
9 | local: *;
10 | } LIBMAX_1.0;
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/libmax2.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b, int c);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | aarch64-linux-gnu-gcc -fPIC -c -o libmax1.o libmax1.c
4 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so.1 libmax1.o
5 | ln -sf libmax.so.1 libmax.so
6 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o vertest1 vertest1.c libmax.so
7 |
8 | aarch64-linux-gnu-gcc -fPIC -c -o libmax2.o libmax2.c
9 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -Wl,--version-script,libmax2.def -o libmax.so.2 libmax2.o
10 | ln -sf libmax.so.2 libmax.so
11 | aarch64-linux-gnu-gcc -Wl,--hash-style=gnu -o vertest2 vertest2.c libmax.so
12 |
13 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -e libmax.so -o vertest1.out vertest1 --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
14 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./vertest1.out
15 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -e libmax.so -o vertest2.out vertest2 --section-headers --check-output --custom-library-path /usr/aarch64-linux-gnu/lib
16 | LD_LIBRARY_PATH=. qemu-aarch64 -L /usr/aarch64-linux-gnu ./vertest2.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/vertest1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax1.h"
3 |
4 | int main(void) {
5 | printf("max(1,2) = %d\n", max(1, 2));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc-aarch64/vertest2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax2.h"
3 |
4 | int main(void) {
5 | printf("max(1, 2, 3) = %d\n", max(1, 2, 3));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/.gitignore:
--------------------------------------------------------------------------------
1 | libmax.so
2 | libmax.so.1
3 | libmax.so.2
4 | libmax1.o
5 | libmax2.o
6 | vertest1
7 | vertest1.out
8 | vertest2
9 | vertest2.out
10 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/libmax1.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int max(int a, int b) {
4 | printf("max__1 @ libmax1\n");
5 | return (a > b ? a : b);
6 | }
7 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/libmax1.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/libmax2.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int max__1(int a, int b) {
4 | printf("max__1 @ libmax2\n");
5 | return (a > b ? a : b);
6 | }
7 |
8 | int max__2(int a, int b, int c) {
9 | printf("max__2 @ libmax2\n");
10 | int r = a > b ? a : b;
11 | r = r > c ? r : c;
12 | return r;
13 | }
14 |
15 | __asm__(".symver max__1,max@LIBMAX_1.0");
16 | __asm__(".symver max__2,max@@LIBMAX_2.0");
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/libmax2.def:
--------------------------------------------------------------------------------
1 | LIBMAX_1.0{
2 | global:
3 | max*;
4 | local: *;
5 | };
6 | LIBMAX_2.0{
7 | global:
8 | max*;
9 | local: *;
10 | } LIBMAX_1.0;
11 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/libmax2.h:
--------------------------------------------------------------------------------
1 | extern int max(int a, int b, int c);
2 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | gcc -fPIC -c -o libmax1.o libmax1.c
4 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -o libmax.so.1 libmax1.o
5 | ln -sf libmax.so.1 libmax.so
6 | gcc -Wl,--hash-style=gnu -o vertest1 vertest1.c libmax.so
7 |
8 | gcc -fPIC -c -o libmax2.o libmax2.c
9 | gcc -Wl,--hash-style=gnu -shared -Wl,-soname,libmax.so -Wl,--version-script,libmax2.def -o libmax.so.2 libmax2.o
10 | ln -sf libmax.so.2 libmax.so
11 | gcc -Wl,--hash-style=gnu -o vertest2 vertest2.c libmax.so
12 |
13 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -e libmax.so -o vertest1.out vertest1 --section-headers --check-output
14 | LD_LIBRARY_PATH=. ./vertest1.out
15 | LD_LIBRARY_PATH=. $(git rev-parse --show-toplevel)/build/sold -e libmax.so -o vertest2.out vertest2 --section-headers --check-output
16 | LD_LIBRARY_PATH=. ./vertest2.out
17 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/vertest1.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax1.h"
3 |
4 | int main(void) {
5 | printf("max(1,2) = %d\n", max(1, 2));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/feature_unit_tests/version-gcc/vertest2.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "libmax2.h"
3 |
4 | int main(void) {
5 | printf("max(1, 2, 3) = %d\n", max(1, 2, 3));
6 | return 0;
7 | }
8 |
--------------------------------------------------------------------------------
/fedora-latest.Dockerfile:
--------------------------------------------------------------------------------
1 | FROM fedora:34
2 | RUN dnf install -y ninja-build cmake gcc g++ git libstdc++ python3 python3-devel python3-pip rsync
3 | RUN pip3 install numpy pytest
4 | COPY . /sold
5 | WORKDIR /sold
6 | RUN rm -rf build
7 | RUN mkdir build && cd build && cmake -GNinja -DSOLD_PYBIND_TEST=ON ..
8 | RUN cmake --build build
9 | RUN cd build && ctest
10 |
--------------------------------------------------------------------------------
/hash.cc:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #include "hash.h"
17 |
18 | uint32_t CalcGnuHash(const std::string& name) {
19 | uint32_t h = 5381;
20 | for (unsigned char c : name) {
21 | h = h * 33 + c;
22 | }
23 | return h;
24 | }
25 |
26 | uint32_t CalcHash(const std::string& name) {
27 | uint32_t h = 0, g;
28 | for (unsigned char c : name) {
29 | h = (h << 4) + c;
30 | g = h & 0xf0000000;
31 | h ^= g >> 24;
32 | h ^= g;
33 | }
34 | return h;
35 | }
36 |
--------------------------------------------------------------------------------
/hash.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #pragma once
17 |
18 | #include "utils.h"
19 |
20 | struct Elf_GnuHash {
21 | uint32_t nbuckets{0};
22 | uint32_t symndx{0};
23 | uint32_t maskwords{0};
24 | uint32_t shift2{0};
25 | uint8_t tail[1];
26 |
27 | Elf_Addr* bloom_filter() { return reinterpret_cast(tail); }
28 |
29 | uint32_t* buckets() { return reinterpret_cast(&bloom_filter()[maskwords]); }
30 |
31 | uint32_t* hashvals() { return reinterpret_cast(&buckets()[nbuckets]); }
32 | };
33 |
34 | uint32_t CalcGnuHash(const std::string& name);
35 |
36 | uint32_t CalcHash(const std::string& name);
37 |
38 | struct Elf_Hash {
39 | uint32_t nbuckets{0};
40 | uint32_t nchains{0};
41 | uint8_t tail[1];
42 |
43 | const uint32_t* buckets() const { return reinterpret_cast(tail); }
44 |
45 | const uint32_t* chains() const { return buckets() + nbuckets; }
46 | };
47 |
--------------------------------------------------------------------------------
/ldsoconf.cc:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #include "ldsoconf.h"
17 |
18 | #include
19 |
20 | #include
21 |
22 | namespace ldsoconf {
23 | namespace {
24 | void read_ldsoconf_dfs(std::vector& res, const std::string& filename) {
25 | std::ifstream f;
26 | f.open(filename);
27 | if (!f) {
28 | return;
29 | }
30 | std::string head;
31 | while (f >> head) {
32 | if (head.substr(0, 1) == "#") {
33 | std::string comment;
34 | std::getline(f, comment);
35 | } else if (head == "include") {
36 | std::string descendants;
37 | f >> descendants;
38 |
39 | glob_t globbuf;
40 | glob(descendants.c_str(), 0, NULL, &globbuf);
41 | for (int i = 0; i < globbuf.gl_pathc; i++) {
42 | read_ldsoconf_dfs(res, globbuf.gl_pathv[i]);
43 | }
44 | globfree(&globbuf);
45 | } else {
46 | res.push_back(head);
47 | }
48 | }
49 | }
50 |
51 | } // namespace
52 |
53 | std::vector read_ldsoconf() {
54 | std::vector res;
55 | read_ldsoconf_dfs(res, "/etc/ld.so.conf");
56 |
57 | return res;
58 | }
59 | } // namespace ldsoconf
60 |
--------------------------------------------------------------------------------
/ldsoconf.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #pragma once
17 |
18 | #include
19 | #include
20 |
21 | namespace ldsoconf {
22 | std::vector read_ldsoconf();
23 | }
24 |
--------------------------------------------------------------------------------
/libtorch_test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4)
2 | project(torch-test LANGUAGES CXX)
3 |
4 | set(CMAKE_CXX_STANDARD 14)
5 | set(CMAKE_CXX_STANDARD_REQUIRED ON)
6 |
7 | if(NOT CMAKE_BUILD_TYPE)
8 | set(CMAKE_BUILD_TYPE "RelWithDebInfo")
9 | endif()
10 |
11 | find_package(Torch REQUIRED)
12 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
13 |
14 | add_library(torch_test SHARED torch_test.cc)
15 | target_link_libraries(torch_test PRIVATE "${TORCH_LIBRARIES}"
16 | -Wl,-soname,libtorch_test.so)
17 | set_target_properties(torch_test PROPERTIES SUFFIX ".so.original")
18 |
19 | add_custom_target(
20 | torch_test_soldout ALL
21 | COMMAND
22 | GLOG_log_dir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/sold -i
23 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.original -o
24 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.soldout --section-headers
25 | --check-output && ln -sf libtorch_test.so.soldout libtorch_test.so
26 | DEPENDS torch_test sold
27 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
28 |
29 | add_custom_target(
30 | torch_test_soldout_wo_section
31 | EXCLUDE_FROM_ALL
32 | COMMAND
33 | GLOG_log_dir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR}/sold -i
34 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.original -o
35 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.wosection.soldout
36 | --check-output
37 | DEPENDS torch_test sold
38 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
39 |
40 | add_custom_target(
41 | torch_test_main ALL
42 | COMMAND
43 | g++ ${CMAKE_CURRENT_SOURCE_DIR}/torch_test_main.cc
44 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.original -o torch_test_main
45 | DEPENDS torch_test
46 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
47 |
48 | add_custom_target(
49 | torch_test_main_linked_soldout
50 | EXCLUDE_FROM_ALL
51 | COMMAND
52 | g++ ${CMAKE_CURRENT_SOURCE_DIR}/torch_test_main.cc
53 | ${CMAKE_CURRENT_BINARY_DIR}/libtorch_test.so.soldout -o
54 | torch_test_main_linked_sold
55 | DEPENDS torch_test_soldout
56 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
57 |
58 | add_executable(torch_test_main_dlopen torch_test_main_dlopen.cc)
59 | target_link_libraries(torch_test_main_dlopen PRIVATE -ldl)
60 |
61 | add_test(
62 | NAME libtorch_test
63 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
64 | COMMAND ./torch_test_main)
65 | set_tests_properties(
66 | libtorch_test PROPERTIES ENVIRONMENT
67 | "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}")
68 | add_test(
69 | NAME libtorch_test_dlopen
70 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
71 | COMMAND ./torch_test_main_dlopen)
72 | set_tests_properties(
73 | libtorch_test_dlopen PROPERTIES ENVIRONMENT
74 | "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}")
75 |
--------------------------------------------------------------------------------
/libtorch_test/torch_test.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #define SLOG() std::cout << __FILE__ << ":" << __LINE__ << " "
11 | #define SSHOW_KV(key, value) " " << key << "=" << (value)
12 | #define SSHOW(x) SSHOW_KV(#x, x)
13 |
14 | extern "C" void test() {
15 | SLOG() << "add test" << std::endl;
16 | auto x = at::randn({1, 128, 224, 224}, at::kFloat);
17 | auto y = at::randn({1, 128, 224, 224}, at::kFloat);
18 | auto z = at::add(x, y);
19 | SLOG() << SSHOW(z.toString()) << std::endl;
20 |
21 | SLOG() << "convolution test" << std::endl;
22 | auto w = at::randn({32, 128, 224, 224}, at::kFloat);
23 | auto r2 = at::convolution(x, w, c10::nullopt, c10::IntArrayRef({1, 1}), c10::IntArrayRef({0}), c10::IntArrayRef({1, 1}), false,
24 | c10::IntArrayRef({0}), 1);
25 | SLOG() << SSHOW(r2.toString()) << std::endl;
26 | }
27 |
--------------------------------------------------------------------------------
/libtorch_test/torch_test.h:
--------------------------------------------------------------------------------
1 | extern "C" void test();
2 |
--------------------------------------------------------------------------------
/libtorch_test/torch_test_main.cc:
--------------------------------------------------------------------------------
1 | #include "torch_test.h"
2 |
3 | int main() {
4 | test();
5 | return 0;
6 | }
7 |
--------------------------------------------------------------------------------
/libtorch_test/torch_test_main_dlopen.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main() {
6 | void* handle;
7 | void (*test)();
8 | handle = dlopen("libtorch_test.so", RTLD_LAZY);
9 | if (!handle) {
10 | fprintf(stderr, "%s\n", dlerror());
11 | exit(1);
12 | }
13 | dlerror();
14 | test = (void (*)())dlsym(handle, "test");
15 | test();
16 | return 0;
17 | }
18 |
--------------------------------------------------------------------------------
/mprotect_builder.cc:
--------------------------------------------------------------------------------
1 | #include "mprotect_builder.h"
2 |
3 | constexpr uint8_t MprotectBuilder::memprotect_body_code_x86_64[];
4 | constexpr uint8_t MprotectBuilder::memprotect_end_code_x86_64[];
5 | constexpr uint8_t MprotectBuilder::memprotect_end_code_aarch64[];
6 |
7 | void MprotectBuilder::EmitX86_64(FILE* fp, uintptr_t mprotect_code_offset) {
8 | uint8_t* mprotect_code = (uint8_t*)malloc(Size());
9 | uint8_t* mprotect_code_head = mprotect_code;
10 | for (int i = 0; i < offsets.size(); i++) {
11 | LOG(INFO) << "MprotectBuilder::Emit: " << SOLD_LOG_BITS(offsets[i]) << SOLD_LOG_BITS(sizes[i]);
12 |
13 | memcpy(mprotect_code_head, memprotect_body_code_x86_64, sizeof(memprotect_body_code_x86_64));
14 | int64_t* offset_p = (int64_t*)(mprotect_code_head + memprotect_body_addr_offset_x86_64);
15 | // 17 is the length of `mov $0xdeadbeefdeadbeef, %rdi; lea (%rip), %rsi'
16 | int64_t offset_v = (offsets[i] & (~(0x1000 - 1))) -
17 | (static_cast(mprotect_code_offset) + static_cast(mprotect_code_head - mprotect_code) + 17);
18 | LOG(INFO) << "MprotectBuilder::Emit" << SOLD_LOG_BITS(offset_v) << SOLD_LOG_KEY(offset_v);
19 | *offset_p = offset_v;
20 | uint32_t* size_p = (uint32_t*)(mprotect_code_head + memprotect_body_size_offset_x86_64);
21 | *size_p = ((offsets[i] + sizes[i]) & (~(0x1000 - 1))) - (offsets[i] & (~(0x1000 - 1)));
22 | mprotect_code_head += sizeof(memprotect_body_code_x86_64);
23 | }
24 | memcpy(mprotect_code_head, memprotect_end_code_x86_64, sizeof(memprotect_end_code_x86_64));
25 | mprotect_code_head += sizeof(memprotect_end_code_x86_64);
26 |
27 | CHECK(fwrite(mprotect_code, sizeof(uint8_t), Size(), fp) == Size());
28 | free(mprotect_code);
29 | }
30 |
31 | namespace {
32 | std::vector set_immediate_to_register_aarch64(int64_t value, uint8_t reg) {
33 | std::vector ret;
34 | for (int i = 0; i < 4; i++) {
35 | uint32_t u = 0b11110010'10000000'00000000'00000000; // movk instruction
36 | u |= (i << 21);
37 | u |= ((value >> (i * 16)) & 0xffff) << 5;
38 | u |= reg;
39 | ret.emplace_back(u);
40 | }
41 | return ret;
42 | }
43 | } // namespace
44 |
45 | void MprotectBuilder::EmitAarch64(FILE* fp, uintptr_t mprotect_code_offset) {
46 | long int old_pos = ftell(fp);
47 |
48 | LOG(INFO) << "MprotectBuilder::EmitAarch64";
49 | std::vector insts;
50 | for (int i = 0; i < offsets.size(); i++) {
51 | // 5 is the length of x0 <- offsets[i] using 4 movk instructions; adr x3, 0
52 | int64_t offset = offsets[i] - (static_cast(mprotect_code_offset) + body_code_length_aarch64 + 5 * 4);
53 | auto set_x0 = set_immediate_to_register_aarch64(offset, 0); // x0 <- offsets[i] using 4 movk instructions
54 | insts.insert(insts.end(), set_x0.begin(), set_x0.end()); //
55 | insts.emplace_back(0b00010000'00000000'00000000'00000011); // adr x3, 0
56 | insts.emplace_back(0x8B030000); // add x0, x0,x3
57 | auto set_x1 = set_immediate_to_register_aarch64(sizes[i], 1); // x1 <- len[i] using 4 movk instructions
58 | insts.insert(insts.end(), set_x1.begin(), set_x1.end()); //
59 | insts.emplace_back(0xD2800022); // mov x2, 1(PROT_READ)
60 | insts.emplace_back(0x52800148); // mov w8, 10(mprotect)
61 | insts.emplace_back(0xD4000001); // svc 0
62 | }
63 | insts.emplace_back(0xD65F03C0);
64 |
65 | for (uint32_t i : insts) {
66 | CHECK(fwrite(&i, sizeof(uint32_t), 1, fp) == 1);
67 | }
68 | CHECK(ftell(fp) - old_pos == Size());
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/mprotect_builder.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #pragma once
17 |
18 | #include
19 | #include
20 |
21 | #include "utils.h"
22 |
23 | class MprotectBuilder {
24 | public:
25 | void SetMachineType(const Elf64_Half machine_type) {
26 | CHECK(machine_type == EM_X86_64 || machine_type == EM_AARCH64);
27 | machine_type_ = machine_type;
28 | }
29 | void Add(uintptr_t offset, uintptr_t size) {
30 | offsets.emplace_back(offset);
31 | sizes.emplace_back(size);
32 | }
33 | uintptr_t Size() const {
34 | CHECK(offsets.size() == sizes.size());
35 | if (machine_type_ == EM_X86_64) {
36 | return sizeof(memprotect_body_code_x86_64) * offsets.size() + sizeof(memprotect_end_code_x86_64);
37 | } else if (machine_type_ == EM_AARCH64) {
38 | return body_code_length_aarch64 * offsets.size() + ret_code_length_aarch64;
39 | } else {
40 | CHECK(false) << SOLD_LOG_KEY(machine_type_) << " is not supported.";
41 | }
42 | }
43 | void Emit(FILE* fp, uintptr_t mprotect_code_offset) {
44 | CHECK(machine_type_ == EM_X86_64 || machine_type_ == EM_AARCH64) << "SetMachineType before Emit";
45 | if (machine_type_ == EM_X86_64) {
46 | EmitX86_64(fp, mprotect_code_offset);
47 | } else if (machine_type_ == EM_AARCH64) {
48 | EmitAarch64(fp, mprotect_code_offset);
49 | } else {
50 | CHECK(false) << SOLD_LOG_KEY(machine_type_) << " is not supported.";
51 | }
52 | }
53 |
54 | // call SYS_mprotect syscall
55 | //
56 | // mov $0xdeadbeefdeadbeef, %rdi
57 | // lea (%rip), %rsi
58 | // add %rsi, %rdi
59 | // mov $0xaabbcc, %rsi (size)
60 | // mov $0x1, %rdx (0x1 = PROT_READ)
61 | // mov $10, %eax (10 = SYS_mprotect)
62 | // syscall
63 | // test %eax, %eax
64 | // jz ok
65 | // ud2
66 | // ok:
67 | static constexpr uint8_t memprotect_body_code_x86_64[] = {0x48, 0xbf, 0xef, 0xbe, 0xad, 0xde, 0xef, 0xbe, 0xad, 0xde, 0x48, 0x8d,
68 | 0x35, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xf7, 0x48, 0xc7, 0xc6, 0xcc,
69 | 0xbb, 0xaa, 0x00, 0x48, 0xc7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0xb8, 0x0a,
70 | 0x00, 0x00, 0x00, 0x0f, 0x05, 0x85, 0xc0, 0x74, 0x02, 0x0f, 0x0b};
71 | // offset to 0xabbccdd
72 | static constexpr int memprotect_body_addr_offset_x86_64 = 2;
73 | // offset to 0xaabbcc
74 | static constexpr int memprotect_body_size_offset_x86_64 = 23;
75 |
76 | // ret
77 | static constexpr uint8_t memprotect_end_code_x86_64[] = {0xc3};
78 |
79 | // ret
80 | static constexpr uint8_t memprotect_end_code_aarch64[] = {0xc0, 0x03, 0x5f, 0xd6};
81 |
82 | static constexpr int body_code_length_aarch64 = 13 * 4;
83 | static constexpr int ret_code_length_aarch64 = 4;
84 |
85 | private:
86 | void EmitX86_64(FILE* fp, uintptr_t mprotect_code_offset);
87 | void EmitAarch64(FILE* fp, uintptr_t mprotect_code_offset);
88 | Elf64_Half machine_type_;
89 | std::vector offsets;
90 | std::vector sizes;
91 | };
92 |
--------------------------------------------------------------------------------
/print_dtrela.cc:
--------------------------------------------------------------------------------
1 | // print_dtrela
2 | // This program shows relocation entries in DT_RELA.
3 | //
4 | // Copyright (C) 2021 The sold authors
5 | //
6 | // This program is free software: you can redistribute it and/or modify
7 | // it under the terms of the GNU General Public License as published by
8 | // the Free Software Foundation, either version 3 of the License, or
9 | // (at your option) any later version.
10 | //
11 | // This program is distributed in the hope that it will be useful,
12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | // GNU General Public License for more details.
15 | //
16 | // You should have received a copy of the GNU General Public License
17 | // along with this program. If not, see .
18 |
19 | #include "elf_binary.h"
20 |
21 | #include
22 |
23 | int main(int argc, const char* argv[]) {
24 | google::InitGoogleLogging(argv[0]);
25 |
26 | if (argc != 2) {
27 | std::cerr << "Usage: " << argv[0] << " \nThis program parse DT_RELA of the given ELF file." << std::endl;
28 | return 1;
29 | }
30 |
31 | auto b = ReadELF(argv[1]);
32 | std::cout << b->ShowDtRela();
33 | return 0;
34 | }
35 |
--------------------------------------------------------------------------------
/print_dynsymtab.cc:
--------------------------------------------------------------------------------
1 | // print_dynsymtab
2 | //
3 | // This program parses and prints DT_SYMTAB of a given ELF file. It prints all symbols
4 | // and version information. When the ELF file does not include version information,
5 | // it prints NO_VERSION_INFO instead of version information.
6 | //
7 | // Unlike nm -D --with-symbol-versions or readelf --dynsyms, it works without any shdrs
8 | // because print_dynsymtab gets all information only from phdrs.
9 | //
10 | // Copyright (C) 2021 The sold authors
11 | //
12 | // This program is free software: you can redistribute it and/or modify
13 | // it under the terms of the GNU General Public License as published by
14 | // the Free Software Foundation, either version 3 of the License, or
15 | // (at your option) any later version.
16 | //
17 | // This program is distributed in the hope that it will be useful,
18 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 | // GNU General Public License for more details.
21 | //
22 | // You should have received a copy of the GNU General Public License
23 | // along with this program. If not, see .
24 |
25 | #include "elf_binary.h"
26 |
27 | #include
28 |
29 | #include "sold.h"
30 |
31 | int main(int argc, const char* argv[]) {
32 | google::InitGoogleLogging(argv[0]);
33 |
34 | if (argc != 2) {
35 | std::cerr << "Usage: " << argv[0] << " \nThis program parse DT_SYMTAB of the given ELF file." << std::endl;
36 | return 1;
37 | }
38 |
39 | // This Sold class instrance is used only to get filename_to_soname map.
40 | Sold sold(argv[1], {}, {}, {}, {}, {}, false, false);
41 |
42 | auto b = ReadELF(argv[1]);
43 | b->ReadDynSymtab(sold.filename_to_soname());
44 | std::cout << b->ShowDynSymtab();
45 | }
46 |
--------------------------------------------------------------------------------
/print_ehframe.cc:
--------------------------------------------------------------------------------
1 | //
2 | // print_ehframe
3 | //
4 | // This program shows .eh_frame_hdr
5 | //
6 | // Copyright (C) 2021 The sold authors
7 | //
8 | // This program is free software: you can redistribute it and/or modify
9 | // it under the terms of the GNU General Public License as published by
10 | // the Free Software Foundation, either version 3 of the License, or
11 | // (at your option) any later version.
12 | //
13 | // This program is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | // GNU General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU General Public License
19 | // along with this program. If not, see .
20 |
21 | #include "elf_binary.h"
22 |
23 | #include
24 |
25 | int main(int argc, const char* argv[]) {
26 | google::InitGoogleLogging(argv[0]);
27 | google::InstallFailureSignalHandler();
28 |
29 | if (argc != 2) {
30 | std::cerr << "Usage: " << argv[0] << " \nThis program shows .eh_frame_hdr." << std::endl;
31 | return 1;
32 | }
33 |
34 | auto b = ReadELF(argv[1]);
35 | std::cout << b->ShowEHFrame();
36 | return 0;
37 | }
38 |
--------------------------------------------------------------------------------
/print_tls.cc:
--------------------------------------------------------------------------------
1 | //
2 | // print_tls
3 | //
4 | // This program shows tls entries.
5 | //
6 | // Copyright (C) 2021 The sold authors
7 | //
8 | // This program is free software: you can redistribute it and/or modify
9 | // it under the terms of the GNU General Public License as published by
10 | // the Free Software Foundation, either version 3 of the License, or
11 | // (at your option) any later version.
12 | //
13 | // This program is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | // GNU General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU General Public License
19 | // along with this program. If not, see .
20 |
21 | #include "elf_binary.h"
22 |
23 | #include
24 |
25 | int main(int argc, const char* argv[]) {
26 | google::InitGoogleLogging(argv[0]);
27 |
28 | if (argc != 2) {
29 | std::cerr << "Usage: " << argv[0] << " \nThis program shows TLS entries of the given ELF file." << std::endl;
30 | return 1;
31 | }
32 |
33 | auto b = ReadELF(argv[1]);
34 | std::cout << b->ShowTLS();
35 | return 0;
36 | }
37 |
--------------------------------------------------------------------------------
/print_version.cc:
--------------------------------------------------------------------------------
1 | //
2 | // print_verneed
3 | //
4 | // This program shows version information.
5 | //
6 | // Copyright (C) 2021 The sold authors
7 | //
8 | // This program is free software: you can redistribute it and/or modify
9 | // it under the terms of the GNU General Public License as published by
10 | // the Free Software Foundation, either version 3 of the License, or
11 | // (at your option) any later version.
12 | //
13 | // This program is distributed in the hope that it will be useful,
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | // GNU General Public License for more details.
17 | //
18 | // You should have received a copy of the GNU General Public License
19 | // along with this program. If not, see .
20 |
21 | #include "elf_binary.h"
22 |
23 | #include
24 |
25 | int main(int argc, const char* argv[]) {
26 | google::InitGoogleLogging(argv[0]);
27 |
28 | if (argc != 2) {
29 | std::cerr << "Usage: " << argv[0] << " \nThis program shows verneed information of the given ELF file." << std::endl;
30 | return 1;
31 | }
32 |
33 | auto b = ReadELF(argv[1]);
34 | std::cout << b->ShowVersion();
35 | return 0;
36 | }
37 |
--------------------------------------------------------------------------------
/pybind_libtorch_test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4)
2 |
3 | find_package(Torch REQUIRED)
4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
5 |
6 | # I set PREFIX and SUFFIX here because I want to pass generated files to sold.
7 | # The default SUFFIX depends on the system configuration and is difficult to
8 | # infer.
9 | pybind11_add_module(my_add_kernel numpy.cc)
10 | set_target_properties(my_add_kernel PROPERTIES PREFIX "" SUFFIX ".so")
11 | target_link_libraries(my_add_kernel PRIVATE "${TORCH_LIBRARIES}")
12 |
13 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/soldout")
14 | add_custom_target(
15 | my_add_kernel_soldout ALL
16 | COMMAND
17 | "${PROJECT_BINARY_DIR}/sold" -i
18 | "${CMAKE_CURRENT_BINARY_DIR}/my_add_kernel.so" -o
19 | "${CMAKE_CURRENT_BINARY_DIR}/soldout/my_add_kernel.so" --section-headers
20 | --check-output
21 | DEPENDS sold my_add_kernel)
22 |
23 | # ${CMAKE_CURRENT_BINARY_DIR}/test_soldout_modules_original.py is for debug.
24 | configure_file(
25 | test_soldout_modules.py
26 | ${CMAKE_CURRENT_BINARY_DIR}/test_soldout_modules_original.py @ONLY)
27 | configure_file(
28 | test_soldout_modules.py
29 | ${CMAKE_CURRENT_BINARY_DIR}/soldout/test_soldout_modules.py @ONLY)
30 |
31 | add_test(
32 | NAME pybind_libtorch_test
33 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/soldout"
34 | COMMAND pytest -v)
35 |
--------------------------------------------------------------------------------
/pybind_libtorch_test/numpy.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | namespace py = pybind11;
12 |
13 | py::array_t add_arrays(py::array_t input1, py::array_t input2) {
14 | py::buffer_info buf1 = input1.request(), buf2 = input2.request();
15 |
16 | if (buf1.ndim != 1 || buf2.ndim != 1) throw std::runtime_error("Number of dimensions must be one");
17 |
18 | if (buf1.size != buf2.size) throw std::runtime_error("Input shapes must match");
19 |
20 | /* No pointer is passed, so NumPy will allocate the buffer */
21 | auto result = py::array_t(buf1.size);
22 |
23 | py::buffer_info buf3 = result.request();
24 |
25 | double* ptr1 = static_cast(buf1.ptr);
26 | double* ptr2 = static_cast(buf2.ptr);
27 | double* ptr3 = static_cast(buf3.ptr);
28 |
29 | at::Tensor tensor1 = at::from_blob(ptr1, buf1.size, at::kDouble).clone();
30 | at::Tensor tensor2 = at::from_blob(ptr2, buf1.size, at::kDouble).clone();
31 | at::Tensor tensor3 = tensor1 + tensor2;
32 |
33 | for (size_t idx = 0; idx < buf1.shape[0]; idx++) ptr3[idx] = tensor3[idx].item();
34 |
35 | return result;
36 | }
37 |
38 | PYBIND11_MODULE(my_add_kernel, m) {
39 | m.def("add_arrays", &add_arrays, "Add two NumPy arrays using libtorch");
40 | }
41 |
--------------------------------------------------------------------------------
/pybind_libtorch_test/test_soldout_modules.py:
--------------------------------------------------------------------------------
1 | import numpy
2 |
3 | import my_add_kernel
4 |
5 | def test_mynumpy_add():
6 | # The size of arrays is pretty large because I had encountered a bug that
7 | # appears only for large arrays.
8 | a = numpy.random.rand(32)
9 | b = numpy.random.rand(32)
10 | r = my_add_kernel.add_arrays(a, b)
11 | assert numpy.allclose(a + b, r)
12 |
--------------------------------------------------------------------------------
/pybind_test/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4)
2 |
3 | # I set PREFIX and SUFFIX here because I want to pass generated files to sold.
4 | # The default SUFFIX depends on the system configuration and is difficult to
5 | # infer.
6 | pybind11_add_module(myadd add.cc)
7 | set_target_properties(myadd PROPERTIES PREFIX "" SUFFIX ".so")
8 | pybind11_add_module(myobject object.cc)
9 | set_target_properties(myobject PROPERTIES PREFIX "" SUFFIX ".so")
10 | pybind11_add_module(mynumpy numpy.cc)
11 | set_target_properties(mynumpy PROPERTIES PREFIX "" SUFFIX ".so")
12 |
13 | file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/soldout")
14 | add_custom_target(
15 | myadd_soldout ALL
16 | COMMAND
17 | "${PROJECT_BINARY_DIR}/sold" -i "${CMAKE_CURRENT_BINARY_DIR}/myadd.so" -o
18 | "${CMAKE_CURRENT_BINARY_DIR}/soldout/myadd.so" --section-headers
19 | --check-output
20 | DEPENDS sold myadd)
21 | add_custom_target(
22 | myobject_soldout ALL
23 | COMMAND
24 | "${PROJECT_BINARY_DIR}/sold" -i "${CMAKE_CURRENT_BINARY_DIR}/myobject.so" -o
25 | "${CMAKE_CURRENT_BINARY_DIR}/soldout/myobject.so" --section-headers
26 | --check-output
27 | DEPENDS sold myobject)
28 | add_custom_target(
29 | mynumpy_soldout ALL
30 | COMMAND
31 | "${PROJECT_BINARY_DIR}/sold" -i "${CMAKE_CURRENT_BINARY_DIR}/mynumpy.so" -o
32 | "${CMAKE_CURRENT_BINARY_DIR}/soldout/mynumpy.so" --section-headers
33 | --check-output
34 | DEPENDS sold mynumpy)
35 |
36 | # ${CMAKE_CURRENT_BINARY_DIR}/test_soldout_modules_original.py is for debug.
37 | configure_file(
38 | test_soldout_modules.py
39 | ${CMAKE_CURRENT_BINARY_DIR}/test_soldout_modules_original.py @ONLY)
40 | configure_file(
41 | test_soldout_modules.py
42 | ${CMAKE_CURRENT_BINARY_DIR}/soldout/test_soldout_modules.py @ONLY)
43 |
44 | add_test(
45 | NAME pybind_test
46 | WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/soldout"
47 | COMMAND pytest -v)
48 |
--------------------------------------------------------------------------------
/pybind_test/README.md:
--------------------------------------------------------------------------------
1 | # pybind test
2 | Most of codes in this directory comes from
3 | - [https://pybind11.readthedocs.io/en/stable/basics.html]()
4 | - [https://pybind11.readthedocs.io/en/stable/classes.html]()
5 | - [https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html]()
6 |
--------------------------------------------------------------------------------
/pybind_test/add.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace py = pybind11;
4 | using namespace pybind11::literals;
5 |
6 | int add(int i, int j) {
7 | return i + j;
8 | }
9 |
10 | PYBIND11_MODULE(myadd, m) {
11 | m.doc() = "pybind11 example plugin"; // optional module docstring
12 | m.def("myadd", &add, "A function which adds two numbers");
13 | m.def("myadd2", &add, "i"_a, "j"_a);
14 | m.def("myadd3", &add, "i"_a = 1, "j"_a = 2);
15 |
16 | m.attr("the_answer") = 42;
17 | py::object world = py::cast("World");
18 | m.attr("what") = world;
19 | }
20 |
--------------------------------------------------------------------------------
/pybind_test/numpy.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | namespace py = pybind11;
5 |
6 | py::array_t add_arrays(py::array_t input1, py::array_t input2) {
7 | py::buffer_info buf1 = input1.request(), buf2 = input2.request();
8 |
9 | if (buf1.ndim != 1 || buf2.ndim != 1) throw std::runtime_error("Number of dimensions must be one");
10 |
11 | if (buf1.size != buf2.size) throw std::runtime_error("Input shapes must match");
12 |
13 | /* No pointer is passed, so NumPy will allocate the buffer */
14 | auto result = py::array_t(buf1.size);
15 |
16 | py::buffer_info buf3 = result.request();
17 |
18 | double* ptr1 = static_cast(buf1.ptr);
19 | double* ptr2 = static_cast(buf2.ptr);
20 | double* ptr3 = static_cast(buf3.ptr);
21 |
22 | for (size_t idx = 0; idx < buf1.shape[0]; idx++) ptr3[idx] = ptr1[idx] + ptr2[idx];
23 |
24 | return result;
25 | }
26 |
27 | PYBIND11_MODULE(mynumpy, m) {
28 | m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
29 | }
30 |
--------------------------------------------------------------------------------
/pybind_test/object.cc:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace py = pybind11;
4 |
5 | struct Pet {
6 | enum Kind { Dog = 0, Cat };
7 |
8 | Pet(const std::string& name) : name(name), type(Kind::Dog) {}
9 | Pet(const std::string& name, Kind type) : name(name), type(type) {}
10 |
11 | void set(int age_) { age = age_; }
12 | void set(const std::string& name_) { name = name_; }
13 | void setName(const std::string& name_) { name = name_; }
14 | const std::string& getName() const { return name; }
15 | const int getAge() const { return age; }
16 |
17 | int age;
18 | std::string name;
19 | Kind type;
20 | };
21 |
22 | struct Dog : Pet {
23 | Dog(const std::string& name) : Pet(name) {}
24 | std::string bark() const { return "woof!"; }
25 | };
26 |
27 | struct PolymorphicPet {
28 | virtual ~PolymorphicPet() = default;
29 | };
30 |
31 | struct PolymorphicDog : PolymorphicPet {
32 | std::string bark() const { return "woof!"; }
33 | };
34 |
35 | PYBIND11_MODULE(myobject, m) {
36 | py::class_ pet(m, "Pet");
37 |
38 | pet.def(py::init())
39 | .def(py::init())
40 | .def("set", py::overload_cast(&Pet::set), "Set the pet's age")
41 | .def("set", py::overload_cast(&Pet::set), "Set the pet's name")
42 | .def("setName", &Pet::setName)
43 | .def("getName", &Pet::getName)
44 | .def("getAge", &Pet::getAge)
45 | .def("__repr__", [](const Pet& a) { return ""; })
46 | .def_readwrite("type", &Pet::type);
47 | py::enum_(pet, "Kind").value("Dog", Pet::Kind::Dog).value("Cat", Pet::Kind::Cat).export_values();
48 |
49 | py::class_(m, "Dog").def(py::init()).def("bark", &Dog::bark);
50 |
51 | m.def("pet_store", []() { return std::unique_ptr(new Dog("Molly")); });
52 |
53 | py::class_(m, "PolymorphicPet");
54 | py::class_(m, "PolymorphicDog").def(py::init<>()).def("bark", &PolymorphicDog::bark);
55 |
56 | m.def("pet_store2", []() { return std::unique_ptr(new PolymorphicDog); });
57 | }
58 |
--------------------------------------------------------------------------------
/pybind_test/test_soldout_modules.py:
--------------------------------------------------------------------------------
1 | import numpy
2 |
3 | import myadd
4 | import myobject
5 | import mynumpy
6 |
7 | def test_myadd():
8 | assert myadd.myadd(1, 2) == 3
9 |
10 | def test_myadd_keyword():
11 | assert myadd.myadd2(i=1, j=2) == 3
12 |
13 | def test_myadd_default():
14 | assert myadd.myadd3() == 3
15 |
16 | def test_myadd_const():
17 | assert myadd.the_answer == 42
18 | assert myadd.what == "World"
19 |
20 | def test_myobject_pet():
21 | p = myobject.Pet('Molly')
22 | assert p.getName() == "Molly"
23 | p.setName('Charly')
24 | assert p.getName() == "Charly"
25 |
26 | def test_myobject_dog():
27 | p = myobject.Dog('Molly')
28 | assert p.getName() == "Molly"
29 | assert p.bark() == "woof!"
30 |
31 | def test_myobject_pet_store():
32 | p = myobject.pet_store()
33 | assert type(p).__name__ == "Pet"
34 |
35 | def test_myobject_pet_store2():
36 | p = myobject.pet_store2()
37 | assert type(p).__name__ == "PolymorphicDog"
38 | assert p.bark() == "woof!"
39 |
40 | def test_myobject_overload():
41 | p = myobject.Pet('Molly')
42 | p.set(10)
43 | p.set("hogehoge")
44 | assert p.getAge() == 10
45 | assert p.getName() == "hogehoge"
46 |
47 | def test_myobject_enum():
48 | p = myobject.Pet('Lucy', myobject.Pet.Cat)
49 | assert p.type == 1
50 |
51 | def test_mynumpy_add():
52 | # The size of arrays is pretty large because I had encountered a bug that
53 | # appears only for large arrays.
54 | a = numpy.random.rand(1024 * 1024 * 32)
55 | b = numpy.random.rand(1024 * 1024 * 32)
56 | r = mynumpy.add_arrays(a, b)
57 | assert numpy.allclose(a + b, r)
58 |
--------------------------------------------------------------------------------
/renamer_test/.gitignore:
--------------------------------------------------------------------------------
1 | libfugafuga.so
2 | libhoge_original.so
3 | libhoge_renamed.so
4 | libhoge.so
5 | use_fugafuga
6 |
--------------------------------------------------------------------------------
/renamer_test/fugafuga.c:
--------------------------------------------------------------------------------
1 | int fugafuga(int a, int b) {
2 | return a - b;
3 | }
4 |
--------------------------------------------------------------------------------
/renamer_test/hoge.c:
--------------------------------------------------------------------------------
1 | int hoge(int a, int b) {
2 | return a + b;
3 | }
4 |
--------------------------------------------------------------------------------
/renamer_test/mapping:
--------------------------------------------------------------------------------
1 | hoge fugafuga
2 |
--------------------------------------------------------------------------------
/renamer_test/test.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | gcc -fPIC -fpic -shared -o libhoge_original.so hoge.c -Wl,-soname,libhoge.so
4 | gcc -fPIC -fpic -shared -o libfugafuga.so fugafuga.c -Wl,-soname,libhoge.so
5 | ln -sf libfugafuga.so libhoge.so
6 | gcc -o use_fugafuga use_fugafuga.c libhoge.so
7 | $(git rev-parse --show-toplevel)/build/renamer libhoge_original.so --output libhoge_renamed.so --rename-mapping-file mapping
8 | ln -sf libhoge_renamed.so libhoge.so
9 | LD_LIBRARY_PATH=. ./use_fugafuga
10 |
--------------------------------------------------------------------------------
/renamer_test/use_fugafuga.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | // Although `fugafuga` in fugafuga.c is subtraction, `hoge` in hoge.c is
5 | // addition. renamer renames `hoge` to `fugafuga`.
6 | int fugafuga(int a, int b);
7 |
8 | int main() {
9 | int a = fugafuga(1, 2);
10 | assert(a == 3);
11 | return 0;
12 | }
13 |
--------------------------------------------------------------------------------
/run-docker-tests.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eux
2 |
3 | # ========== ubuntu18.04 start ==========
4 | # ---------- CPU start ----------
5 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.8.0+cpu IMAGE_NAME=ubuntu:18.04 .
6 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.8.1+cpu IMAGE_NAME=ubuntu:18.04 .
7 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.9.0+cpu IMAGE_NAME=ubuntu:18.04 .
8 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.9.1+cpu IMAGE_NAME=ubuntu:18.04 .
9 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.10.0+cpu IMAGE_NAME=ubuntu:18.04 .
10 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.10.1+cpu IMAGE_NAME=ubuntu:18.04 .
11 | sudo docker build -f ubuntu18.04.Dockerfile --build-arg TORCH_VERSION=1.10.2+cpu IMAGE_NAME=ubuntu:18.04 .
12 | # ---------- CPU end ----------
13 |
14 | # ---------- GPU start ----------
15 | # DT_INIT and DT_FINI.
16 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.8.0+cu101 --build-arg IMAGE_NAME=nvidia/cuda:10.1-devel-ubuntu18.04 .
17 | # F0530 00:17:28.955174 231 sold.cc:135] Check failed: file_offset < offsets_[main_binary_.get()]
18 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.8.0+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
19 |
20 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.8.1+cu101 --build-arg IMAGE_NAME=nvidia/cuda:10.1-devel-ubuntu18.04 .
21 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.8.1+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
22 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.8.1+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
23 |
24 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.0+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
25 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.0+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
26 |
27 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.0+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
28 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.0+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
29 |
30 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.1+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
31 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.9.1+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
32 |
33 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.0+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
34 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.0+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
35 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.0+cu113 --build-arg IMAGE_NAME=nvidia/cuda:11.3-devel-ubuntu18.04 .
36 |
37 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.1+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
38 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.1+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
39 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.1+cu113 --build-arg IMAGE_NAME=nvidia/cuda:11.3-devel-ubuntu18.04 .
40 |
41 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.2+cu102 --build-arg IMAGE_NAME=nvidia/cuda:10.2-devel-ubuntu18.04 .
42 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.2+cu111 --build-arg IMAGE_NAME=nvidia/cuda:11.1-devel-ubuntu18.04 .
43 | sudo docker build -f ubuntu18.04-gpu.Dockerfile --build-arg TORCH_VERSION=1.10.2+cu113 --build-arg IMAGE_NAME=nvidia/cuda:11.3-devel-ubuntu18.04 .
44 | # ---------- GPU end ----------
45 | # ========== ubuntu18.04 end ==========
46 |
47 | sudo docker build -f ubuntu20.04.Dockerfile .
48 | sudo docker build -f ubuntu22.04.Dockerfile .
49 | sudo docker build -f fedora-latest.Dockerfile .
50 |
--------------------------------------------------------------------------------
/run-format.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash -eu
2 |
3 | cd "$(git rev-parse --show-toplevel)"
4 | git ls-files -- '**/*.h' '**/*.cc' '**/*.c'| xargs -P4 clang-format -i
5 | git ls-files -- '**/CMakeLists.txt' | xargs -P4 cmake-format -i
6 | git diff --exit-code -- .
7 |
--------------------------------------------------------------------------------
/shdr_builder.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2021 The sold authors
2 | //
3 | // This program is free software: you can redistribute it and/or modify
4 | // it under the terms of the GNU General Public License as published by
5 | // the Free Software Foundation, either version 3 of the License, or
6 | // (at your option) any later version.
7 | //
8 | // This program is distributed in the hope that it will be useful,
9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | // GNU General Public License for more details.
12 | //
13 | // You should have received a copy of the GNU General Public License
14 | // along with this program. If not, see .
15 |
16 | #include