summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2026-01-08 10:00:55 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2026-01-08 10:00:55 +0100
commited4ad3ecdd446d2f60a9b671a43b0e7ec32f2a04 (patch)
treee7fc4efbec13b9d10dd029e1caf55a6c140a8d91
parent404d6901985ce7b87ae9fcfcbab16abc9c4bf180 (diff)
fix: Fix Issue #53 on AMD64 assembler.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
-rw-r--r--.gitignore8
-rw-r--r--src/CommandLine/asm.cc94
-rw-r--r--src/CommandLine/pef-amd64-asm.cc37
-rw-r--r--src/CommandLine/pef-amd64-asm.json (renamed from src/CommandLine/asm.json)10
-rw-r--r--src/CompilerKit/src/Assemblers/Assembler+AMD64.cc59
-rw-r--r--test/test_samples/sample.asm8
6 files changed, 89 insertions, 127 deletions
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 <CompilerKit/Detail/Config.h>
-#include <cstring>
-#include <vector>
-
-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<const Char*> 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/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 <CompilerKit/Detail/Config.h>
+#include <CompilerKit/ErrorID.h>
+#include <CompilerKit/Utilities/Compiler.h>
+#include <CompilerKit/Utilities/DLL.h>
+
+#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<CompilerKit::DLLLoader::EntryT>(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/asm.json b/src/CommandLine/pef-amd64-asm.json
index 7107c4b..060fbf3 100644
--- a/src/CommandLine/asm.json
+++ b/src/CommandLine/pef-amd64-asm.json
@@ -1,12 +1,12 @@
{
- "compiler_path": "clang++",
+ "compiler_path": "g++",
"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"],
+ "sources_path": ["pef-amd64-asm.cc"],
+ "output_name": "pef-amd64-asm",
+ "compiler_flags": ["-L/usr/lib"],
"cpp_macros": [
- "__ASM__=202401",
+ "__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 <CompilerKit/AE.h>
@@ -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
+