diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2026-01-21 22:14:31 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2026-01-21 22:14:31 +0100 |
| commit | 6c2b1b2f83c492db1e38879719502668276442f6 (patch) | |
| tree | a3b057c2eef7759010beca6b859eb0e0854026fa | |
| parent | 470f065bc61bc3dbebe342d426e49a4f70ff335b (diff) | |
feat: CompilerKit: Assembler and Linker improvements.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
| -rw-r--r-- | include/CompilerKit/AE.h | 9 | ||||
| -rw-r--r-- | include/CompilerKit/Utilities/Compiler.h | 10 | ||||
| -rw-r--r-- | src/CompilerKit/src/Assemblers/Assembler+AMD64.cc | 52 | ||||
| -rw-r--r-- | src/CompilerKit/src/Assemblers/Assembler+PowerPC.cc | 34 | ||||
| -rw-r--r-- | src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc | 10 | ||||
| -rw-r--r-- | src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc | 10 | ||||
| -rw-r--r-- | src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cc | 24 | ||||
| -rw-r--r-- | src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cc | 28 | ||||
| -rw-r--r-- | src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cc (renamed from src/CompilerKit/test/Linkers/DynamicLinker+PEF64.test.cc) | 2 | ||||
| -rw-r--r-- | src/CompilerKit/test/Linkers/ck-linker-test-posix.json | 3 |
10 files changed, 97 insertions, 85 deletions
diff --git a/include/CompilerKit/AE.h b/include/CompilerKit/AE.h index e96861c..777dc0b 100644 --- a/include/CompilerKit/AE.h +++ b/include/CompilerKit/AE.h @@ -11,9 +11,9 @@ #define kAEIdentVersion (0x0123) -#define kAEMag0 'H' +#define kAEMag0 'A' #define kAEMag1 'E' -#define kAEMag2 'Y' +#define kAEMag2 'O' #define kAESymbolLen (256) #define kAEPad (8) @@ -58,6 +58,11 @@ typedef struct AERecordHeader final { } PACKED AERecordHeader, *AERecordHeaderPtr; enum { + kKindImportSymbol = 0x356, + kKindExportSymbol = 0x237, +}; + +enum { kKindRelocationByOffset = 0x23f, kKindRelocationAtRuntime = 0x34f, }; diff --git a/include/CompilerKit/Utilities/Compiler.h b/include/CompilerKit/Utilities/Compiler.h index 97d1e9c..621f229 100644 --- a/include/CompilerKit/Utilities/Compiler.h +++ b/include/CompilerKit/Utilities/Compiler.h @@ -91,15 +91,7 @@ inline void drvi_crash_handler(std::int32_t id) { switch (id) { default: { - kStdOut << "SIGNAL: Unknown Signal (" << id << ")." << kBlank << std::endl; - break; - } - case SIGSEGV: { - kStdOut << "SIGNAL: Segmentation Fault." << kBlank << std::endl; - break; - } - case SIGABRT: { - kStdOut << "SIGNAL: Aborted." << kBlank << std::endl; + kStdOut << "SIGNAL: Signal (" << id << ")." << kBlank << std::endl; break; } } diff --git a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc index f6bbf2e..efe9b8c 100644 --- a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc +++ b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc @@ -115,23 +115,24 @@ NECTAR_MODULE(AssemblerMainAMD64) { for (size_t i = 1; i < argc; ++i) { if (argv[i][0] == '-') { - if (strcmp(argv[i], "--amd64:ver") == 0 || strcmp(argv[i], "--amd64:v") == 0) { - kStdOut << "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: " - "v1.10\nAssemblerAMD64: Copyright " - "(c) Amlal El Mahrouss\n"; + if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) { + kStdOut << "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: Copyright (c) 2024-2026 " + "Amlal El Mahrouss\n"; + kStdOut << "AssemblerAMD64: This Software is part of the NeKernel project. (nekernel.org)\n"; return 0; - } else if (strcmp(argv[i], "--amd64:h") == 0) { - kStdOut << "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: Copyright (c) 2024 " + } else if (strcmp(argv[i], "-help") == 0) { + kStdOut << "AssemblerAMD64: AMD64 Assembler Driver.\nAssemblerAMD64: Copyright (c) 2024-2026 " "Amlal El Mahrouss\n"; + kStdOut << "AssemblerAMD64: This Software is part of the NeKernel project. (nekernel.org)\n"; kStdOut << "--version: Print program version.\n"; kStdOut << "--verbose: Print verbose output.\n"; kStdOut << "--binary: Output as flat binary.\n"; return 0; - } else if (strcmp(argv[i], "--amd64:binary") == 0) { + } else if (strcmp(argv[i], "--fbinary") == 0) { kOutputAsBinary = true; continue; - } else if (strcmp(argv[i], "--amd64:verbose") == 0) { + } else if (strcmp(argv[i], "--fverbose") == 0) { kVerbose = true; continue; } @@ -192,7 +193,6 @@ NECTAR_MODULE(AssemblerMainAMD64) { if (kVerbose) { kStdOut << "Compiling: " + asm_input << "\n"; - kStdOut << "From: " + line << "\n"; } while (std::getline(file_ptr, line)) { @@ -366,13 +366,6 @@ static bool asm_read_attributes(std::string line) { kCurrentRecord.fKind = CompilerKit::kPefZero; } - // this is a special case for the start stub. - // we want this so that ld can find it. - - if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; - } - // now we can tell the code size of the previous kCurrentRecord. if (!kRecords.empty()) kRecords[kRecords.size() - 1].fSize = kAppBytes.size(); @@ -418,30 +411,17 @@ static bool asm_read_attributes(std::string line) { kDefinedSymbols.push_back(name); - if (name.find(".code64") != std::string::npos) { + if (name.find(kPefCode64) != std::string::npos) { // data is treated as code. - - name_copy.erase(name_copy.find(".code64"), strlen(".code64")); kCurrentRecord.fKind = CompilerKit::kPefCode; - } else if (name.find(".data64") != std::string::npos) { + } else if (name.find(kPefData64) != std::string::npos) { // no code will be executed from here. - - name_copy.erase(name_copy.find(".data64"), strlen(".data64")); kCurrentRecord.fKind = CompilerKit::kPefData; - } else if (name.find(".zero64") != std::string::npos) { + } else if (name.find(kPefZero64) != std::string::npos) { // this is a bss section. - - name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); kCurrentRecord.fKind = CompilerKit::kPefZero; } - // this is a special case for the start stub. - // we want this so that ld can find it. - - if (name == kPefStart) { - kCurrentRecord.fKind = CompilerKit::kPefCode; - } - while (name_copy.find(" ") != std::string::npos) name_copy.erase(name_copy.find(" "), 1); kOriginLabel.push_back(std::make_pair(name_copy, kOrigin)); @@ -1204,6 +1184,10 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { if (bits == 64 || bits == 32) { if (!hasRBasedRegs && bits >= 32) { kAppBytes.emplace_back(opcodeAMD64.fOpcode); + } else if (hasRBasedRegs && bits == 32) { + CompilerKit::Detail::print_error("Invalid combination of operands and registers.", + "CompilerKit"); + throw std::runtime_error("comb_op_reg"); } if (!onlyOneReg) kAppBytes.emplace_back(0x89); @@ -1808,7 +1792,9 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { kRegisterBitWidth = 32U; } else if (line.find("bits 16") != std::string::npos) { kRegisterBitWidth = 16U; - } else if (auto org_pos = line.find("org"); org_pos != std::string::npos) { + } + + if (auto org_pos = line.find("org"); org_pos != std::string::npos) { auto value_pos = org_pos + strlen("org") + 1; if (value_pos >= line.size()) { diff --git a/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cc b/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cc index 8f6119c..35d81b8 100644 --- a/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cc +++ b/src/CompilerKit/src/Assemblers/Assembler+PowerPC.cc @@ -290,15 +290,17 @@ static bool asm_read_attributes(std::string line) { result += name; - if (name.find(".code64") != std::string::npos) { + kCurrentRecord.fKind = CompilerKit::kKindImportSymbol; + + if (name.find(kPefCode64) != std::string::npos) { // data is treated as code. - kCurrentRecord.fKind = CompilerKit::kPefCode; - } else if (name.find(".data64") != std::string::npos) { + kCurrentRecord.fKind |= CompilerKit::kPefCode; + } else if (name.find(kPefData64) != std::string::npos) { // no code will be executed from here. - kCurrentRecord.fKind = CompilerKit::kPefData; - } else if (name.find(".zero64") != std::string::npos) { + kCurrentRecord.fKind |= CompilerKit::kPefData; + } else if (name.find(kPefZero64) != std::string::npos) { // this is a bss section. - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind |= CompilerKit::kPefZero; } // this is a special case for the start stub. @@ -341,21 +343,17 @@ static bool asm_read_attributes(std::string line) { if (j == ' ') j = '$'; } - if (name.find(".code64") != std::string::npos) { - // data is treated as code. + kCurrentRecord.fKind = CompilerKit::kKindExportSymbol; - name_copy.erase(name_copy.find(".code64"), strlen(".code64")); - kCurrentRecord.fKind = CompilerKit::kPefCode; - } else if (name.find(".data64") != std::string::npos) { + if (name.find(kPefCode64) != std::string::npos) { + // data is treated as code. + kCurrentRecord.fKind |= CompilerKit::kPefCode; + } else if (name.find(kPefData64) != std::string::npos) { // no code will be executed from here. - - name_copy.erase(name_copy.find(".data64"), strlen(".data64")); - kCurrentRecord.fKind = CompilerKit::kPefData; - } else if (name.find(".zero64") != std::string::npos) { + kCurrentRecord.fKind |= CompilerKit::kPefData; + } else if (name.find(kPefZero64) != std::string::npos) { // this is a bss section. - - name_copy.erase(name_copy.find(".zero64"), strlen(".zero64")); - kCurrentRecord.fKind = CompilerKit::kPefZero; + kCurrentRecord.fKind |= CompilerKit::kPefZero; } // this is a special case for the start stub. diff --git a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc b/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc index f2cbc04..53a27d2 100644 --- a/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc +++ b/src/CompilerKit/src/Compilers/NectarCompiler+AMD64.cc @@ -525,7 +525,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile( ++kFunctionEmbedLevel; kOriginMap.push_back({mangled_name, kOrigin}); - kOrigin += 2UL; // Account for prologue instructions + ++kOrigin; break; } @@ -836,7 +836,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile( break; } - if (valueOfVar.ends_with("{}")) valueOfVar = "rax"; // impl init. + if (valueOfVar.ends_with("{}")) valueOfVar = "rax"; // impl init returns back to rax. syntax_tree.fUserValue += instr + nectar_get_variable_ref(varName) + ", " + valueOfVar + "\n"; @@ -849,7 +849,7 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile( if (pos == CompilerKit::STLString::npos) { syntax_tree.fUserValue += nectar_generate_epilogue() + "ret\n"; - kOrigin += 2UL; + ++kOrigin; break; } @@ -882,10 +882,10 @@ CompilerKit::SyntaxLeafList::SyntaxLeaf CompilerFrontendNectarAMD64::Compile( } syntax_tree.fUserValue += nectar_generate_epilogue() + "ret\n"; - kOrigin += 2UL; + ++kOrigin; } catch (...) { syntax_tree.fUserValue += nectar_generate_epilogue() + "ret\n"; - kOrigin += 2UL; + ++kOrigin; } if (kCurrentIfCondition) { diff --git a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc b/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc index 0068350..87b14af 100644 --- a/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc +++ b/src/CompilerKit/src/Linkers/DynamicLinker64+MachO.cc @@ -86,7 +86,7 @@ static CompilerKit::STLString macho_extract_symbol_name(const CompilerKit::STLSt } /// @brief Add a symbol to the symbol table -static UInt32 AddSymbol(const CompilerKit::STLString& name, uint8_t type, uint8_t sect, +static UInt32 macho_add_symbol(const CompilerKit::STLString& name, uint8_t type, uint8_t sect, UInt64 value) { // Add name to string table (offset 0 is reserved for empty string) if (kStringTable.empty()) { @@ -256,16 +256,18 @@ NECTAR_MODULE(DynamicLinker64MachO) { if (!symbolName.empty()) { // Determine section number (1 = __text, 2 = __data) uint8_t sectNum = 0; - if (section.kind == CompilerKit::kPefCode) { + if (section.kind & CompilerKit::kPefCode) { sectNum = 1; // __text section - } else if (section.kind == CompilerKit::kPefData) { + } else if (section.kind & CompilerKit::kPefData) { sectNum = 2; // __data section + } else if (section.kind & CompilerKit::kPefZero) { + sectNum = 3; // __bss section } // N_EXT = external, N_SECT = defined in section uint8_t symType = N_EXT | N_SECT; - AddSymbol(symbolName, symType, sectNum, ae_records[ae_record_index].fOffset); + macho_add_symbol(symbolName, symType, sectNum, ae_records[ae_record_index].fOffset); if (kVerbose) { kConsoleOut << "Added symbol: " << symbolName diff --git a/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cc b/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cc index ab6a9fa..c2c17a8 100644 --- a/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cc +++ b/src/CompilerKit/src/Preprocessors/Preprocessor+Generic.cc @@ -30,7 +30,7 @@ typedef Int32 (*pp_parser_fn_t)(CompilerKit::STLString& line, std::ifstream& hdr ///////////////////////////////////////////////////////////////////////////////////////// namespace Detail { -enum { +enum PPOperatorType : Int32 { kInvalid = 0, kEqual = 100, kGreaterEqThan, @@ -83,7 +83,7 @@ static CompilerKit::STLString kWorkingDir = ""; int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro& macro, bool& inactive_code, bool& defined, CompilerKit::STLString& macro_str) { - if (cond.fType == Detail::kEqual) { + if (cond.fType == Detail::PPOperatorType::kEqual) { auto pos = macro_str.find(macro.fName); if (pos == CompilerKit::STLString::npos) return 0; @@ -184,7 +184,7 @@ int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro lhs = atol(number.c_str()); } - if (cond.fType == Detail::kGreaterThan) { + if (cond.fType == Detail::PPOperatorType::kGreaterThan) { if (lhs > rhs) { defined = true; inactive_code = false; @@ -195,7 +195,7 @@ int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro return 0; } - if (cond.fType == Detail::kGreaterEqThan) { + if (cond.fType == Detail::PPOperatorType::kGreaterEqThan) { if (lhs >= rhs) { defined = true; inactive_code = false; @@ -206,7 +206,7 @@ int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro return 0; } - if (cond.fType == Detail::kLesserEqThan) { + if (cond.fType == Detail::PPOperatorType::kLesserEqThan) { if (lhs <= rhs) { defined = true; inactive_code = false; @@ -217,7 +217,7 @@ int32_t pp_parse_if_condition(Detail::pp_macro_condition& cond, Detail::pp_macro return 0; } - if (cond.fType == Detail::kLesserThan) { + if (cond.fType == Detail::PPOperatorType::kLesserThan) { if (lhs < rhs) { defined = true; inactive_code = false; @@ -550,27 +550,27 @@ void pp_parse_file(std::ifstream& hdr_file, std::ofstream& pp_out) { std::vector<Detail::pp_macro_condition> pp_macro_condition_list = { { - .fType = Detail::kEqual, + .fType = Detail::PPOperatorType::kEqual, .fTypeName = "==", }, { - .fType = Detail::kNotEqual, + .fType = Detail::PPOperatorType::kNotEqual, .fTypeName = "!=", }, { - .fType = Detail::kLesserThan, + .fType = Detail::PPOperatorType::kLesserThan, .fTypeName = "<", }, { - .fType = Detail::kGreaterThan, + .fType = Detail::PPOperatorType::kGreaterThan, .fTypeName = ">", }, { - .fType = Detail::kLesserEqThan, + .fType = Detail::PPOperatorType::kLesserEqThan, .fTypeName = "<=", }, { - .fType = Detail::kGreaterEqThan, + .fType = Detail::PPOperatorType::kGreaterEqThan, .fTypeName = ">=", }, }; diff --git a/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cc b/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cc new file mode 100644 index 0000000..c6592dd --- /dev/null +++ b/src/CompilerKit/test/Linkers/DynamicLinker64+MachO.test.cc @@ -0,0 +1,28 @@ +// Copyright 2025-2026, Amlal El Mahrouss (amlal@nekernel.org) +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// Official repository: https://github.com/nekernel-org/nectar + +/// @author Amlal El Mahrouss + +#include <CompilerKit/Detail/Config.h> +#include <gtest/gtest.h> + +CK_IMPORT_C Int32 DynamicLinker64MachO(Int32 argc, Char** argv); + +static Int32 kArgc{}; +static Char** kArgv{}; + +Int32 main(Int32 argc, Char** argv) { + ::testing::InitGoogleTest(&argc, argv); + + kArgc = argc; + kArgv = argv; + + return RUN_ALL_TESTS(); +} + +TEST(LinkerRunMachO, LinkerExitsCorrectly) { + EXPECT_TRUE(kArgc > 1); + EXPECT_TRUE(DynamicLinker64MachO(kArgc, kArgv) == 0); +} diff --git a/src/CompilerKit/test/Linkers/DynamicLinker+PEF64.test.cc b/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cc index 1277cae..a32bae2 100644 --- a/src/CompilerKit/test/Linkers/DynamicLinker+PEF64.test.cc +++ b/src/CompilerKit/test/Linkers/DynamicLinker64+PEF.test.cc @@ -22,7 +22,7 @@ Int32 main(Int32 argc, Char** argv) { return RUN_ALL_TESTS(); } -TEST(LinkerRun, LinkerExitsCorrectly) { +TEST(LinkerRunPEF, LinkerExitsCorrectly) { EXPECT_TRUE(kArgc > 1); EXPECT_TRUE(DynamicLinker64PEF(kArgc, kArgv) == 0); } diff --git a/src/CompilerKit/test/Linkers/ck-linker-test-posix.json b/src/CompilerKit/test/Linkers/ck-linker-test-posix.json index 754367b..bebd381 100644 --- a/src/CompilerKit/test/Linkers/ck-linker-test-posix.json +++ b/src/CompilerKit/test/Linkers/ck-linker-test-posix.json @@ -9,7 +9,8 @@ "/usr/include/" ], "sources_path": [ - "DynamicLinker+PEF64.test.cc" + "DynamicLinker64+PEF64.test.cc", + "DynamicLinker64+MachO.test.cc" ], "output_name": "LinkerTest.o", "compiler_flags": [ |
