From ed4ad3ecdd446d2f60a9b671a43b0e7ec32f2a04 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 8 Jan 2026 10:00:55 +0100 Subject: fix: Fix Issue #53 on AMD64 assembler. Signed-off-by: Amlal El Mahrouss --- .gitignore | 8 +- src/CommandLine/asm.cc | 94 ----------------------- src/CommandLine/asm.json | 13 ---- src/CommandLine/pef-amd64-asm.cc | 37 +++++++++ src/CommandLine/pef-amd64-asm.json | 13 ++++ src/CompilerKit/src/Assemblers/Assembler+AMD64.cc | 59 +++++++++----- test/test_samples/sample.asm | 8 +- 7 files changed, 97 insertions(+), 135 deletions(-) delete mode 100644 src/CommandLine/asm.cc delete mode 100644 src/CommandLine/asm.json create mode 100644 src/CommandLine/pef-amd64-asm.cc create mode 100644 src/CommandLine/pef-amd64-asm.json diff --git a/.gitignore b/.gitignore index 7c8ade8..bdc5572 100644 --- a/.gitignore +++ b/.gitignore @@ -15,11 +15,9 @@ tools/cxxdrv src/*/dbg src/*/cppdrv src/*/kdbg -src/*/asm -src/*/pef-amd64-cxxdrv -src/*/pef-aarch64-cxxdrv -src/*/pef-aarch64-cdrv -src/*/pef-arm64-cdrv +src/*/pef-*-asm +src/*/pef-*-cxxdrv +src/*/pef-*-cdrv *.pp *.masm diff --git a/src/CommandLine/asm.cc b/src/CommandLine/asm.cc deleted file mode 100644 index 12d179a..0000000 --- a/src/CommandLine/asm.cc +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) -// Licensed under the Apache License, Version 2.0 (See accompanying -// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) -// Official repository: https://github.com/nekernel-org/nectar - -/// @file asm.cc -/// @brief Assembler frontend. - -#include -#include -#include - -CK_IMPORT_C Int32 AssemblerMainPower64(Int32 argc, Char const* argv[]); -CK_IMPORT_C Int32 AssemblerMainARM64(Int32 argc, Char const* argv[]); -CK_IMPORT_C Int32 AssemblerMain64x0(Int32 argc, Char const* argv[]); -CK_IMPORT_C Int32 AssemblerMainAMD64(Int32 argc, Char const* argv[]); - -enum AsmKind : Int32 { - kInvalidAssembler = 0, - kX64Assembler = 100, - k64X0Assembler, - kPOWER64Assembler, - kARM64Assembler, - kAssemblerCount = kARM64Assembler - kX64Assembler + 1, -}; - -Int32 main(Int32 argc, Char const* argv[]) { - std::vector arg_vec_cstr; - arg_vec_cstr.push_back(argv[0]); - - const Int32 kInvalidAssembler = -1; - Int32 asm_type = kInvalidAssembler; - - for (size_t index_arg = 1; index_arg < argc; ++index_arg) { - if (strcmp(argv[index_arg], "-asm-h") == 0) { - std::printf("asm: Frontend Assembler (64x0, power64, arm64, x64).\n"); - std::printf("asm: Version: %s, Release: %s.\n", kDistVersion, kDistRelease); - std::printf( - "asm: Designed by Amlal El Mahrouss, Copyright (C) 2024-2025 Amlal El Mahrouss, all " - "rights reserved.\n"); - std::printf( - "CompilerKit: Designed by Amlal El Mahrouss, Copyright (C) 2024-2025 Amlal El Mahrouss, " - "Licensed under the Apache 2.0 license.\n"); - - return 0; - } else if (strcmp(argv[index_arg], "-asm-x64") == 0) { - asm_type = kX64Assembler; - } else if (strcmp(argv[index_arg], "-asm-aarch64") == 0) { - asm_type = kARM64Assembler; - } else if (strcmp(argv[index_arg], "-asm-64x0") == 0) { - asm_type = k64X0Assembler; - } else if (strcmp(argv[index_arg], "-asm-power64") == 0) { - asm_type = kPOWER64Assembler; - } else { - arg_vec_cstr.push_back(argv[index_arg]); - } - } - - switch (asm_type) { - case kPOWER64Assembler: { - if (int32_t code = AssemblerMainPower64(arg_vec_cstr.size(), arg_vec_cstr.data()); code) { - std::printf("asm: frontend exited with code %i.\n", code); - return code; - } - break; - } - case k64X0Assembler: { - if (int32_t code = AssemblerMain64x0(arg_vec_cstr.size(), arg_vec_cstr.data()); code) { - std::printf("asm: frontend exited with code %i.\n", code); - return code; - } - break; - } - case kARM64Assembler: { - if (int32_t code = AssemblerMainARM64(arg_vec_cstr.size(), arg_vec_cstr.data()); code) { - std::printf("asm: frontend exited with code %i.\n", code); - return code; - } - break; - } - case kX64Assembler: { - if (int32_t code = AssemblerMainAMD64(arg_vec_cstr.size(), arg_vec_cstr.data()); code) { - std::printf("asm: frontend exited with code %i.\n", code); - return code; - } - break; - } - default: { - return EXIT_FAILURE; - } - } - - return EXIT_SUCCESS; -} diff --git a/src/CommandLine/asm.json b/src/CommandLine/asm.json deleted file mode 100644 index 7107c4b..0000000 --- a/src/CommandLine/asm.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compiler_path": "clang++", - "compiler_std": "c++20", - "headers_path": ["../../include/CompilerKit", "../../include", "../../include/CompilerKit/src/Detail"], - "sources_path": ["asm.cc"], - "output_name": "asm", - "compiler_flags": ["-L/usr/lib", "-lCompilerKit"], - "cpp_macros": [ - "__ASM__=202401", - "kDistReleaseBranch=$(git rev-parse --abbrev-ref HEAD)-$(uuidgen)" - ] -} - diff --git a/src/CommandLine/pef-amd64-asm.cc b/src/CommandLine/pef-amd64-asm.cc new file mode 100644 index 0000000..1316d93 --- /dev/null +++ b/src/CommandLine/pef-amd64-asm.cc @@ -0,0 +1,37 @@ +// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org) +// Licensed under the Apache License, Version 2.0 (See accompanying +// file LICENSE or copy at http://www.apache.org/licenses/LICENSE-2.0) +// Official repository: https://github.com/nekernel-org/nectar + +/// @file pef-amd64-asm.cc +/// @brief Nectar C++ frontend compiler for AMD64. + +#include +#include +#include +#include + +#ifdef __APPLE__ +static auto kPath = "/usr/local/lib/libCompilerKit.dylib"; +#else +static auto kPath = "/usr/lib/libCompilerKit.so"; +#endif + +static auto kSymbol = "AssemblerMainAMD64"; + +Int32 main(Int32 argc, Char const* argv[]) { + CompilerKit::DLLLoader dylib; + dylib(kPath, kSymbol); + + CompilerKit::DLLLoader::EntryT entrypoint_cxx = + reinterpret_cast(dylib.fEntrypoint); + + if (!entrypoint_cxx) { + kStdOut; + std::printf("error: Could not find entrypoint in %s: %s\n", kPath, dlerror()); + + return EXIT_FAILURE; + } + + return (entrypoint_cxx(argc, argv) == NECTAR_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/src/CommandLine/pef-amd64-asm.json b/src/CommandLine/pef-amd64-asm.json new file mode 100644 index 0000000..060fbf3 --- /dev/null +++ b/src/CommandLine/pef-amd64-asm.json @@ -0,0 +1,13 @@ +{ + "compiler_path": "g++", + "compiler_std": "c++20", + "headers_path": ["../../include/CompilerKit", "../../include", "../../include/CompilerKit/src/Detail"], + "sources_path": ["pef-amd64-asm.cc"], + "output_name": "pef-amd64-asm", + "compiler_flags": ["-L/usr/lib"], + "cpp_macros": [ + "__DRV_ASM__=202601", + "kDistReleaseBranch=$(git rev-parse --abbrev-ref HEAD)-$(uuidgen)" + ] +} + diff --git a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc index 85033dc..096ebc1 100644 --- a/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc +++ b/src/CompilerKit/src/Assemblers/Assembler+AMD64.cc @@ -24,7 +24,7 @@ #define __ASM_NEED_AMD64__ #endif -#define kAssemblerPragmaSymStr "%%" +#define kAssemblerPragmaSymStr "%" #define kAssemblerPragmaSym '%' #include @@ -203,12 +203,12 @@ NECTAR_MODULE(AssemblerMainAMD64) { } while (std::getline(file_ptr, line)) { - if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) { - CompilerKit::Detail::print_error(ln, argv[i]); - continue; - } - try { + if (auto ln = asm64.CheckLine(line, argv[i]); !ln.empty()) { + CompilerKit::Detail::print_error(ln, argv[i]); + continue; + } + asm_read_attributes(line); asm64.WriteLine(line, argv[i]); } catch (const std::exception& e) { @@ -343,7 +343,15 @@ static bool asm_read_attributes(std::string line) { throw std::runtime_error("invalid_extern_segment_bin"); } - auto name = line.substr(line.find("extern_segment") + strlen("extern_segment") + 1); + auto pos = line.find("extern_segment"); + auto name_pos = pos + strlen("extern_segment") + 1; + + if (pos == std::string::npos || name_pos >= line.size()) { + CompilerKit::Detail::print_error("Invalid extern_segment", "power-as"); + throw std::runtime_error("invalid_extern_segment"); + } + + auto name = line.substr(name_pos); if (name.size() == 0) { CompilerKit::Detail::print_error("Invalid extern_segment", "power-as"); @@ -402,7 +410,13 @@ static bool asm_read_attributes(std::string line) { throw std::runtime_error("invalid_public_segment_bin"); } - auto name = line.substr(line.find("public_segment") + strlen("public_segment") + 1); + auto res_sym_at = (line.find("public_segment") + strlen("public_segment") + 1); + if (res_sym_at > line.size()) { + CompilerKit::Detail::print_error("Invalid symbol for public_segment.", "CompilerKit"); + throw std::runtime_error("invalid_public_segment_symbol"); + } + + auto name = line.substr(res_sym_at); std::string name_copy = name; @@ -473,7 +487,7 @@ static inline bool is_not_valid(char c) { if ((isalpha(c) || isdigit(c)) || ((c == ' ') || (c == '\t') || (c == ',') || (c == '(') || (c == ')') || (c == '"') || (c == '*') || (c == '\'') || (c == '[') || (c == ']') || (c == '+') || (c == '_') || - (c == ':') || (c == '@') || (c == '.') || (c == '#') || (c == ';'))) + (c == ':') || (c == '@') || (c == '.') || (c == '#') || (c == '%') || (c == '~') || (c == ';'))) return false; return true; @@ -571,7 +585,7 @@ bool CompilerKit::EncoderAMD64::WriteNumber(const std::size_t& pos, std::string& CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtol(jump_label.substr(pos + 2).c_str(), nullptr, 16)); - for (char& i : num.number) { + for (auto& i : num.number) { if (i == 0) i = 0xFF; kAppBytes.push_back(i); @@ -1170,13 +1184,18 @@ 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 (line.find("org") != std::string::npos) { + } else 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()) { + CompilerKit::Detail::print_error("Invalid org directive", "CompilerKit"); + throw std::runtime_error("invalid_org"); + } + size_t base[] = {10, 16, 2, 7}; for (size_t i = 0; i < 4; i++) { - if (kOrigin = strtol((line.substr(line.find("org") + strlen("org") + 1)).c_str(), nullptr, - base[i]); - kOrigin) { + if (kOrigin = strtol(line.substr(value_pos).c_str(), nullptr, base[i]); kOrigin) { if (errno != 0) { continue; } else { @@ -1191,16 +1210,16 @@ bool CompilerKit::EncoderAMD64::WriteLine(std::string line, std::string file) { } } /// write a dword - else if (line.find(".dword") != std::string::npos) { - this->WriteNumber32(line.find(".dword") + strlen(".dword") + 1, line); + else if (auto pos = line.find(".dword"); pos != std::string::npos) { + this->WriteNumber32(pos + strlen(".dword") + 1, line); } /// write a long - else if (line.find(".long") != std::string::npos) { - this->WriteNumber(line.find(".long") + strlen(".long") + 1, line); + else if (auto pos = line.find(".long"); pos != std::string::npos) { + this->WriteNumber(pos + strlen(".long") + 1, line); } /// write a 16-bit number - else if (line.find(".word") != std::string::npos) { - this->WriteNumber16(line.find(".word") + strlen(".word") + 1, line); + else if (auto pos = line.find(".word"); pos != std::string::npos) { + this->WriteNumber16(pos + strlen(".word") + 1, line); } kOrigin += kIPAlignement; diff --git a/test/test_samples/sample.asm b/test/test_samples/sample.asm index 6b622f7..72b1a46 100644 --- a/test/test_samples/sample.asm +++ b/test/test_samples/sample.asm @@ -1,5 +1,7 @@ -;; \note This should compile. +%bits 64 +%org 0x40000000 + public_segment .code64 __ImageStart - ;; rax is the return value register. mov rax, 5 - ret \ No newline at end of file + ret + -- cgit v1.2.3