From 2fd6271bdc6c2382194cf79dd67a9482d152e94e Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 20 May 2025 15:53:46 +0200 Subject: feat(cxxdrv): Improving and patching C++'s driver segfault at exit. Signed-off-by: Amlal El Mahrouss --- dev/LibCompiler/Backend/Amd64.h | 3 +- dev/LibCompiler/Detail/ClUtils.h | 18 ++++++++-- dev/LibCompiler/src/Assembler64x0.cc | 2 +- dev/LibCompiler/src/AssemblerAMD64.cc | 2 +- dev/LibCompiler/src/AssemblerARM64.cc | 2 +- dev/LibCompiler/src/AssemblerPowerPC.cc | 2 +- .../src/AssemblyFactory+AssemblyInterface.cc | 6 +++- dev/LibCompiler/src/CCompiler64x0.cc | 2 +- dev/LibCompiler/src/CCompilerARM64.cc | 2 +- dev/LibCompiler/src/CCompilerPower64.cc | 2 +- dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc | 38 +++++++++++----------- dev/LibCompiler/src/DynamicLinkerPEF.cc | 16 ++++----- 12 files changed, 57 insertions(+), 38 deletions(-) (limited to 'dev/LibCompiler') diff --git a/dev/LibCompiler/Backend/Amd64.h b/dev/LibCompiler/Backend/Amd64.h index b6d9530..ae8458f 100644 --- a/dev/LibCompiler/Backend/Amd64.h +++ b/dev/LibCompiler/Backend/Amd64.h @@ -43,6 +43,7 @@ inline std::vector kOpcodesAMD64 = { kAsmOpcodeDecl("int3", 0xC3) kAsmOpcodeDecl("iret", 0xCF) kAsmOpcodeDecl("retf", 0xCB) kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("ret", 0xC3) kAsmOpcodeDecl("sti", 0xfb) kAsmOpcodeDecl("cli", 0xfa) kAsmOpcodeDecl("hlt", 0xf4) kAsmOpcodeDecl("nop", 0x90) - kAsmOpcodeDecl("mov", 0x48) kAsmOpcodeDecl("call", 0xFF) kAsmOpcodeDecl("syscall", 0x0F) kAsmOpcodeDecl("xor", 0x48)}; + kAsmOpcodeDecl("mov", 0x48) kAsmOpcodeDecl("call", 0xFF) + kAsmOpcodeDecl("syscall", 0x0F) kAsmOpcodeDecl("xor", 0x48)}; #define kAsmRegisterLimit 16 diff --git a/dev/LibCompiler/Detail/ClUtils.h b/dev/LibCompiler/Detail/ClUtils.h index a809cdf..5277a6b 100644 --- a/dev/LibCompiler/Detail/ClUtils.h +++ b/dev/LibCompiler/Detail/ClUtils.h @@ -50,8 +50,22 @@ 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 on the GitHub issues page."); +/// @brief Handler for SIGSEGV signal. +inline void drv_segfault_handler(std::int32_t id) { + switch (id) { + case SIGSEGV: { + kStdErr << kRed << "drv: " << kWhite + << "Segmentation fault. Please report this on the GitHub issues page." << kBlank + << std::endl; + break; + } + case SIGABRT: { + kStdErr << kRed << "drv: " << kWhite + << "Aborted. Please report this on the GitHub issues page." << kBlank << std::endl; + break; + } + } + std::exit(LIBCOMPILER_EXEC_ERROR); } } // namespace Detail diff --git a/dev/LibCompiler/src/Assembler64x0.cc b/dev/LibCompiler/src/Assembler64x0.cc index a7c3efc..eb5b4dd 100644 --- a/dev/LibCompiler/src/Assembler64x0.cc +++ b/dev/LibCompiler/src/Assembler64x0.cc @@ -67,7 +67,7 @@ static bool asm_read_attributes(std::string line); ///////////////////////////////////////////////////////////////////////////////////////// LIBCOMPILER_MODULE(AssemblerMain64x0) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); for (size_t i = 1; i < argc; ++i) { if (argv[i][0] == '-') { diff --git a/dev/LibCompiler/src/AssemblerAMD64.cc b/dev/LibCompiler/src/AssemblerAMD64.cc index 9054a62..eb767cc 100644 --- a/dev/LibCompiler/src/AssemblerAMD64.cc +++ b/dev/LibCompiler/src/AssemblerAMD64.cc @@ -88,7 +88,7 @@ static bool asm_read_attributes(std::string line); LIBCOMPILER_MODULE(AssemblerMainAMD64) { //////////////// CPU OPCODES BEGIN //////////////// - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); std::string opcodes_jump[kJumpLimit] = {"ja", "jae", "jb", "jbe", "jc", "je", "jg", "jge", "jl", "jle", "jna", "jnae", "jnb", "jnbe", "jnc", "jne", diff --git a/dev/LibCompiler/src/AssemblerARM64.cc b/dev/LibCompiler/src/AssemblerARM64.cc index c8b66f7..19c7401 100644 --- a/dev/LibCompiler/src/AssemblerARM64.cc +++ b/dev/LibCompiler/src/AssemblerARM64.cc @@ -74,7 +74,7 @@ static bool asm_read_attributes(std::string line); ///////////////////////////////////////////////////////////////////////////////////////// LIBCOMPILER_MODULE(AssemblerMainARM64) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); for (size_t i = 1; i < argc; ++i) { if (argv[i][0] == '-') { diff --git a/dev/LibCompiler/src/AssemblerPowerPC.cc b/dev/LibCompiler/src/AssemblerPowerPC.cc index a438aed..ddd0b4e 100644 --- a/dev/LibCompiler/src/AssemblerPowerPC.cc +++ b/dev/LibCompiler/src/AssemblerPowerPC.cc @@ -74,7 +74,7 @@ static bool asm_read_attributes(std::string line); ///////////////////////////////////////////////////////////////////////////////////////// LIBCOMPILER_MODULE(AssemblerMainPower64) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); for (size_t i = 1; i < argc; ++i) { if (argv[i][0] == '-') { diff --git a/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc b/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc index 11655fb..e6072d9 100644 --- a/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc +++ b/dev/LibCompiler/src/AssemblyFactory+AssemblyInterface.cc @@ -28,7 +28,11 @@ Int32 AssemblyFactory::Compile(std::string sourceFile, const Int32& arch) noexce if (arch != fMounted->Arch()) return LIBCOMPILER_INVALID_ARCH; - return fMounted->CompileToFormat(sourceFile, arch); + try { + return fMounted->CompileToFormat(sourceFile, arch); + } catch (std::exception& e) { + return LIBCOMPILER_EXEC_ERROR; + } } ///! @brief mount assembly backend. diff --git a/dev/LibCompiler/src/CCompiler64x0.cc b/dev/LibCompiler/src/CCompiler64x0.cc index e43e16b..7bd8e8b 100644 --- a/dev/LibCompiler/src/CCompiler64x0.cc +++ b/dev/LibCompiler/src/CCompiler64x0.cc @@ -1200,7 +1200,7 @@ static void cc_print_help() { #define kExt ".c" LIBCOMPILER_MODULE(NeOSCompilerCLang64x0) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); kCompilerTypes.push_back({.fName = "void", .fValue = "void"}); kCompilerTypes.push_back({.fName = "char", .fValue = "byte"}); diff --git a/dev/LibCompiler/src/CCompilerARM64.cc b/dev/LibCompiler/src/CCompilerARM64.cc index b60ef4f..542f45f 100644 --- a/dev/LibCompiler/src/CCompilerARM64.cc +++ b/dev/LibCompiler/src/CCompilerARM64.cc @@ -1198,7 +1198,7 @@ static void cc_print_help() { #define kCExtension ".c" LIBCOMPILER_MODULE(NeOSCompilerCLangARM64) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); kCompilerTypes.push_back({.fName = "void", .fValue = "void"}); kCompilerTypes.push_back({.fName = "char", .fValue = "byte"}); diff --git a/dev/LibCompiler/src/CCompilerPower64.cc b/dev/LibCompiler/src/CCompilerPower64.cc index 30a1ab3..e5b25a5 100644 --- a/dev/LibCompiler/src/CCompilerPower64.cc +++ b/dev/LibCompiler/src/CCompilerPower64.cc @@ -1217,7 +1217,7 @@ static void cc_print_help() { #define kExt ".c" LIBCOMPILER_MODULE(NeOSCompilerCLangPowerPC) { - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); kCompilerTypes.push_back({.fName = "void", .fValue = "void"}); kCompilerTypes.push_back({.fName = "char", .fValue = "byte"}); diff --git a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc index 7b92552..98b9d43 100644 --- a/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc +++ b/dev/LibCompiler/src/CPlusPlusCompilerAMD64.cc @@ -9,6 +9,7 @@ /// BUGS: 1 +#include "Vendor/Dialogs.h" #define kPrintF printf #define kExitOK (EXIT_SUCCESS) @@ -23,7 +24,7 @@ #include -/* NE C++ Compiler */ +/* NeKernel C++ Compiler Driver */ /* This is part of the LibCompiler. */ /* (c) Amlal El Mahrouss */ @@ -91,7 +92,6 @@ struct CompilerState final { std::string fOutputValue; std::string fLastFile; std::string fLastError; - Boolean fVerbose; }; } // namespace Detail @@ -141,7 +141,7 @@ static Boolean kOnForLoop = false; static Boolean kInBraces = false; static size_t kBracesCount = 0UL; -/* @brief C++ compiler backend for the NE C++ driver */ +/* @brief C++ compiler backend for the NeKernel C++ driver */ class CompilerFrontendCPlusPlus final : public LibCompiler::ICompilerFrontend { public: explicit CompilerFrontendCPlusPlus() = default; @@ -725,25 +725,24 @@ class AssemblyCPlusPlusInterface final ASSEMBLY_INTERFACE { Int32 CompileToFormat(std::string src, Int32 arch) override { if (kCompilerFrontend == nullptr) return kExitNO; - /* @brief copy contents wihtout extension */ - std::ifstream src_fp = std::ifstream(src, std::ios::in); - std::string dest = src; dest += ".masm"; std::string line_source; - std::ofstream out(dest); + std::ofstream out_fp(dest); + + std::ifstream src_fp = std::ifstream(src); while (std::getline(src_fp, line_source)) { + if (kVerbose) { + std::cout << kWhite << line_source << std::endl; + } + kCompilerFrontend->Compile(line_source, src); - out << kState.fOutputValue; + out_fp << kState.fOutputValue; } - out.flush(); - - if (kAcceptableErrors > 0) return kExitNO; - return kExitOK; } }; @@ -785,8 +784,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { kKeywords.push_back( {.keyword_name = "auto*", .keyword_kind = LibCompiler::kKeywordKindVariablePtr}); kKeywords.push_back({.keyword_name = "int*", .keyword_kind = LibCompiler::kKeywordKindTypePtr}); - kKeywords.push_back( - {.keyword_name = "bool*", .keyword_kind = LibCompiler::kKeywordKindTypePtr}); + kKeywords.push_back({.keyword_name = "bool*", .keyword_kind = LibCompiler::kKeywordKindTypePtr}); kKeywords.push_back( {.keyword_name = "unsigned*", .keyword_kind = LibCompiler::kKeywordKindTypePtr}); kKeywords.push_back({.keyword_name = "short*", .keyword_kind = LibCompiler::kKeywordKindTypePtr}); @@ -836,7 +834,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { kCompilerFrontend = new CompilerFrontendCPlusPlus(); kFactory.Mount(new AssemblyCPlusPlusInterface()); - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); for (auto index = 1UL; index < argc; ++index) { if (argv[index][0] == '-') { @@ -846,7 +844,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { } if (strcmp(argv[index], "-cxx-verbose") == 0) { - kState.fVerbose = true; + kVerbose = true; continue; } @@ -892,7 +890,7 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { } if (!found) { - if (kState.fVerbose) { + if (kVerbose) { Detail::print_error(argv_i + " is not a valid C++ source.\n", "cxxdrv"); } @@ -900,11 +898,13 @@ LIBCOMPILER_MODULE(CompilerCPlusPlusAMD64) { } if (kFactory.Compile(argv_i, kMachine) != kExitOK) { - Detail::print_error("Compiler error, see log for details.\n", "cxxdrv"); + return kExitNO; } } - return kExitNO; + kFactory.Unmount(); + + return kExitOK; } // Last rev 8-1-24 diff --git a/dev/LibCompiler/src/DynamicLinkerPEF.cc b/dev/LibCompiler/src/DynamicLinkerPEF.cc index b51502f..6421171 100644 --- a/dev/LibCompiler/src/DynamicLinkerPEF.cc +++ b/dev/LibCompiler/src/DynamicLinkerPEF.cc @@ -61,7 +61,7 @@ /// @brief PEF stack size symbol. #define kLinkerStackSizeSymbol "__PEFSizeOfReserveStack" -#define kConsoleOut \ +#define kConsoleOut \ (std::cout << "\e[0;31m" \ << "ld64: " \ << "\e[0;97m") @@ -101,7 +101,7 @@ static std::vector kObjectBytes; LIBCOMPILER_MODULE(DynamicLinker64PEF) { bool is_executable = true; - ::signal(SIGSEGV, Detail::segfault_handler); + ::signal(SIGSEGV, Detail::drv_segfault_handler); /** * @brief parse flags and trigger options. @@ -270,9 +270,9 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) { if (kVerbose) kConsoleOut << "not a FAT binary.\n"; kConsoleOut << "object " << objectFile - << " is a different kind of architecture and output isn't " - "treated as a FAT binary." - << std::endl; + << " is a different kind of architecture and output isn't " + "treated as a FAT binary." + << std::endl; return LIBCOMPILER_FAT_ERROR; } else { @@ -450,8 +450,8 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) { if (!kStartFound && is_executable) { if (kVerbose) kConsoleOut << "Undefined entrypoint: " << kPefStart - << ", you may have forget to link " - "against the C++ runtime library.\n"; + << ", you may have forget to link " + "against the C++ runtime library.\n"; kConsoleOut << "Undefined entrypoint " << kPefStart << " for executable: " << kOutput << "\n"; } @@ -603,7 +603,7 @@ LIBCOMPILER_MODULE(DynamicLinker64PEF) { if (kVerbose) { kConsoleOut << "Command name: " << name << "\n"; kConsoleOut << "VMAddress of command content: " << command_headers[commandHeaderIndex].Offset - << "\n"; + << "\n"; } output_fc << command_headers[commandHeaderIndex]; -- cgit v1.2.3