diff options
| author | Amlal <amlal@nekernel.org> | 2025-08-12 15:25:04 +0200 |
|---|---|---|
| committer | Amlal <amlal@nekernel.org> | 2025-08-12 15:25:04 +0200 |
| commit | a2d091a55cdc465a4f90181f2b404bdd062dbad6 (patch) | |
| tree | 9c62d0c14aafb6ee4f520bfc7cbef00816ea200e | |
| parent | b77d1d0a876b845d98c8828da27b2d828378138f (diff) | |
feat: Linker test and improvements to the linker.
Signed-off-by: Amlal <amlal@nekernel.org>
| -rw-r--r-- | dev/CompilerKit/ck-posix.json | 4 | ||||
| -rw-r--r-- | dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc | 23 | ||||
| -rw-r--r-- | tests/test_02_linker/CMakeLists.txt | 23 | ||||
| -rw-r--r-- | tests/test_02_linker/linker_test.cc | 24 | ||||
| -rw-r--r-- | tests/test_02_linker/sample/sample.cc | 3 | ||||
| -rw-r--r-- | tests/test_02_linker/sample/sample.cc.pp | 3 |
6 files changed, 71 insertions, 9 deletions
diff --git a/dev/CompilerKit/ck-posix.json b/dev/CompilerKit/ck-posix.json index e80ce65..e3ff231 100644 --- a/dev/CompilerKit/ck-posix.json +++ b/dev/CompilerKit/ck-posix.json @@ -11,7 +11,7 @@ "src/*.cc", "src/*/*.cc" ], - "output_name": "/usr/local/lib/libCompilerKit.so", + "output_name": "/usr/lib/libCompilerKit.so", "compiler_flags": [ "-fPIC", "-shared" @@ -21,4 +21,4 @@ "CK_USE_STRUCTS=1", "kDistReleaseBranch=$(git rev-parse --abbrev-ref HEAD)-$(uuidgen)" ] -}
\ No newline at end of file +} diff --git a/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc b/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc index 6c8ca95..917b592 100644 --- a/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc +++ b/dev/CompilerKit/src/Linker/DynamicLinker64PEF.cc @@ -62,6 +62,8 @@ static Bool kDuplicateSymbols = false; static const Char* kLdDefineSymbol = ":UndefinedSymbol:"; static const Char* kLdDynamicSym = ":RuntimeSymbol:"; +static CompilerKit::STLString kLinkerStart = kPefStart; + /* object code and list. */ static std::vector<CompilerKit::STLString> kObjectList; static std::vector<Detail::DynamicLinkerBlob> kObjectBytes; @@ -71,7 +73,7 @@ static std::vector<Detail::DynamicLinkerBlob> kObjectBytes; NECTI_MODULE(DynamicLinker64PEF) { bool is_executable = true; - ::signal(SIGSEGV, Detail::drvi_crash_handler); + CompilerKit::install_signal(SIGSEGV, Detail::drvi_crash_handler); /** * @brief parse flags and trigger options. @@ -110,6 +112,13 @@ NECTI_MODULE(DynamicLinker64PEF) { kArch = CompilerKit::kPefArchAMD64; continue; + } else if (std::strcmp(argv[linker_arg], "-start") == 0) { + if (argv[linker_arg + 1] == nullptr || argv[linker_arg][0] == '-') continue; + + kLinkerStart = argv[linker_arg + 1]; + linker_arg += 2; + + continue; } else if (std::strcmp(argv[linker_arg], "-32k") == 0) { kArch = CompilerKit::kPefArch32000; @@ -284,7 +293,7 @@ NECTI_MODULE(DynamicLinker64PEF) { if (cmd_hdr_name.find(kPefCode64) == CompilerKit::STLString::npos && cmd_hdr_name.find(kPefData64) == CompilerKit::STLString::npos && cmd_hdr_name.find(kPefZero64) == CompilerKit::STLString::npos) { - if (cmd_hdr_name.find(kPefStart) == CompilerKit::STLString::npos && + if (cmd_hdr_name.find(kLinkerStart) == CompilerKit::STLString::npos && *command_header.Name == 0) { if (cmd_hdr_name.find(kLdDefineSymbol) != CompilerKit::STLString::npos) { goto ld_mark_header; @@ -294,7 +303,7 @@ NECTI_MODULE(DynamicLinker64PEF) { } } - if (cmd_hdr_name.find(kPefStart) != CompilerKit::STLString::npos && + if (cmd_hdr_name.find(kLinkerStart) != CompilerKit::STLString::npos && cmd_hdr_name.find(kPefCode64) != CompilerKit::STLString::npos) { kStartFound = true; } @@ -422,11 +431,11 @@ NECTI_MODULE(DynamicLinker64PEF) { if (!kStartFound && is_executable) { if (kVerbose) - kConsoleOut << "Undefined entrypoint: " << kPefStart + kConsoleOut << "Undefined entrypoint: " << kLinkerStart << ", you may have forget to link " "against the C++ runtime library.\n"; - kConsoleOut << "Undefined entrypoint " << kPefStart << " for executable: " << kOutput << "\n"; + kConsoleOut << "Undefined entrypoint " << kLinkerStart << " for executable: " << kOutput << "\n"; } // step 4: write all PEF commands. @@ -560,9 +569,9 @@ NECTI_MODULE(DynamicLinker64PEF) { CompilerKit::STLString name = command_headers[commandHeaderIndex].Name; /// so this is valid when we get to the entrypoint. - /// it is always a code64 container. And should equal to kPefStart as well. + /// it is always a code64 container. And should equal to kLinkerStart as well. /// this chunk of code updates the pef_container.Start with the updated offset. - if (name.find(kPefStart) != CompilerKit::STLString::npos && + if (name.find(kLinkerStart) != CompilerKit::STLString::npos && name.find(kPefCode64) != CompilerKit::STLString::npos) { pef_container.Start = command_headers[commandHeaderIndex].Offset; auto tellCurPos = output_fc.tellp(); diff --git a/tests/test_02_linker/CMakeLists.txt b/tests/test_02_linker/CMakeLists.txt new file mode 100644 index 0000000..f3493fc --- /dev/null +++ b/tests/test_02_linker/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.10) +project(NeCTILinkerTest) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) + +enable_testing() + +add_executable(LinkerTestBasic linker_test.cc) +target_link_libraries(LinkerTestBasic gtest_main) + +set_property(TARGET LinkerTestBasic PROPERTY CXX_STANDARD 20) +target_include_directories(LinkerTestBasic PUBLIC ../../) + +include(GoogleTest) +gtest_discover_tests(LinkerTestBasic) diff --git a/tests/test_02_linker/linker_test.cc b/tests/test_02_linker/linker_test.cc new file mode 100644 index 0000000..88d51de --- /dev/null +++ b/tests/test_02_linker/linker_test.cc @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025 Amlal EL Mahrouss, all rights reserved + + ------------------------------------------- */ + + +/// @brief Linker Unit test, from the C++ unit to the final executable. +/// @author Amlal El Mahrouss + +#include <gtest/gtest.h> + +TEST(LinkerTest, BasicLinkTest) +{ + /// @note this is the driver, it will look for a .cc.pp (.pp stands for pre-processed) + auto expr = std::system("pef-amd64-cxxdrv sample/sample.cc"); + EXPECT_TRUE(expr == 0) << "C++ Driver did not compile the easy C++ unit."; + + expr = std::system("asm -asm:x64 sample/sample.cc.pp.masm"); + EXPECT_TRUE(expr == 0) << "Assembler did not assemble the easy asm unit."; + + expr = std::system("ld64 -fat-binary sample/sample.cc.pp.obj -start __NECTI_main -output main.exec"); + EXPECT_TRUE(expr == 0) << "Linker did not link the easy object."; +} diff --git a/tests/test_02_linker/sample/sample.cc b/tests/test_02_linker/sample/sample.cc new file mode 100644 index 0000000..4cce7f6 --- /dev/null +++ b/tests/test_02_linker/sample/sample.cc @@ -0,0 +1,3 @@ +int main() { + return 0; +} diff --git a/tests/test_02_linker/sample/sample.cc.pp b/tests/test_02_linker/sample/sample.cc.pp new file mode 100644 index 0000000..cb3f748 --- /dev/null +++ b/tests/test_02_linker/sample/sample.cc.pp @@ -0,0 +1,3 @@ +int main() { + return 0; +} |
