From ea991f7e7c882c6e36ed2f6042d025edc9baf49f Mon Sep 17 00:00:00 2001 From: Amlal Date: Sun, 4 May 2025 12:31:10 +0200 Subject: bug(LibCompiler/C++): Segfault raised when compiling C++ source. Signed-off-by: Amlal --- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index b4725a4..0afdf3e 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -837,7 +837,7 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { delete kState.fSyntaxTree; kState.fSyntaxTree = nullptr; - if (kAcceptableErrors > 0) return 1; + if (kAcceptableErrors > 0) return kExitNO; return kExitOK; } @@ -928,8 +928,8 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { kErrorLimit = 100; - kFactory.Mount(new AssemblyCPlusPlusInterface()); kCompilerFrontend = new CompilerFrontendCPlusPlus(); + kFactory.Mount(new AssemblyCPlusPlusInterface()); ::signal(SIGSEGV, Detail::segfault_handler); -- cgit v1.2.3 From 352fbc89ec1323ef92db81dd52175ac086352cfa Mon Sep 17 00:00:00 2001 From: Amlal Date: Sun, 4 May 2025 19:15:24 +0200 Subject: bug(cxxdrv): isolating segfault on cxxdrv. Signed-off-by: Amlal --- dev/LibCompiler/Detail/ClUtils.h | 3 +- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 77 +++++++-------------------- 2 files changed, 21 insertions(+), 59 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/Detail/ClUtils.h b/dev/LibCompiler/Detail/ClUtils.h index 5ec9857..feb17fc 100644 --- a/dev/LibCompiler/Detail/ClUtils.h +++ b/dev/LibCompiler/Detail/ClUtils.h @@ -51,8 +51,7 @@ inline void print_warning(std::string reason, std::string file) noexcept { /// @internal inline void segfault_handler(std::int32_t _) { - pfd::notify("LibCompiler", - "Driver just crashed, please report this to the developers."); + pfd::notify("LibCompiler", "Driver just crashed, please report this to the developers."); std::exit(LIBCOMPILER_EXEC_ERROR); } } // namespace Detail diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 0afdf3e..38b6ecf 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -27,7 +27,7 @@ /* This is part of the LibCompiler. */ /* (c) Amlal El Mahrouss */ -/// @author EL Mahrouss Amlal (amlel) +/// @author EL Mahrouss Amlal (amlal@nekernel.org) /// @file CPlusPlusCompilerAMD64.cxx /// @brief Optimized C++ Compiler Driver. /// @todo Throw error for scoped inside scoped variables when they get referenced outside. @@ -86,8 +86,7 @@ struct CompilerStructMap final { struct CompilerState final { std::vector fStackMapVector; std::vector fStructMapVector; - LibCompiler::SyntaxLeafList* fSyntaxTree{nullptr}; - std::unique_ptr fOutputAssembly; + std::ofstream fOutputAssembly; std::string fLastFile; std::string fLastError; Boolean fVerbose; @@ -178,9 +177,8 @@ const char* CompilerFrontendCPlusPlus::Language() { return "NeKernel C++"; } -static std::uintptr_t kOrigin = 0x1000000; - -std::vector> kOriginMap; +static std::uintptr_t kOrigin = 0x1000000; +static std::vector> kOriginMap; ///////////////////////////////////////////////////////////////////////////////////////// @@ -190,7 +188,7 @@ std::vector> kOriginMap; ///////////////////////////////////////////////////////////////////////////////////////// Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string file) { - if (text.empty()) return true; + if (text.empty()) return false; // Clean whitespace and tabs std::string cleanLine = text; @@ -201,7 +199,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f // Skip empty, doc, or block comment lines if (cleanLine.empty() || cleanLine.starts_with("///") || cleanLine.starts_with("//") || cleanLine.starts_with("/*")) - return true; + return false; std::size_t index = 0UL; std::vector> keywords_list; @@ -276,6 +274,8 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f size_t i = right.size() - 1; + if (i < 1) break; + try { while (!std::isalnum(right[i])) { right.erase(i, 1); @@ -731,7 +731,8 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f } syntax_tree.fUserData = keyword.first; - kState.fSyntaxTree->fLeafList.push_back(syntax_tree); + + kState.fOutputAssembly << syntax_tree.fUserValue; } lc_compile_ok: @@ -769,53 +770,21 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { std::string dest = src_file; dest += cExts[2]; - if (dest.empty()) { - dest = "CXX-LibCompiler-"; - - std::random_device rd; - auto seed_data = std::array{}; - - std::generate(std::begin(seed_data), std::end(seed_data), std::ref(rd)); - - std::seed_seq seq(std::begin(seed_data), std::end(seed_data)); - std::mt19937 generator(seq); + kState.fOutputAssembly.open(dest); - auto gen = uuids::uuid_random_generator(generator); - - auto id = gen(); - dest += uuids::to_string(id); - } - - kState.fOutputAssembly = std::make_unique(dest); + if (!kState.fOutputAssembly.good()) return kExitNO; auto fmt = LibCompiler::current_date(); - (*kState.fOutputAssembly) << "; Repository Path: /" << src_file << "\n"; - - std::filesystem::path path = std::filesystem::path("./"); - - while (path != Detail::expand_home(std::filesystem::path("~"))) { - for (auto const& dir_entry : std::filesystem::recursive_directory_iterator{path}) { - if (dir_entry.is_directory() && dir_entry.path().string().find(".git") != std::string::npos) - goto break_loop; - } - - path = path.parent_path(); - break_loop: - (*kState.fOutputAssembly) << "; Repository Style: Git\n"; - break; - } - std::stringstream stream; stream << kOrigin; + std::string result(stream.str()); - (*kState.fOutputAssembly) + kState.fOutputAssembly << "; Assembler Dialect: AMD64 LibCompiler Assembler. (Generated from C++)\n"; - (*kState.fOutputAssembly) << "; Date: " << fmt << "\n"; - (*kState.fOutputAssembly) << "#bits 64\n#org " + result << "\n"; - - kState.fSyntaxTree = new LibCompiler::SyntaxLeafList(); + kState.fOutputAssembly << "; Date: " << fmt << "\n" + << "#bits 64\n#org " + result << "\n"; // =================================== // Parse source file. @@ -824,18 +793,12 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { std::string line_source; while (std::getline(src_fp, line_source)) { + kStdOut << line_source; kCompilerFrontend->Compile(line_source, src); } - for (auto& ast_generated : kState.fSyntaxTree->fLeafList) { - (*kState.fOutputAssembly) << ast_generated.fUserValue; - } - - kState.fOutputAssembly->flush(); - kState.fOutputAssembly->close(); - - delete kState.fSyntaxTree; - kState.fSyntaxTree = nullptr; + kState.fOutputAssembly.flush(); + kState.fOutputAssembly.close(); if (kAcceptableErrors > 0) return kExitNO; @@ -993,7 +956,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { Detail::print_error(argv_i + " is not a valid C++ source.\n", "cxxdrv"); } - return 1; + return kExitNO; } kStdOut << "CPlusPlusCompilerAMD64: Building: " << argv[index] << std::endl; -- cgit v1.2.3 From 23d3e00324b7f691a893df7e73462b9b73c03a4f Mon Sep 17 00:00:00 2001 From: Amlal Date: Sun, 4 May 2025 23:13:10 +0200 Subject: feat(cxxdrv): small optimizations regarding variable and useless logging. Signed-off-by: Amlal --- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 38b6ecf..f5e9bf7 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -774,17 +774,10 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { if (!kState.fOutputAssembly.good()) return kExitNO; - auto fmt = LibCompiler::current_date(); - - std::stringstream stream; - stream << kOrigin; - - std::string result(stream.str()); - kState.fOutputAssembly << "; Assembler Dialect: AMD64 LibCompiler Assembler. (Generated from C++)\n"; - kState.fOutputAssembly << "; Date: " << fmt << "\n" - << "#bits 64\n#org " + result << "\n"; + kState.fOutputAssembly << "; Date: " << LibCompiler::current_date() << "\n" + << "#bits 64\n#org " << kOrigin << "\n"; // =================================== // Parse source file. @@ -793,7 +786,6 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { std::string line_source; while (std::getline(src_fp, line_source)) { - kStdOut << line_source; kCompilerFrontend->Compile(line_source, src); } -- cgit v1.2.3 From d8d943929c25151fd6a8aadd6ea4cdbd5065845a Mon Sep 17 00:00:00 2001 From: Amlal Date: Wed, 7 May 2025 09:18:33 +0200 Subject: feat(LibCompiler): Reworking architecture to integrate the Arch() method in the AssemblyInterface. Signed-off-by: Amlal --- dev/LibCompiler/AssemblyInterface.h | 34 ++++--- dev/LibCompiler/Detail/ClUtils.h | 2 +- dev/LibCompiler/ErrorID.h | 1 + dev/LibCompiler/Parser.h | 2 +- .../src/AssemblyFactory+AssemblyInterface.cc | 51 ++++++++++ dev/LibCompiler/src/AssemblyFactory.cc | 51 ---------- dev/LibCompiler/src/CCompiler64x0.cc | 10 +- dev/LibCompiler/src/CCompilerARM64.cc | 8 +- dev/LibCompiler/src/CCompilerPower64.cc | 8 +- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 107 ++++++--------------- 10 files changed, 113 insertions(+), 161 deletions(-) create mode 100644 dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc delete mode 100644 dev/LibCompiler/src/AssemblyFactory.cc (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/AssemblyInterface.h b/dev/LibCompiler/AssemblyInterface.h index 5450f84..b612962 100644 --- a/dev/LibCompiler/AssemblyInterface.h +++ b/dev/LibCompiler/AssemblyInterface.h @@ -13,19 +13,8 @@ #define ASSEMBLY_INTERFACE : public LibCompiler::AssemblyInterface namespace LibCompiler { -/// @brief Assembly to binary generator class. -/// @note This interface creates according to the CPU target of the child class. -class AssemblyInterface { - public: - explicit AssemblyInterface() = default; - virtual ~AssemblyInterface() = default; - - LIBCOMPILER_COPY_DEFAULT(AssemblyInterface); - - /// @brief compile to object file. - /// @note Example C++ -> MASM -> AE object. - virtual Int32 CompileToFormat(std::string src, Int32 arch) = 0; -}; +class AssemblyFactory; +class AssemblyInterface; /// @brief Simple assembly factory class AssemblyFactory final { @@ -37,7 +26,8 @@ class AssemblyFactory final { public: enum { - kArchAMD64, + kArchInvalid = 0, + kArchAMD64 = 100, kArch32x0, kArch64x0, kArchRISCV, @@ -55,6 +45,22 @@ class AssemblyFactory final { AssemblyInterface* fMounted{nullptr}; }; +/// @brief Assembly to binary generator class. +/// @note This interface creates according to the CPU target of the child class. +class AssemblyInterface { + public: + explicit AssemblyInterface() = default; + virtual ~AssemblyInterface() = default; + + LIBCOMPILER_COPY_DEFAULT(AssemblyInterface); + + [[maybe_unused]] virtual Int32 Arch() noexcept { return AssemblyFactory::kArchAMD64; } + + /// @brief compile to object file. + /// @note Example C++ -> MASM -> AE object. + virtual Int32 CompileToFormat(std::string src, Int32 arch) = 0; +}; + union NumberCastBase { NumberCastBase() = default; ~NumberCastBase() = default; diff --git a/dev/LibCompiler/Detail/ClUtils.h b/dev/LibCompiler/Detail/ClUtils.h index feb17fc..f47101a 100644 --- a/dev/LibCompiler/Detail/ClUtils.h +++ b/dev/LibCompiler/Detail/ClUtils.h @@ -51,7 +51,7 @@ inline void print_warning(std::string reason, std::string file) noexcept { /// @internal inline void segfault_handler(std::int32_t _) { - pfd::notify("LibCompiler", "Driver just crashed, please report this to the developers."); + pfd::notify("LibCompiler", "Driver just crashed, please report this on the GitHub issues page."); std::exit(LIBCOMPILER_EXEC_ERROR); } } // namespace Detail diff --git a/dev/LibCompiler/ErrorID.h b/dev/LibCompiler/ErrorID.h index 380fa69..45bb393 100644 --- a/dev/LibCompiler/ErrorID.h +++ b/dev/LibCompiler/ErrorID.h @@ -21,3 +21,4 @@ #define LIBCOMPILER_INVALID_DATA -35 #define LIBCOMPILER_UNIMPLEMENTED -36 #define LIBCOMPILER_FAT_ERROR -37 +#define LIBCOMPILER_INVALID_ARCH -38 diff --git a/dev/LibCompiler/Parser.h b/dev/LibCompiler/Parser.h index 64c46d6..6baff7e 100644 --- a/dev/LibCompiler/Parser.h +++ b/dev/LibCompiler/Parser.h @@ -26,7 +26,7 @@ class ICompilerFrontend { //! @brief Compile a syntax tree ouf of the text. //! Also takes the source file name for metadata. - virtual bool Compile(std::string text, const std::string file) = 0; + virtual bool Compile(std::string text, std::string file) = 0; //! @brief What language are we dealing with? virtual const char* Language() { return kInvalidFrontend; } diff --git a/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc b/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc new file mode 100644 index 0000000..11655fb --- /dev/null +++ b/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc @@ -0,0 +1,51 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved + +------------------------------------------- */ + +#include +#include + +/** + * @file AssemblyFactory.cxx + * @author amlal (amlal@nekernel.org) + * @brief Assembler Kit + * @version 0.1 + * @date 2024-01-27 + * + * @copyright Copyright (c) 2024-2025 Amlal El Mahrouss + * + */ + +//! @file Asm.cpp +//! @brief AssemblyKit source implementation. + +namespace LibCompiler { +///! @brief Compile for specific format (ELF, PEF, ZBIN) +Int32 AssemblyFactory::Compile(std::string sourceFile, const Int32& arch) noexcept { + if (sourceFile.length() < 1 || !fMounted) return LIBCOMPILER_UNIMPLEMENTED; + + if (arch != fMounted->Arch()) return LIBCOMPILER_INVALID_ARCH; + + return fMounted->CompileToFormat(sourceFile, arch); +} + +///! @brief mount assembly backend. +void AssemblyFactory::Mount(AssemblyInterface* mountPtr) noexcept { + if (mountPtr) { + fMounted = mountPtr; + } +} + +///! @brief Unmount assembler. +AssemblyInterface* AssemblyFactory::Unmount() noexcept { + auto mount_prev = fMounted; + + if (mount_prev) { + fMounted = nullptr; + } + + return mount_prev; +} +} // namespace LibCompiler diff --git a/dev/LibCompiler/src/AssemblyFactory.cc b/dev/LibCompiler/src/AssemblyFactory.cc deleted file mode 100644 index 8fa12a8..0000000 --- a/dev/LibCompiler/src/AssemblyFactory.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025 Amlal EL Mahrous, all rights reserved - -------------------------------------------- */ - -#include -#include - -/** - * @file AssemblyFactory.cxx - * @author amlal (amlal@nekernel.org) - * @brief Assembler Kit - * @version 0.1 - * @date 2024-01-27 - * - * @copyright Copyright (c) 2024-2025 Amlal El Mahrouss - * - */ - -#include - -//! @file Asm.cpp -//! @brief AssemblyKit source implementation. - -namespace LibCompiler { -///! @brief Compile for specific format (ELF, PEF, ZBIN) -Int32 AssemblyFactory::Compile(std::string sourceFile, const Int32& arch) noexcept { - if (sourceFile.length() < 1 || !fMounted) return LIBCOMPILER_UNIMPLEMENTED; - - return fMounted->CompileToFormat(sourceFile, arch); -} - -///! @brief mount assembly backend. -void AssemblyFactory::Mount(AssemblyInterface* mountPtr) noexcept { - if (mountPtr) { - fMounted = mountPtr; - } -} - -///! @brief Unmount assembler. -AssemblyInterface* AssemblyFactory::Unmount() noexcept { - auto mount_prev = fMounted; - - if (mount_prev) { - fMounted = nullptr; - } - - return mount_prev; -} -} // namespace LibCompiler diff --git a/dev/LibCompiler/src/CCompiler64x0.cc b/dev/LibCompiler/src/CCompiler64x0.cc index c100e96..79d32ce 100644 --- a/dev/LibCompiler/src/CCompiler64x0.cc +++ b/dev/LibCompiler/src/CCompiler64x0.cc @@ -142,7 +142,7 @@ class CompilerFrontend64x0 final : public LibCompiler::ICompilerFrontend { LIBCOMPILER_COPY_DEFAULT(CompilerFrontend64x0); std::string Check(const char* text, const char* file); - bool Compile(std::string text, const std::string file) override; + bool Compile(std::string text, std::string file) override; const char* Language() override { return "64k C"; } }; @@ -182,7 +182,7 @@ union double_cast final { ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerFrontend64x0::Compile(std::string text_, const std::string file) { +bool CompilerFrontend64x0::Compile(std::string text_, std::string file) { std::string text = text_; bool typeFound = false; @@ -1051,11 +1051,11 @@ class AssemblyCCInterface final ASSEMBLY_INTERFACE { LIBCOMPILER_COPY_DEFAULT(AssemblyCCInterface); - [[maybe_unused]] static Int32 Arch() noexcept { return LibCompiler::AssemblyFactory::kArch64x0; } + [[maybe_unused]] Int32 Arch() noexcept override { + return LibCompiler::AssemblyFactory::kArch64x0; + } Int32 CompileToFormat(std::string src, Int32 arch) override { - if (arch != AssemblyCCInterface::Arch()) return 1; - if (kCompilerFrontend == nullptr) return 1; /* @brief copy contents wihtout extension */ diff --git a/dev/LibCompiler/src/CCompilerARM64.cc b/dev/LibCompiler/src/CCompilerARM64.cc index a992349..a5ddf43 100644 --- a/dev/LibCompiler/src/CCompilerARM64.cc +++ b/dev/LibCompiler/src/CCompilerARM64.cc @@ -142,7 +142,7 @@ class CompilerFrontendARM64 final : public LibCompiler::ICompilerFrontend { LIBCOMPILER_COPY_DEFAULT(CompilerFrontendARM64); std::string Check(const char* text, const char* file); - bool Compile(std::string text, const std::string file) override; + bool Compile(std::string text, std::string file) override; const char* Language() override { return "64k C"; } }; @@ -182,7 +182,7 @@ union double_cast final { ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerFrontendARM64::Compile(std::string text, const std::string file) { +bool CompilerFrontendARM64::Compile(std::string text, std::string file) { bool typeFound = false; bool fnFound = false; @@ -1049,13 +1049,11 @@ class AssemblyCCInterface final ASSEMBLY_INTERFACE { LIBCOMPILER_COPY_DEFAULT(AssemblyCCInterface); - [[maybe_unused]] static Int32 Arch() noexcept { + [[maybe_unused]] Int32 Arch() noexcept override { return LibCompiler::AssemblyFactory::kArchAARCH64; } Int32 CompileToFormat(std::string src, Int32 arch) override { - if (arch != AssemblyCCInterface::Arch()) return 1; - if (kCompilerFrontend == nullptr) return 1; /* @brief copy contents wihtout extension */ diff --git a/dev/LibCompiler/src/CCompilerPower64.cc b/dev/LibCompiler/src/CCompilerPower64.cc index c65f575..f2eba43 100644 --- a/dev/LibCompiler/src/CCompilerPower64.cc +++ b/dev/LibCompiler/src/CCompilerPower64.cc @@ -133,7 +133,7 @@ class CompilerFrontendPower64 final : public LibCompiler::ICompilerFrontend { LIBCOMPILER_COPY_DEFAULT(CompilerFrontendPower64); std::string Check(const char* text, const char* file); - bool Compile(std::string text, const std::string file) override; + bool Compile(std::string text, std::string file) override; const char* Language() override { return "POWER C"; } }; @@ -173,7 +173,7 @@ union double_cast final { ///////////////////////////////////////////////////////////////////////////////////////// -bool CompilerFrontendPower64::Compile(std::string text_, const std::string file) { +bool CompilerFrontendPower64::Compile(std::string text_, std::string file) { std::string text = text_; bool typeFound = false; @@ -1069,13 +1069,11 @@ class AssemblyMountpointCLang final ASSEMBLY_INTERFACE { LIBCOMPILER_COPY_DEFAULT(AssemblyMountpointCLang); - [[maybe_unused]] static Int32 Arch() noexcept { + [[maybe_unused]] Int32 Arch() noexcept override { return LibCompiler::AssemblyFactory::kArchPowerPC; } Int32 CompileToFormat(std::string src, Int32 arch) override { - if (arch != AssemblyMountpointCLang::Arch()) return 1; - if (kCompilerFrontend == nullptr) return 1; /* @brief copy contents wihtout extension */ diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index f5e9bf7..344622e 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -148,7 +148,7 @@ class CompilerFrontendCPlusPlus final : public LibCompiler::ICompilerFrontend { LIBCOMPILER_COPY_DEFAULT(CompilerFrontendCPlusPlus); - Boolean Compile(const std::string text, const std::string file) override; + Boolean Compile(const std::string text, std::string file) override; const char* Language() override; }; @@ -174,7 +174,7 @@ static std::size_t kFunctionEmbedLevel = 0UL; /// detail namespaces const char* CompilerFrontendCPlusPlus::Language() { - return "NeKernel C++"; + return "AMD64 C++"; } static std::uintptr_t kOrigin = 0x1000000; @@ -187,37 +187,15 @@ static std::vector> kOriginMap; ///////////////////////////////////////////////////////////////////////////////////////// -Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string file) { +Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) { if (text.empty()) return false; - // Clean whitespace and tabs - std::string cleanLine = text; - cleanLine.erase(std::remove(cleanLine.begin(), cleanLine.end(), '\t'), cleanLine.end()); - cleanLine.erase(0, cleanLine.find_first_not_of(" \r\n")); - cleanLine.erase(cleanLine.find_last_not_of(" \r\n") + 1); - - // Skip empty, doc, or block comment lines - if (cleanLine.empty() || cleanLine.starts_with("///") || cleanLine.starts_with("//") || - cleanLine.starts_with("/*")) - return false; - std::size_t index = 0UL; std::vector> keywords_list; - Boolean found = false; - static Boolean commentBlock = false; - for (auto& keyword : kKeywords) { if (text.find(keyword.keyword_name) != std::string::npos) { switch (keyword.keyword_kind) { - case LibCompiler::kKeywordKindCommentMultiLineStart: { - commentBlock = true; - return true; - } - case LibCompiler::kKeywordKindCommentMultiLineEnd: { - commentBlock = false; - break; - } case LibCompiler::kKeywordKindCommentInline: { break; } @@ -239,22 +217,13 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f keywords_list.emplace_back(std::make_pair(keyword, index)); ++index; - - found = true; } } - if (!found && !commentBlock) { - for (size_t i = 0; i < text.size(); i++) { - if (isalnum(text[i])) { - Detail::print_error("syntax error: " + text, file); - return NO; - } - } - } + auto syntax_tree = LibCompiler::SyntaxLeafList::SyntaxLeaf(); for (auto& keyword : keywords_list) { - auto syntax_tree = LibCompiler::SyntaxLeafList::SyntaxLeaf(); + kStdOut << keyword.second; switch (keyword.first.keyword_kind) { case LibCompiler::KeywordKind::kKeywordKindClass: { @@ -408,10 +377,10 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f return fnName == pair.first; }); - std::stringstream ss; - ss << std::hex << it->second; - if (it != kOriginMap.end()) { + std::stringstream ss; + ss << std::hex << it->second; + syntax_tree.fUserValue = "jmp " + ss.str() + "\n"; kOrigin += 1UL; } @@ -506,12 +475,12 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f valueOfVar.erase(i, 1); } - constexpr auto cTrueVal = "true"; - constexpr auto cFalseVal = "false"; + constexpr auto kTrueVal = "true"; + constexpr auto kFalseVal = "false"; - if (valueOfVar == cTrueVal) { + if (valueOfVar == kTrueVal) { valueOfVar = "1"; - } else if (valueOfVar == cFalseVal) { + } else if (valueOfVar == kFalseVal) { valueOfVar = "0"; } @@ -620,14 +589,14 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f valueOfVar.erase(valueOfVar.find("\t"), 1); } - constexpr auto cTrueVal = "true"; - constexpr auto cFalseVal = "false"; + constexpr auto kTrueVal = "true"; + constexpr auto kFalseVal = "false"; /// interpet boolean values, since we're on C++ - if (valueOfVar == cTrueVal) { + if (valueOfVar == kTrueVal) { valueOfVar = "1"; - } else if (valueOfVar == cFalseVal) { + } else if (valueOfVar == kFalseVal) { valueOfVar = "0"; } @@ -726,16 +695,15 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, const std::string f } } default: { - break; + continue; } } - syntax_tree.fUserData = keyword.first; - - kState.fOutputAssembly << syntax_tree.fUserValue; + break; } lc_compile_ok: + kState.fOutputAssembly << syntax_tree.fUserValue; return true; } @@ -754,37 +722,23 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { LIBCOMPILER_COPY_DEFAULT(AssemblyCPlusPlusInterface); - [[maybe_unused]] static Int32 Arch() noexcept { return LibCompiler::AssemblyFactory::kArchAMD64; } + [[maybe_unused]] Int32 Arch() noexcept override { + return LibCompiler::AssemblyFactory::kArchAMD64; + } Int32 CompileToFormat(std::string src, Int32 arch) override { - if (arch != AssemblyCPlusPlusInterface::Arch()) return 1; - - if (kCompilerFrontend == nullptr) return 1; + if (kCompilerFrontend == nullptr) return kExitNO; /* @brief copy contents wihtout extension */ - std::string src_file = src; - std::ifstream src_fp = std::ifstream(src_file, std::ios::in); + std::ifstream src_fp = std::ifstream(src, std::ios::in); - const char* cExts[] = kAsmFileExts; + std::string dest = src; + dest += ".masm"; - std::string dest = src_file; - dest += cExts[2]; + std::string line_source; kState.fOutputAssembly.open(dest); - if (!kState.fOutputAssembly.good()) return kExitNO; - - kState.fOutputAssembly - << "; Assembler Dialect: AMD64 LibCompiler Assembler. (Generated from C++)\n"; - kState.fOutputAssembly << "; Date: " << LibCompiler::current_date() << "\n" - << "#bits 64\n#org " << kOrigin << "\n"; - - // =================================== - // Parse source file. - // =================================== - - std::string line_source; - while (std::getline(src_fp, line_source)) { kCompilerFrontend->Compile(line_source, src); } @@ -951,12 +905,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { return kExitNO; } - kStdOut << "CPlusPlusCompilerAMD64: Building: " << argv[index] << std::endl; - - if (kFactory.Compile(argv_i, kMachine) != kExitOK) { - kStdOut << "CPlusPlusCompilerAMD64: Failed to build: " << argv[index] << std::endl; - return kExitNO; - } + kFactory.Compile(argv_i, kMachine); } return kExitOK; -- cgit v1.2.3 From b4155efdeb3df35080e3e14ab7a618de97164eea Mon Sep 17 00:00:00 2001 From: Amlal Date: Fri, 9 May 2025 13:17:23 +0200 Subject: dev(cxxdrv): figured out where the segfault comes from, probably the call to Compile who causes the issue. Signed-off-by: Amlal --- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 344622e..c0dc281 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -220,11 +220,9 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) { } } - auto syntax_tree = LibCompiler::SyntaxLeafList::SyntaxLeaf(); + static LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree; for (auto& keyword : keywords_list) { - kStdOut << keyword.second; - switch (keyword.first.keyword_kind) { case LibCompiler::KeywordKind::kKeywordKindClass: { ++kOnClassScope; -- cgit v1.2.3 From 672541352e91ce4e2333d45dd8b3808d2d379466 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 11 May 2025 14:11:05 +0200 Subject: feat(cxxdrv): Begin addressing stack corruption issue causing segmentation fault Signed-off-by: Amlal El Mahrouss --- dev/LibC++/lc_runtime+unreachable.cc | 3 +- dev/LibCompiler/UUID.h | 2 +- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 25 +++++++--------- dev/LibCompiler/src/DynamicLinkerPEF.cc | 5 +++- dev/Vendor/Dialogs.h | 41 ++++++++++++++------------- tools/asm.cc | 10 +++---- tools/cxxdrv.cc | 9 +----- tools/cxxdrv.json | 2 +- 8 files changed, 46 insertions(+), 51 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibC++/lc_runtime+unreachable.cc b/dev/LibC++/lc_runtime+unreachable.cc index 2aaa3c1..39115a1 100644 --- a/dev/LibC++/lc_runtime+unreachable.cc +++ b/dev/LibC++/lc_runtime+unreachable.cc @@ -7,5 +7,6 @@ #include extern "C" void __libcompiler_unreachable(void) { - while (true); + while (true) + ; } \ No newline at end of file diff --git a/dev/LibCompiler/UUID.h b/dev/LibCompiler/UUID.h index d54eec7..39db276 100644 --- a/dev/LibCompiler/UUID.h +++ b/dev/LibCompiler/UUID.h @@ -172,7 +172,7 @@ namespace Detail { process_byte(static_cast((bitCount >> 24) & 0xFF)); process_byte(static_cast((bitCount >> 16) & 0xFF)); process_byte(static_cast((bitCount >> 8) & 0xFF)); - process_byte(static_cast((bitCount) & 0xFF)); + process_byte(static_cast((bitCount) &0xFF)); memcpy(digest, m_digest, 5 * sizeof(uint32_t)); return digest; diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index c0dc281..62d51aa 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -54,9 +54,11 @@ namespace Detail { std::filesystem::path expand_home(const std::filesystem::path& p) { if (!p.empty() && p.string()[0] == '~') { const char* home = std::getenv("HOME"); // For Unix-like systems + if (!home) { home = std::getenv("USERPROFILE"); // For Windows } + if (home) { return std::filesystem::path(home) / p.relative_path().string().substr(1); } else { @@ -86,7 +88,7 @@ struct CompilerStructMap final { struct CompilerState final { std::vector fStackMapVector; std::vector fStructMapVector; - std::ofstream fOutputAssembly; + std::string fOutputValue; std::string fLastFile; std::string fLastError; Boolean fVerbose; @@ -132,7 +134,6 @@ static std::vector kKeywords; ///////////////////////////////////////// -static std::vector kFileList; static LibCompiler::AssemblyFactory kFactory; static Boolean kInStruct = false; static Boolean kOnWhileLoop = false; @@ -220,7 +221,7 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) { } } - static LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree; + LibCompiler::SyntaxLeafList::SyntaxLeaf syntax_tree; for (auto& keyword : keywords_list) { switch (keyword.first.keyword_kind) { @@ -696,12 +697,9 @@ Boolean CompilerFrontendCPlusPlus::Compile(std::string text, std::string file) { continue; } } - - break; } -lc_compile_ok: - kState.fOutputAssembly << syntax_tree.fUserValue; + kState.fOutputValue = syntax_tree.fUserValue; return true; } @@ -735,14 +733,14 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { std::string line_source; - kState.fOutputAssembly.open(dest); + std::ofstream out(dest); while (std::getline(src_fp, line_source)) { kCompilerFrontend->Compile(line_source, src); + out << kState.fOutputValue; } - kState.fOutputAssembly.flush(); - kState.fOutputAssembly.close(); + out.flush(); if (kAcceptableErrors > 0) return kExitNO; @@ -881,8 +879,6 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { continue; } - kFileList.emplace_back(argv[index]); - std::string argv_i = argv[index]; std::vector exts = kExtListCxx; @@ -903,10 +899,11 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { return kExitNO; } - kFactory.Compile(argv_i, kMachine); + auto ret = kFactory.Compile(argv_i, kMachine); + return ret; } - return kExitOK; + return kExitNO; } // Last rev 8-1-24 diff --git a/dev/LibCompiler/src/DynamicLinkerPEF.cc b/dev/LibCompiler/src/DynamicLinkerPEF.cc index 21572bb..9e3be82 100644 --- a/dev/LibCompiler/src/DynamicLinkerPEF.cc +++ b/dev/LibCompiler/src/DynamicLinkerPEF.cc @@ -64,7 +64,10 @@ /// @brief PEF stack size symbol. #define kLinkerStackSizeSymbol "__PEFSizeOfReserveStack" -#define kOutCon (std::cout << "\e[0;31m" << "ld64: " << "\e[0;97m") +#define kOutCon \ + (std::cout << "\e[0;31m" \ + << "ld64: " \ + << "\e[0;97m") namespace Detail { struct DynamicLinkerBlob final { diff --git a/dev/Vendor/Dialogs.h b/dev/Vendor/Dialogs.h index ce50b81..84e239f 100644 --- a/dev/Vendor/Dialogs.h +++ b/dev/Vendor/Dialogs.h @@ -175,7 +175,7 @@ namespace internal { #elif __EMSCRIPTEN__ void start(int exit_code); #else - void start_process(std::vector const& command); + void start_process(std::vector const& command); #endif ~executor(); @@ -490,10 +490,10 @@ inline settings::settings(bool resync) { #if _WIN32 flags(flag::is_vista) = internal::is_vista(); #elif !__APPLE__ - flags(flag::has_zenity) = check_program("zenity"); + flags(flag::has_zenity) = check_program("zenity"); flags(flag::has_matedialog) = check_program("matedialog"); - flags(flag::has_qarma) = check_program("qarma"); - flags(flag::has_kdialog) = check_program("kdialog"); + flags(flag::has_qarma) = check_program("qarma"); + flags(flag::has_kdialog) = check_program("kdialog"); // If multiple helpers are available, try to default to the best one if (flags(flag::has_zenity) && flags(flag::has_kdialog)) { @@ -540,7 +540,7 @@ inline bool settings::check_program(std::string const& program) { (void) program; return false; #else - int exit_code = -1; + int exit_code = -1; internal::executor async; async.start_process({"/bin/sh", "-c", "which " + program}); async.result(&exit_code); @@ -604,7 +604,7 @@ inline std::string path::home() { if (size_max != -1) len = size_t(size_max); #endif std::vector buf(len); - struct passwd pwd, *result; + struct passwd pwd, *result; if (getpwuid_r(getuid(), &pwd, buf.data(), buf.size(), &result) == 0) return result->pw_dir; #endif return "/"; @@ -717,7 +717,7 @@ inline void internal::executor::start_process(std::vector const& co } close(in[1]); - m_fd = out[0]; + m_fd = out[0]; auto flags = fcntl(m_fd, F_GETFL); fcntl(m_fd, F_SETFL, flags | O_NONBLOCK); @@ -753,7 +753,7 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) // FIXME: do something (void) timeout; #else - char buf[BUFSIZ]; + char buf[BUFSIZ]; ssize_t received = read(m_fd, buf, BUFSIZ); // Flawfinder: ignore if (received > 0) { m_stdout += std::string(buf, received); @@ -764,7 +764,7 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) // (this happens when the calling application handles or ignores SIG_CHLD) and results in // waitpid() failing with ECHILD. Otherwise we assume the child is running and we sleep for // a little while. - int status; + int status; pid_t child = waitpid(m_pid, &status, WNOHANG); if (child != m_pid && (child >= 0 || errno != ECHILD)) { // FIXME: this happens almost always at first iteration @@ -782,7 +782,8 @@ inline bool internal::executor::ready(int timeout /* = default_wait_timeout */) inline void internal::executor::stop() { // Loop until the user closes the dialog - while (!ready()); + while (!ready()) + ; } // dll implementation @@ -878,11 +879,11 @@ inline std::vector internal::dialog::desktop_helper() const { #if __APPLE__ return {"osascript"}; #else - return {flags(flag::has_zenity) ? "zenity" + return {flags(flag::has_zenity) ? "zenity" : flags(flag::has_matedialog) ? "matedialog" - : flags(flag::has_qarma) ? "qarma" - : flags(flag::has_kdialog) ? "kdialog" - : "echo"}; + : flags(flag::has_qarma) ? "qarma" + : flags(flag::has_kdialog) ? "kdialog" + : "echo"}; #endif } @@ -1124,9 +1125,9 @@ inline internal::file_dialog::file_dialog(type in_type, std::string const& title // Split the pattern list to check whether "*" is in there; if it // is, we have to disable filters because there is no mechanism in // OS X for the user to override the filter. - std::regex sep("\\s+"); - std::string filter_list; - bool has_filter = true; + std::regex sep("\\s+"); + std::string filter_list; + bool has_filter = true; std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1); std::sregex_token_iterator end; for (; iter != end; ++iter) { @@ -1235,7 +1236,7 @@ inline std::vector internal::file_dialog::vector_result() { return m_vector_result; #else std::vector ret; - auto result = m_async->result(); + auto result = m_async->result(); for (;;) { // Split result along newline characters auto i = result.find('\n'); @@ -1568,7 +1569,7 @@ inline message::message(std::string const& title, std::string const& text, if_cancel = button::ok; break; } - m_mappings[1] = if_cancel; + m_mappings[1] = if_cancel; m_mappings[256] = if_cancel; // XXX: I think this was never correct script += " with icon "; switch (_icon) { @@ -1655,7 +1656,7 @@ inline message::message(std::string const& title, std::string const& text, if (_choice == choice::yes_no_cancel) flag += "cancel"; command.push_back(flag); if (_choice == choice::yes_no || _choice == choice::yes_no_cancel) { - m_mappings[0] = button::yes; + m_mappings[0] = button::yes; m_mappings[256] = button::no; } } diff --git a/tools/asm.cc b/tools/asm.cc index 36e55cf..8f98543 100644 --- a/tools/asm.cc +++ b/tools/asm.cc @@ -36,7 +36,7 @@ int main(int argc, char const* argv[]) { Int32 asm_type = kInvalidAssembler; for (size_t index_arg = 1; index_arg < argc; ++index_arg) { - if (strstr(argv[index_arg], "--asm:h")) { + if (strstr(argv[index_arg], "-asm:h")) { std::printf("asm: Frontend Assembler (64x0, power64, arm64, x64).\n"); std::printf("asm: Version: %s, Release: %s.\n", kDistVersion, kDistRelease); std::printf( @@ -47,13 +47,13 @@ int main(int argc, char const* argv[]) { "all rights reserved.\n"); return 0; - } else if (strstr(argv[index_arg], "--asm:x64")) { + } else if (strstr(argv[index_arg], "-asm:x64")) { asm_type = kX64Assembler; - } else if (strstr(argv[index_arg], "--asm:aarch64")) { + } else if (strstr(argv[index_arg], "-asm:aarch64")) { asm_type = kARM64Assembler; - } else if (strstr(argv[index_arg], "--asm:64x0")) { + } else if (strstr(argv[index_arg], "-asm:64x0")) { asm_type = k64X0Assembler; - } else if (strstr(argv[index_arg], "--asm:power64")) { + } else if (strstr(argv[index_arg], "-asm:power64")) { asm_type = kPOWER64Assembler; } else { arg_vec_cstr.push_back(argv[index_arg]); diff --git a/tools/cxxdrv.cc b/tools/cxxdrv.cc index a44b51d..f0aee1b 100644 --- a/tools/cxxdrv.cc +++ b/tools/cxxdrv.cc @@ -12,13 +12,6 @@ #include #include -LC_IMPORT_C int CompilerCPlusPlusAMD64(int argc, char const* argv[]); - int main(int argc, char const* argv[]) { - if (auto code = CompilerCPlusPlusAMD64(argc, argv); code > 0) { - std::printf("cxxdrv: compiler exited with code %i.\n", code); - return LIBCOMPILER_EXEC_ERROR; - } - - return LIBCOMPILER_SUCCESS; + return EXIT_FAILURE; } diff --git a/tools/cxxdrv.json b/tools/cxxdrv.json index d16f3b3..ad760c3 100644 --- a/tools/cxxdrv.json +++ b/tools/cxxdrv.json @@ -4,7 +4,7 @@ "headers_path": ["../dev/LibCompiler", "../dev/", "../dev/LibCompiler/src/Detail"], "sources_path": ["cxxdrv.cc"], "output_name": "cxxdrv", - "compiler_flags": ["-L/usr/local/lib", "-lCompiler"], + "compiler_flags": ["-L/usr/local/lib", "-lCompiler", "-Wl,-e,_CompilerCPlusPlusAMD64"], "cpp_macros": [ "__CXXDRV__=202504", "kDistReleaseBranch=$(git rev-parse --abbrev-ref HEAD)-$(uuidgen)" -- cgit v1.2.3 From 2be9a150bb742987330c6de4dac23d4d2efb1ebe Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Mon, 12 May 2025 08:15:14 +0200 Subject: fix(cxxdrv): The Compiler driver shall take multiple files, instead of one. Signed-off-by: Amlal El Mahrouss --- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc') diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 62d51aa..ace6d17 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -899,8 +899,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { return kExitNO; } - auto ret = kFactory.Compile(argv_i, kMachine); - return ret; + kFactory.Compile(argv_i, kMachine); } return kExitNO; -- cgit v1.2.3