From 037ac38824623c13070384e8fc0e70c4770dcdbd Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 5 Dec 2025 11:49:28 -0500 Subject: chore! new project filesystem structure. Signed-off-by: Amlal El Mahrouss --- src/CompilerKit/AE.h | 138 --- src/CompilerKit/AST.h | 143 --- src/CompilerKit/AST.inl | 63 -- src/CompilerKit/CodeGenerator.h | 228 ----- src/CompilerKit/Detail/32x0.h | 94 -- src/CompilerKit/Detail/64x0.h | 100 --- src/CompilerKit/Detail/AMD64.h | 50 -- src/CompilerKit/Detail/Aarch64.h | 41 - src/CompilerKit/Detail/Config.h | 64 -- src/CompilerKit/Detail/Power64.h | 1557 --------------------------------- src/CompilerKit/Detail/PreConfig.h | 120 --- src/CompilerKit/ErrorID.h | 29 - src/CompilerKit/ErrorOr.h | 54 -- src/CompilerKit/Macros.h | 28 - src/CompilerKit/PEF.h | 138 --- src/CompilerKit/Ref.h | 77 -- src/CompilerKit/UUID.h | 826 ----------------- src/CompilerKit/Utilities/Assembler.h | 92 -- src/CompilerKit/Utilities/Compiler.h | 123 --- src/CompilerKit/Utilities/DLL.h | 67 -- src/CompilerKit/XCOFF.h | 43 - src/CompilerKit/ck-osx-san.json | 10 +- src/CompilerKit/ck-osx.json | 10 +- src/CompilerKit/ck-posix.json | 8 +- 24 files changed, 14 insertions(+), 4089 deletions(-) delete mode 100644 src/CompilerKit/AE.h delete mode 100644 src/CompilerKit/AST.h delete mode 100644 src/CompilerKit/AST.inl delete mode 100644 src/CompilerKit/CodeGenerator.h delete mode 100644 src/CompilerKit/Detail/32x0.h delete mode 100644 src/CompilerKit/Detail/64x0.h delete mode 100644 src/CompilerKit/Detail/AMD64.h delete mode 100644 src/CompilerKit/Detail/Aarch64.h delete mode 100644 src/CompilerKit/Detail/Config.h delete mode 100644 src/CompilerKit/Detail/Power64.h delete mode 100644 src/CompilerKit/Detail/PreConfig.h delete mode 100644 src/CompilerKit/ErrorID.h delete mode 100644 src/CompilerKit/ErrorOr.h delete mode 100644 src/CompilerKit/Macros.h delete mode 100644 src/CompilerKit/PEF.h delete mode 100644 src/CompilerKit/Ref.h delete mode 100644 src/CompilerKit/UUID.h delete mode 100644 src/CompilerKit/Utilities/Assembler.h delete mode 100644 src/CompilerKit/Utilities/Compiler.h delete mode 100644 src/CompilerKit/Utilities/DLL.h delete mode 100644 src/CompilerKit/XCOFF.h (limited to 'src/CompilerKit') diff --git a/src/CompilerKit/AE.h b/src/CompilerKit/AE.h deleted file mode 100644 index cf6e71b..0000000 --- a/src/CompilerKit/AE.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#ifndef _NECTI_AE_H_ -#define _NECTI_AE_H_ - -#include -#include - -#define kAEIdentVersion (0x0122) - -#define kAEMag0 'A' -#define kAEMag1 'E' -#define kAEMag2 'F' - -#define kAESymbolLen (256) -#define kAEPad (8) -#define kAEMagLen (3) -#define kAENullType (0x00) - -/// @author Amlal El Mahrouss - -/// @brief -// Advanced Executable File Format for ld64. -// Reloctable by offset is the default strategy. -// You can also relocate at runtime but that's up to the operating system loader. - -namespace CompilerKit { -// @brief Advanced Executable Header -// One thing to keep in mind. -// This object format, is reloctable. -typedef struct AEHeader final { - Char fMagic[kAEMagLen] = {}; - UInt16 fVersion{kAEIdentVersion}; - Char fArch{}; - Char fSubArch{}; - SizeType fCount{}; - Char fSize{}; - SizeType fStartCode{}; - SizeType fCodeSize{}; - Char fPad[kAEPad] = {}; -} PACKED AEHeader, *AEHeaderPtr; - -// @brief Advanced Executable Record. -// Could be data, code or bss. -// fKind must be filled with PEF fields. - -typedef struct AERecordHeader final { - Char fName[kAESymbolLen]; - SizeType fKind; - SizeType fSize; - SizeType fFlags; - UIntPtr fOffset; - Char fPad[kAEPad]; -} PACKED AERecordHeader, *AERecordHeaderPtr; - -enum { - kKindRelocationByOffset = 0x23f, - kKindRelocationAtRuntime = 0x34f, -}; -} // namespace CompilerKit - -// provide operator<< for AE - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AEHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::AEHeader)); - - return fp; -} - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AERecordHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::AERecordHeader)); - - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AEHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::AEHeader)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AERecordHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::AERecordHeader)); - return fp; -} - -namespace CompilerKit::Utils { -/** - * @brief AE Reader protocol - * - */ -class AEReadableProtocol final { - public: - std::ifstream file_pointer_; - - public: - explicit AEReadableProtocol() = default; - ~AEReadableProtocol() = default; - - NECTI_COPY_DELETE(AEReadableProtocol); - - /** - * @brief Read AE Record headers. - * - * @param raw the containing buffer - * @param sz it's size (1 = one AERecordHeader, 2 two AERecordHeader(s)) - * @return AERecordHeaderPtr - */ - AERecordHeaderPtr Read(char* raw, std::size_t sz) { - if (!raw) return nullptr; - - return this->Read_(raw, sz * sizeof(AERecordHeader)); - } - - private: - /** - * @brief Implementation of Read for raw classes. - * - * @tparam TypeClass The class to read. - * @param raw the buffer - * @param sz the size - * @return TypeClass* the returning class. - */ - template - TypeClass* Read_(char* raw, std::size_t sz) { - file_pointer_.read(raw, std::streamsize(sz)); - return reinterpret_cast(raw); - } -}; -} // namespace CompilerKit::Utils - -#endif /* ifndef _NECTI_AE_H_ */ \ No newline at end of file diff --git a/src/CompilerKit/AST.h b/src/CompilerKit/AST.h deleted file mode 100644 index 3987f13..0000000 --- a/src/CompilerKit/AST.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -#define CK_COMPILER_FRONTEND : public ::CompilerKit::CompilerFrontendInterface - -namespace CompilerKit { -inline static auto kInvalidFrontend = "(null)"; - -struct SyntaxLeafList; -struct SyntaxLeafList; -struct CompilerKeyword; - -/// =========================================================== /// -/// @note we want to do that to separate keywords. -/// =========================================================== /// - -enum KeywordKind { - kKeywordKindReserved = 0, - kKeywordKindNamespace = 100, - kKeywordKindFunctionStart, - kKeywordKindFunctionEnd, - kKeywordKindVariable, - kKeywordKindVariablePtr, - kKeywordKindType, - kKeywordKindTypePtr, - kKeywordKindExpressionBegin, - kKeywordKindExpressionEnd, - kKeywordKindArgSeparator, - kKeywordKindBodyStart, - kKeywordKindBodyEnd, - kKeywordKindClass, - kKeywordKindPtrAccess, - kKeywordKindAccess, - kKeywordKindIf, - kKeywordKindElse, - kKeywordKindElseIf, - kKeywordKindVariableAssign, - kKeywordKindVariableDec, - kKeywordKindVariableInc, - kKeywordKindConstant, - kKeywordKindTypedef, - kKeywordKindEndInstr, - kKeywordKindSpecifier, - kKeywordKindInvalid, - kKeywordKindReturn, - kKeywordKindCommentInline, - kKeywordKindCommentMultiLineStart, - kKeywordKindCommentMultiLineEnd, - kKeywordKindEq, - kKeywordKindNotEq, - kKeywordKindGreaterEq, - kKeywordKindLessEq, - kKeywordKindPtr, - kKeywordKindCount = kKeywordKindPtr - kKeywordKindNamespace + 1, -}; - -/// =========================================================== /// -/// \brief Compiler keyword information struct. -/// =========================================================== /// -struct CompilerKeyword { - CompilerKeyword(STLString name, KeywordKind kind) : keyword_name(name), keyword_kind(kind) {} - - STLString keyword_name{""}; - KeywordKind keyword_kind{kKeywordKindInvalid}; -}; - -struct SyntaxLeafList final { - struct SyntaxLeaf final { - Int32 fUserType{0U}; - CompilerKeyword fUserData{"", kKeywordKindInvalid}; - - STLString fUserValue{""}; - struct SyntaxLeaf* fNext{nullptr}; - }; - - std::vector fLeafList; - SizeType fNumLeafs{0}; - - SizeType SizeOf() { return fNumLeafs; } - std::vector& Get() { return fLeafList; } - SyntaxLeaf& At(SizeType index) { return fLeafList[index]; } -}; - -/// =========================================================== /// -/// find the perfect matching word in a haystack. -/// \param haystack base string -/// \param needle the string we search for. -/// \return if we found it or not. -/// =========================================================== /// -bool find_word(STLString haystack, STLString needle) noexcept; - -/// =========================================================== /// -/// find a word within strict conditions and returns a range of it. -/// \param haystack -/// \param needle -/// \return position of needle. -/// =========================================================== /// -SizeType find_word_range(STLString haystack, STLString needle) noexcept; - -/// =========================================================== /// -/// @brief Compiler backend, implements a frontend, such as C, C++... -/// See Toolchain, for some examples. -/// =========================================================== /// -class CompilerFrontendInterface { - public: - explicit CompilerFrontendInterface() = default; - virtual ~CompilerFrontendInterface() = default; - - NECTI_COPY_DEFAULT(CompilerFrontendInterface); - - /// =========================================================== /// - // NOTE: cast this to your user defined ast. - /// =========================================================== /// - typedef VoidPtr AstType; - - /// =========================================================== /// - //! @brief Compile a syntax tree ouf of the text. - //! Also takes the source file name for metadata. - /// =========================================================== /// - - virtual CompilerKit::SyntaxLeafList::SyntaxLeaf Compile(std::string text, std::string file) = 0; - - /// =========================================================== /// - //! @brief What language are we dealing with? - /// =========================================================== /// - virtual const char* Language(); - - /// =========================================================== /// - /// @brief Checks if language is a valid frontend. - /// =========================================================== /// - virtual bool IsValid(); -}; -} // namespace CompilerKit - -#include \ No newline at end of file diff --git a/src/CompilerKit/AST.inl b/src/CompilerKit/AST.inl deleted file mode 100644 index 3dc9456..0000000 --- a/src/CompilerKit/AST.inl +++ /dev/null @@ -1,63 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -namespace CompilerKit { -/// find the perfect matching word in a haystack. -/// \param haystack base string -/// \param needle the string we search for. -/// \return if we found it or not. -inline bool find_word(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - // declare lambda - auto not_part_of_word = [&](int index) { - if (std::isspace(haystack[index]) || std::ispunct(haystack[index])) return true; - - if (index <= 0 || index >= haystack.size()) return true; - - return false; - }; - - return not_part_of_word(index - 1) && not_part_of_word(index + needle.size()); -} - -/// find a word within strict conditions and returns a range of it. -/// \param haystack -/// \param needle -/// \return position of needle. -inline SizeType find_word_range(STLString haystack, STLString needle) noexcept { - auto index = haystack.find(needle); - - // check for needle validity. - if (index == STLString::npos) return false; - - if (!isalnum((haystack[index + needle.size() + 1])) && - !isdigit(haystack[index + needle.size() + 1]) && - !isalnum((haystack[index - needle.size() - 1])) && - !isdigit(haystack[index - needle.size() - 1])) { - return index; - } - - return STLString::npos; -} - -/// =========================================================== /// -//! @brief What language are we dealing with? -/// =========================================================== /// -inline const char* CompilerFrontendInterface::Language() { - return kInvalidFrontend; -} - -/// =========================================================== /// -/// @brief Checks if language is a valid frontend. -/// =========================================================== /// -inline bool CompilerFrontendInterface::IsValid() { - return strcmp(this->Language(), kInvalidFrontend) > 0; -} -} // namespace CompilerKit \ No newline at end of file diff --git a/src/CompilerKit/CodeGenerator.h b/src/CompilerKit/CodeGenerator.h deleted file mode 100644 index 383f170..0000000 --- a/src/CompilerKit/CodeGenerator.h +++ /dev/null @@ -1,228 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include -#include - -#define CK_ASSEMBLY_INTERFACE : public ::CompilerKit::AssemblyInterface -#define CK_ENCODER : public ::CompilerKit::EncoderInterface - -namespace CompilerKit { -class AssemblyFactory; -class AssemblyInterface; - -/// =========================================================== /// -/// @brief Simple assembly factory -/// =========================================================== /// -class AssemblyFactory final { - public: - explicit AssemblyFactory() = default; - ~AssemblyFactory() = default; - - NECTI_COPY_DEFAULT(AssemblyFactory); - - public: - enum { - kArchInvalid = 0, - kArchAMD64 = 100, - kArch32x0, - kArch64x0, - kArchRISCV, - kArchPowerPC, - kArchAARCH64, - kArchUnknown, - kArchCount = kArchUnknown - kArchAMD64, - }; - - Int32 Compile(std::string sourceFile, const Int32& arch) noexcept; - - void Mount(AssemblyInterface* mountPtr) noexcept; - AssemblyInterface* Unmount() noexcept; - - private: - 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; - - NECTI_COPY_DEFAULT(AssemblyInterface); - - virtual UInt32 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; -}; - -/// =========================================================== /// -/// @brief Number casting unions for different sizes. -/// =========================================================== /// -union NumberCastBase { - NumberCastBase() = default; - ~NumberCastBase() = default; -}; - -union NumberCast64 final { - NumberCast64() = default; - explicit NumberCast64(UInt64 raw) : raw(raw) {} - - ~NumberCast64() { raw = 0; } - - static constexpr auto kLimit = 8; - - Char number[kLimit]; - UInt64 raw; -}; - -union NumberCast32 final { - NumberCast32() = default; - explicit NumberCast32(UInt32 raw) : raw(raw) {} - - ~NumberCast32() { raw = 0; } - - static constexpr auto kLimit = 4; - - Char number[kLimit]; - UInt32 raw; -}; - -union NumberCast16 final { - NumberCast16() = default; - explicit NumberCast16(UInt16 raw) : raw(raw) {} - - ~NumberCast16() { raw = 0; } - - static constexpr auto kLimit = 2; - - Char number[kLimit]; - UInt16 raw; -}; - -union NumberCast8 final { - NumberCast8() = default; - explicit NumberCast8(UInt8 raw) : raw(raw) {} - - ~NumberCast8() { raw = 0; } - - Char number; - UInt8 raw; -}; - -/// =========================================================== /// -/// @brief Assembly encoder interface. -/// =========================================================== /// -class EncoderInterface { - public: - explicit EncoderInterface() = default; - virtual ~EncoderInterface() = default; - - NECTI_COPY_DEFAULT(EncoderInterface); - - virtual std::string CheckLine(std::string line, std::string file) = 0; - virtual bool WriteLine(std::string line, std::string file) = 0; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) = 0; -}; - -/// =========================================================== /// -/// @brief Different architecture encoders. -/// =========================================================== /// - -#ifdef __ASM_NEED_AMD64__ - -class EncoderAMD64 final : public EncoderInterface { - public: - explicit EncoderAMD64() = default; - ~EncoderAMD64() override = default; - - NECTI_COPY_DEFAULT(EncoderAMD64); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; - - virtual bool WriteNumber16(const std::size_t& pos, std::string& from_what); - virtual bool WriteNumber32(const std::size_t& pos, std::string& from_what); - virtual bool WriteNumber8(const std::size_t& pos, std::string& from_what); -}; - -#endif // __ASM_NEED_AMD64__ - -#ifdef __ASM_NEED_ARM64__ - -class EncoderARM64 final : public EncoderInterface { - public: - explicit EncoderARM64() = default; - ~EncoderARM64() override = default; - - NECTI_COPY_DEFAULT(EncoderARM64); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_ARM64__ - -#ifdef __ASM_NEED_64x0__ - -class Encoder64x0 final : public EncoderInterface { - public: - explicit Encoder64x0() = default; - ~Encoder64x0() override = default; - - NECTI_COPY_DEFAULT(Encoder64x0); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_64x0__ - -#ifdef __ASM_NEED_32x0__ - -class Encoder32x0 final : public EncoderInterface { - public: - explicit Encoder32x0() = default; - ~Encoder32x0() override = default; - - NECTI_COPY_DEFAULT(Encoder32x0); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_32x0__ - -#ifdef __ASM_NEED_PPC__ - -class EncoderPowerPC final : public EncoderInterface { - public: - explicit EncoderPowerPC() = default; - ~EncoderPowerPC() override = default; - - NECTI_COPY_DEFAULT(EncoderPowerPC); - - virtual std::string CheckLine(std::string line, std::string file) override; - virtual bool WriteLine(std::string line, std::string file) override; - virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; -}; - -#endif // __ASM_NEED_32x0__ -} // namespace CompilerKit diff --git a/src/CompilerKit/Detail/32x0.h b/src/CompilerKit/Detail/32x0.h deleted file mode 100644 index fc3e0e9..0000000 --- a/src/CompilerKit/Detail/32x0.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -// @brief Open32x0 support. -// @file Detail/32x0.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \ - {.fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7}, - -#define kAsmImmediate 0x01 -#define kAsmSyscall 0x02 -#define kAsmJump 0x03 -#define kAsmNoArgs 0x04 - -#define kAsmByte 0 -#define kAsmHWord 1 -#define kAsmWord 2 - -struct CpuCode32x0 { - const char fName[32]; - uint8_t fOpcode; - uint8_t fSize; - uint8_t fFunct3; - uint8_t fFunct7; -}; - -#define kAsmDWordStr ".dword" /* 64 bit */ -#define kAsmWordStr ".word" /* 32-bit */ -#define kAsmHWordStr ".half" /* 16-bit */ -#define kAsmByteStr ".byte" /* 8-bit */ - -inline std::vector kOpcodes32x0 = { - CK_ASM_OPCODE("nop", 0b0100011, 0b000, kAsmNoArgs) // nothing to do. (1C) - CK_ASM_OPCODE("jmp", 0b1110011, 0b001, kAsmJump) // jump to branch (2C) - CK_ASM_OPCODE("mov", 0b0100011, 0b101, kAsmImmediate) // move registers (3C) - CK_ASM_OPCODE("psh", 0b0111011, 0b000, kAsmImmediate) // push to sp (2C) - CK_ASM_OPCODE("pop", 0b0111011, 0b001, kAsmImmediate) // pop from sp. (1C) - CK_ASM_OPCODE("lea", 0b0111011, 0b010, - kAsmImmediate) // setup stack and call, store address to CR (1C). - CK_ASM_OPCODE("ret", 0b0111011, 0b110, - kAsmImmediate) // return from procedure (2C). - CK_ASM_OPCODE("uc", 0b0111111, 0b000, kAsmSyscall) // user call (1C) - CK_ASM_OPCODE("kc", 0b0111111, 0b001, kAsmSyscall) // kernel call (1C) - CK_ASM_OPCODE("int", 0b0111111, 0b010, kAsmSyscall) // raise interrupt (1C) -}; - -// \brief 64x0 register prefix -// example: r32, r0 -// r32 -> sp -// r0 -> hw zero - -#define kAsmRegisterPrefix "r" -#define kAsmRegisterLimit 16 -#define kAsmPcRegister 17 -#define kAsmCrRegister 18 -#define kAsmSpRegister 5 - -/* return address register */ -#define kAsmRetRegister 19 - -///////////////////////////////////////////////////////////////////////////// - -// SYSTEM CALL ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | OFF | - -// IMMEDIATE ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | REG | -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG | OFF | - -// REG TO REG ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG2 | - -//////////////////////////////// - -// LOAD/CALL INTERRUPTS - -// SET A HANDLER IN ADDRESS: TODO: find one -// DISABLE INTERRUPTS -// PROCESS INTERRUPT -// ENABLE INTERRUPTS - -//////////////////////////////// diff --git a/src/CompilerKit/Detail/64x0.h b/src/CompilerKit/Detail/64x0.h deleted file mode 100644 index ba539f6..0000000 --- a/src/CompilerKit/Detail/64x0.h +++ /dev/null @@ -1,100 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -// @brief Open64x0 support. -// @file Detail/64x0.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE, __FUNCT3, __FUNCT7) \ - {.fName = __NAME, .fOpcode = __OPCODE, .fFunct3 = __FUNCT3, .fFunct7 = __FUNCT7}, - -#define kAsmImmediate 0x01 -#define kAsmRegToReg 0x02 -#define kAsmSyscall 0x03 -#define kAsmJump 0x04 -#define kAsmNoArgs 0x00 - -typedef char e64k_character_t; -typedef uint8_t e64k_num_t; - -struct CpuOpcode64x0 { - const e64k_character_t fName[32]; - e64k_num_t fOpcode; - e64k_num_t fFunct3; - e64k_num_t fFunct7; -}; - -inline std::vector kOpcodes64x0 = { - CK_ASM_OPCODE("nop", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation. - CK_ASM_OPCODE("np", 0b0000000, 0b0000000, kAsmNoArgs) // no-operation. - CK_ASM_OPCODE("jlr", 0b1110011, 0b0000111, - kAsmJump) // jump to linked return register - CK_ASM_OPCODE("jrl", 0b1110011, 0b0001111, - kAsmJump) // jump from return register. - CK_ASM_OPCODE("mv", 0b0100011, 0b101, kAsmRegToReg) CK_ASM_OPCODE( - "bg", 0b1100111, 0b111, kAsmRegToReg) CK_ASM_OPCODE("bl", 0b1100111, 0b011, kAsmRegToReg) - CK_ASM_OPCODE("beq", 0b1100111, 0b000, kAsmRegToReg) - CK_ASM_OPCODE("bne", 0b1100111, 0b001, kAsmRegToReg) - CK_ASM_OPCODE("bge", 0b1100111, 0b101, kAsmRegToReg) - CK_ASM_OPCODE("ble", 0b1100111, 0b100, kAsmRegToReg) - CK_ASM_OPCODE("stw", 0b0001111, 0b100, kAsmImmediate) - CK_ASM_OPCODE("ldw", 0b0001111, 0b100, kAsmImmediate) - CK_ASM_OPCODE("lda", 0b0001111, 0b101, kAsmImmediate) - CK_ASM_OPCODE("sta", 0b0001111, 0b001, kAsmImmediate) - // add/sub without carry flag - CK_ASM_OPCODE("add", 0b0101011, 0b100, kAsmImmediate) - CK_ASM_OPCODE("sub", 0b0101011, 0b101, kAsmImmediate) - // add/sub with carry flag - CK_ASM_OPCODE("addc", 0b0101011, 0b110, kAsmImmediate) CK_ASM_OPCODE( - "subc", 0b0101011, 0b111, kAsmImmediate) CK_ASM_OPCODE("sc", 0b1110011, 0b00, kAsmSyscall)}; - -// \brief 64x0 register prefix -// example: r32, r0 -// r32 -> sp -// r0 -> hw zero - -#define kAsmFloatZeroRegister 0 -#define kAsmZeroRegister 0 - -#define kAsmRegisterPrefix "r" -#define kAsmRegisterLimit 30 -#define kAsmPcRegister 17 -#define kAsmCrRegister 18 -#define kAsmSpRegister 5 - -/* return address register */ -#define kAsmRetRegister 19 - -///////////////////////////////////////////////////////////////////////////// - -// SYSTEM CALL/JUMP ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | OFF | - -// IMMEDIATE ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | -// | OPCODE | FUNCT3 | FUNCT7 | REG | OFF | REG | -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG | OFF | - -// REG TO REG ADDRESSING - -// | OPCODE | FUNCT3 | FUNCT7 | REG | REG2 | - -//////////////////////////////// - -// LOAD/CALL INTERRUPTS - -// SET A HANDLER IN ADDRESS: -// DISABLE INTERRUPTS -// PROCESS INTERRUPT -// ENABLE INTERRUPTS - -//////////////////////////////// diff --git a/src/CompilerKit/Detail/AMD64.h b/src/CompilerKit/Detail/AMD64.h deleted file mode 100644 index a123c02..0000000 --- a/src/CompilerKit/Detail/AMD64.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -// @brief AMD64 support. -// @file Detail/AMD64.h - -#define CK_ASM_OPCODE(__NAME, __OPCODE) {.fName = __NAME, .fOpcode = __OPCODE}, - -typedef char i64_character_t; -typedef uint8_t i64_byte_t; -typedef uint16_t i64_hword_t; -typedef uint32_t i64_word_t; - -#define kAsmRegisterPrefix "r" - -struct CpuOpcodeAMD64 { - std::string fName; - i64_byte_t fPrefixBytes[4]; - i64_hword_t fOpcode; - i64_hword_t fModReg; - i64_word_t fDisplacment; - i64_word_t fImmediate; -}; - -/// these two are edge cases -#define kAsmIntOpcode 0xCC -#define kasmIntOpcodeAlt 0xCD - -#define kAsmJumpOpcode 0x0F80 -#define kJumpLimit 30 -#define kJumpLimitStandard 0xE3 -#define kJumpLimitStandardLimit 0xEB - -inline std::vector kOpcodesAMD64 = { - CK_ASM_OPCODE("int", 0xCD) CK_ASM_OPCODE("into", 0xCE) CK_ASM_OPCODE("intd", 0xF1) - CK_ASM_OPCODE("int3", 0xC3) CK_ASM_OPCODE("iret", 0xCF) CK_ASM_OPCODE("retf", 0xCB) - CK_ASM_OPCODE("retn", 0xC3) CK_ASM_OPCODE("ret", 0xC3) CK_ASM_OPCODE("sti", 0xfb) - CK_ASM_OPCODE("cli", 0xfa) CK_ASM_OPCODE("hlt", 0xf4) CK_ASM_OPCODE("nop", 0x90) - CK_ASM_OPCODE("mov", 0x48) CK_ASM_OPCODE("call", 0xFF) - CK_ASM_OPCODE("syscall", 0x0F) CK_ASM_OPCODE("xor", 0x48)}; - -#define kAsmRegisterLimit 16 diff --git a/src/CompilerKit/Detail/Aarch64.h b/src/CompilerKit/Detail/Aarch64.h deleted file mode 100644 index 1ce1719..0000000 --- a/src/CompilerKit/Detail/Aarch64.h +++ /dev/null @@ -1,41 +0,0 @@ -/* ======================================== - -Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -/// @brief ARM64 encoding support. -/// @file Detail/Aarch64.h - -struct CpuOpcodeArm64; - -/// @brief ARM64 opcode header. -struct PACKED CpuOpcodeArm64_Data final { - uint32_t fOpcode : 10; // Bits 31–22: Opcode for operation - uint32_t fRm : 5; // Bits 21–16: Source register Rm - uint32_t fShamt : 6; // Bits 15–10: Shift amount - uint32_t fRn : 5; // Bits 9–5: Source register Rn - uint32_t fRd : 5; // Bits 4–0: Destination register Rd -}; - -typedef struct { - uint32_t opcode : 6; // Bits 31–26: Branch opcode - int32_t offset : 26; // Bits 25–0: Signed offset (branch target) -} PACKED CpuOpcodeArm64_Branch; - -typedef struct { - uint32_t size : 2; // Bits 31–30: Size of the data - uint32_t opcode : 7; // Bits 29–23: Opcode for load/store - uint32_t offset : 12; // Bits 22–10: Offset - uint32_t rn : 5; // Bits 9–5: Base address register Rn - uint32_t rt : 5; // Bits 4–0: Target/source register Rt -} PACKED CpuOpcodeArm64_LoadStore; - -#define kAsmRegisterLimit (30) -#define kAsmRegisterPrefix "x" -#define kOpcodeARM64Count (1000) diff --git a/src/CompilerKit/Detail/Config.h b/src/CompilerKit/Detail/Config.h deleted file mode 100644 index 6137e2a..0000000 --- a/src/CompilerKit/Detail/Config.h +++ /dev/null @@ -1,64 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -/// =========================================================== /// -/// @file detail/Config.h -/// @author Amlal El Mahrouss -/// @brief Basic defines and types for CompilerKit. -/// =========================================================== /// - -#include - -namespace CompilerKit { -inline constexpr int kBaseYear = 1900; -using STLString = std::string; - -inline STLString current_date() noexcept { - auto time_data = time(nullptr); - auto time_struct = gmtime(&time_data); - - STLString fmt = std::to_string(kBaseYear + time_struct->tm_year); - - fmt += "-"; - fmt += std::to_string(time_struct->tm_mon + 1); - fmt += "-"; - fmt += std::to_string(time_struct->tm_mday); - - return fmt; -} - -inline bool to_str(Char* str, Int32 limit, Int32 base) noexcept { - if (limit == 0) return false; - - Int32 copy_limit = limit; - Int32 cnt = 0; - Int32 ret = base; - - while (limit != 1) { - ret = ret % 10; - str[cnt] = ret; - - ++cnt; - --limit; - --ret; - } - - str[copy_limit] = '\0'; - return true; -} - -inline bool install_signal(Int32 signal, void (*handler)(int)) noexcept { - if (handler == nullptr) return false; - - if (::signal(signal, handler) == SIG_ERR) { - return false; - } - - return true; -} -} // namespace CompilerKit diff --git a/src/CompilerKit/Detail/Power64.h b/src/CompilerKit/Detail/Power64.h deleted file mode 100644 index 7c7f67c..0000000 --- a/src/CompilerKit/Detail/Power64.h +++ /dev/null @@ -1,1557 +0,0 @@ -/* ======================================== - - Some modifications are copyrighted under: - Amlal El Mahrouss - - Original author: - Apple Inc - -======================================== */ - -#pragma once - -#include - -/// @note Based of: -/// https://opensource.apple.com/source/cctools/cctools-750/as/ppc-opcode.h.auto.html - -#define kOpcodePPCCount (1073U) - -/* - * These defines are use in the cpus field of the instructions. If the field - * is zero it can execute on all cpus. The defines are or'ed together. This - * information is used to set the cpusubtype in the resulting object file. - */ -#define CPU601 0x1 -#define IMPL64 0x2 -#define OPTIONAL 0x4 -#define VMX 0x8 -#define CPU970 0x10 /* added to OPTIONAL insts that the 970 has */ -#define CPUMAHROUSS 0x12 /* optional mahrouss insts. */ - -enum OpcodeType { - NONE, /* no operand */ - JBSR, /* jbsr pseudo op */ - PCREL, /* PC relative (branch offset) */ - BADDR, /* Branch address (sign extended absolute address) */ - D, /* 16 bit displacement */ - DS, /* 14 bit displacement (double word) */ - SI, /* signed 16 bit immediate */ - UI, /* unsigned 16 bit immediate */ - HI, /* high 16 bit immediate (with truncation) */ - GREG, /* general register */ - G0REG, /* general register r1-r31 or 0 */ - FREG, /* float register */ - VREG, /* vector register */ - SGREG, /* segment register */ - SPREG, /* special register (or 10 bit number, 5 bit halves reversed) */ - BCND, /* branch condition opcode */ - CRF, /* condition register field */ - CRFONLY, /* condition register field only no expression allowed */ - sh, /* 6 bit number (0 - 63) (sh field, split and reversed) */ - mb, /* 6 bit number (0 - 63) (mb field, mb5 || mb0:4 reversed) */ - NUM, /* number */ - SNUM, /* signed number */ - NUM0, /* number (where 1< -#include -#include -#include -#include -#include - -#define kDistVersion "v0.0.7-compilerkit" -#define kDistVersionBCD 0x0002 - -#define ToString(X) Stringify(X) -#define Stringify(X) #X - -#define kDistRelease ToString(kDistReleaseBranch) - -#ifndef kDistRelease - -#define kDistVersion "v0.0.7-compilerkit" -#define kDistVersionBCD 0x0002 - -#define ToString(X) Stringify(X) -#define Stringify(X) #X - -#define kDistRelease ToString(kDistReleaseBranch) - -#endif // !kDistRelease - -#define MUST_PASS(E) assert(E) - -#ifndef __FORCE_STRLEN -#define __FORCE_STRLEN 1 - -#define string_length(len) strlen(len) -#endif - -#ifndef __FORCE_MEMCPY -#define __FORCE_MEMCPY 1 - -#define rt_copy_memory(dst, src, len) memcpy(dst, src, len) -#endif - -#define ATTRIBUTE(X) __attribute__((X)) -#define PACKED ATTRIBUTE(packed) - -#define kObjectFileExt ".obj" -#define kBinaryFileExt ".bin" - -#define kAsmFileExts {".64x", ".32x", ".masm", ".s", ".S", ".asm", ".x64"} - -#define kAsmFileExtsMax (7U) - -#define NECTI_MODULE(name) extern "C" int name(int argc, char** argv) - -#ifdef MSVC -#pragma scalar_storage_order big - endian -#endif // ifdef MSVC - -#define NECTI_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define NECTI_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define NECTI_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define NECTI_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; - -#define CK_IMPORT_C extern "C" -#define CK_IMPORT extern diff --git a/src/CompilerKit/ErrorID.h b/src/CompilerKit/ErrorID.h deleted file mode 100644 index 3e3b0d7..0000000 --- a/src/CompilerKit/ErrorID.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include - -/// =========================================================== /// -/// @file ErrorID.h -/// @author Amlal El Mahrouss -/// @brief Error IDs for CompilerKit. -/// =========================================================== /// - -#define NECTI_SUCCESS 0 -#define NECTI_EXEC_ERROR -30 -#define NECTI_FILE_NOT_FOUND -31 -#define NECTI_DIR_NOT_FOUND -32 -#define NECTI_FILE_EXISTS -33 -#define NECTI_TOO_LONG -34 -#define NECTI_INVALID_DATA -35 -#define NECTI_UNIMPLEMENTED -36 -#define NECTI_FAT_ERROR -37 -#define NECTI_INVALID_ARCH -38 diff --git a/src/CompilerKit/ErrorOr.h b/src/CompilerKit/ErrorOr.h deleted file mode 100644 index 100624e..0000000 --- a/src/CompilerKit/ErrorOr.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -/// =========================================================== /// -/// @file ErrorOr.h -/// @author Amlal El Mahrouss -/// @brief ErrorOr for CompilerKit. -/// =========================================================== /// - -#include -#include -#include - -namespace CompilerKit { -using ErrorT = Int32; - -template -class ErrorOr final { - public: - ErrorOr() = default; - ~ErrorOr() = default; - - public: - explicit ErrorOr(ErrorT err) : mId(err) {} - explicit ErrorOr(std::nullptr_t null) {} - explicit ErrorOr(T klass) : mRef(klass) {} - - ErrorOr& operator=(const ErrorOr&) = default; - ErrorOr(const ErrorOr&) = default; - - Ref& Leak() { return mRef; } - - ErrorT Error() { return mId; } - - bool HasError() { return mId != NECTI_SUCCESS; } - - explicit operator bool() { return mRef; } - - private: - Ref mRef; - ErrorT mId{0}; -}; - -using ErrorOrAny = ErrorOr; -using ErrorOrString = ErrorOr; -} // namespace CompilerKit diff --git a/src/CompilerKit/Macros.h b/src/CompilerKit/Macros.h deleted file mode 100644 index 6cef758..0000000 --- a/src/CompilerKit/Macros.h +++ /dev/null @@ -1,28 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -/// @brief provide support for Macros.h header. - -#ifndef _NECTI_MACROS_H_ -#define _NECTI_MACROS_H_ - -#define NECTI_COPY_DELETE(KLASS) \ - KLASS& operator=(const KLASS&) = delete; \ - KLASS(const KLASS&) = delete; - -#define NECTI_COPY_DEFAULT(KLASS) \ - KLASS& operator=(const KLASS&) = default; \ - KLASS(const KLASS&) = default; - -#define NECTI_MOVE_DELETE(KLASS) \ - KLASS& operator=(KLASS&&) = delete; \ - KLASS(KLASS&&) = delete; - -#define NECTI_MOVE_DEFAULT(KLASS) \ - KLASS& operator=(KLASS&&) = default; \ - KLASS(KLASS&&) = default; - -#endif /* ifndef _NECTI_MACROS_H_ */ diff --git a/src/CompilerKit/PEF.h b/src/CompilerKit/PEF.h deleted file mode 100644 index 2838f52..0000000 --- a/src/CompilerKit/PEF.h +++ /dev/null @@ -1,138 +0,0 @@ -/* ========================================= - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include - -// @file PEF.h -// @brief Preferred Executable Format - -#define kPefMagic "Open" -#define kPefMagicFat "nepO" - -#define kPefExt ".exec" -#define kPefDylibExt ".dylib" -#define kPefLibExt ".lib" -#define kPefObjectExt ".obj" -#define kPefDebugExt ".dbg" -#define kPefDriverExt ".sys" - -#define kPefZero128 ".zero128" -#define kPefCode128 ".code128" -#define kPefData128 ".data128" - -#define kPefZero64 ".zero64" -#define kPefCode64 ".code64" -#define kPefData64 ".data64" - -/* @note counting the \0 at the end */ -#define kPefMagicLen (5) - -#define kPefVersion (0x0500) -#define kPefNameLen (255) - -#define kPefBaseOrigin (0x40000000) - -/* @note this doesn't have to be __ImageStart only, any C initialization stub will do. */ -#define kPefStart "__ImageStart" - -namespace CompilerKit { -/* @brief Architecture type. */ -enum { - kPefArchIntel86S, - kPefArchAMD64, - kPefArchRISCV, - kPefArch64000, /* Open64x0 RISC architecture. */ - kPefArch32000, - kPefArchPowerPC, /* 64-bit POWER architecture. */ - kPefArchARM64, - kPefArchCount = (kPefArchARM64 - kPefArchIntel86S) + 1, - kPefArchInvalid = 0xFF, -}; - -/* @brief Architecture vendor. */ -enum { - kPefSubArchGeneric = 0, - kPefSubArchAMD = 200, - kPefSubArchIntel, - kPefSubArchARM, - kPefSubArchIBM, -}; - -enum { - kPefKindInvalid = 0, - kPefKindExec = 1, /* .exec */ - kPefKindDylib = 2, /* .dylib */ - kPefKindObject = 4, /* .obj */ - kPefKindDebug = 5, /* .dbg */ - kPefKindDriver = 6, - kPefKindCount, -}; - -/* PEF container information */ -typedef struct PEFContainer final { - Char Magic[kPefMagicLen]; - UInt32 Linker; /* Linker used to link executable */ - UInt32 Version; - UInt32 Kind; - UInt32 Abi; - UInt32 Cpu; - UInt32 SubCpu; /* Cpu specific information */ - UIntPtr Start; /* Origin of code */ - SizeType HdrSz; /* Size of header */ - SizeType Count; /* container header count */ - UInt32 Checksum; /* Whole binary checksum */ -} PACKED PEFContainer, *PEFContainerPtr; - -/* First PEFCommandHeader starts after PEFContainer */ -/* Last container is __exec_end */ - -/* PEF executable section and commands. */ - -/* @brief Command Header, a la Mach-O, designed with FAT binaries and virtual memory in mind. */ -typedef struct PEFCommandHeader final { - Char Name[kPefNameLen]; /* container name */ - UInt32 Cpu; /* container cpu */ - UInt32 SubCpu; /* container sub-cpu */ - UInt32 Flags; /* container flags */ - UInt16 Kind; /* container kind */ - UIntPtr Offset; /* File offset */ - SizeType OffsetSize; - UIntPtr VirtualAddress; /* Virtual Address */ - SizeType VirtualSize; /* Virtual Size */ -} PACKED PEFCommandHeader, *PEFCommandHeaderPtr; - -enum { - kPefInvalid = 0x0, - kPefCode = 0xC, - kPefData = 0xD, - kPefZero = 0xE, - kPefLinkerID = 0x1, - kPefCount = 4, -}; -} // namespace CompilerKit - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFContainer& container) { - fp.write((char*) &container, sizeof(CompilerKit::PEFContainer)); - return fp; -} - -inline std::ofstream& operator<<(std::ofstream& fp, CompilerKit::PEFCommandHeader& container) { - fp.write((char*) &container, sizeof(CompilerKit::PEFCommandHeader)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::PEFContainer& container) { - fp.read((char*) &container, sizeof(CompilerKit::PEFContainer)); - return fp; -} - -inline std::ifstream& operator>>(std::ifstream& fp, CompilerKit::PEFCommandHeader& container) { - fp.read((char*) &container, sizeof(CompilerKit::PEFCommandHeader)); - return fp; -} diff --git a/src/CompilerKit/Ref.h b/src/CompilerKit/Ref.h deleted file mode 100644 index 863a100..0000000 --- a/src/CompilerKit/Ref.h +++ /dev/null @@ -1,77 +0,0 @@ - -/* - * ======================================================== - * - * CompilerKit - * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. - * - * ======================================================== - */ - -#pragma once - -#include - -namespace CompilerKit { -/// @author Amlal El Mahrouss -/// @brief Reference holder class, refers to a pointer of data in static memory. -template -class Ref final { - public: - explicit Ref() = default; - - ~Ref() { - if (m_Strong) { - MUST_PASS(m_Class); - if (m_Class) delete m_Class; - m_Class = nullptr; - } - } - - NECTI_COPY_DEFAULT(Ref); - - public: - explicit Ref(T* cls, const bool& strong = false) : m_Class(cls), m_Strong(strong) {} - - Ref& operator=(T ref) { - *m_Class = ref; - return *this; - } - - public: - T* operator->() const { return m_Class; } - - T& Leak() { return *m_Class; } - - T operator*() { return *m_Class; } - - bool IsStrong() const { return m_Strong; } - - explicit operator bool() { return *m_Class; } - - private: - T* m_Class{nullptr}; - bool m_Strong{false}; -}; - -// @author Amlal El Mahrouss -// @brief Non null Reference holder class, refers to a pointer of data in static memory. -template -class NonNullRef final { - public: - explicit NonNullRef() = delete; - - explicit NonNullRef(T* ref) : m_Ref(ref, true) {} - - Ref& operator->() { - MUST_PASS(m_Ref); - return m_Ref; - } - - NonNullRef& operator=(const NonNullRef& ref) = delete; - NonNullRef(const NonNullRef& ref) = default; - - private: - Ref m_Ref{nullptr}; -}; -} // namespace CompilerKit diff --git a/src/CompilerKit/UUID.h b/src/CompilerKit/UUID.h deleted file mode 100644 index 2993b8b..0000000 --- a/src/CompilerKit/UUID.h +++ /dev/null @@ -1,826 +0,0 @@ -#ifndef STDUUID_H -#define STDUUID_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus - -#if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) -#define LIBUUID_CPP20_OR_GREATER -#endif - -#endif - -#ifdef LIBUUID_CPP20_OR_GREATER -#include -#else -#include -#endif - -#ifdef _WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#ifdef UUID_SYSTEM_GENERATOR -#include -#endif - -#ifdef UUID_TIME_GENERATOR -#include -#pragma comment(lib, "IPHLPAPI.lib") -#endif - -#elif defined(__linux__) || defined(__unix__) - -#ifdef UUID_SYSTEM_GENERATOR -#include -#endif - -#elif defined(__APPLE__) - -#ifdef UUID_SYSTEM_GENERATOR -#include -#endif - -#endif - -namespace uuids { -#ifdef __cpp_lib_span -template -using span = std::span; -#else -template -using span = gsl::span; -#endif - -namespace Detail { - template - [[nodiscard]] constexpr inline unsigned char hex2char(TChar const ch) noexcept { - if (ch >= static_cast('0') && ch <= static_cast('9')) - return static_cast(ch - static_cast('0')); - if (ch >= static_cast('a') && ch <= static_cast('f')) - return static_cast(10 + ch - static_cast('a')); - if (ch >= static_cast('A') && ch <= static_cast('F')) - return static_cast(10 + ch - static_cast('A')); - return 0; - } - - template - [[nodiscard]] constexpr std::basic_string_view to_string_view(TChar const* str) noexcept { - return str; - } - - template - [[nodiscard]] constexpr std::basic_string_view - to_string_view(StringType const& str) noexcept { - return str; - } - - class sha1 { - public: - using digest32_t = uint32_t[5]; - using digest8_t = uint8_t[20]; - - static constexpr unsigned int block_bytes = 64; - - [[nodiscard]] inline static uint32_t left_rotate(uint32_t value, size_t const count) noexcept { - return (value << count) ^ (value >> (32 - count)); - } - - sha1() { reset(); } - - void reset() noexcept { - m_digest[0] = 0x67452301; - m_digest[1] = 0xEFCDAB89; - m_digest[2] = 0x98BADCFE; - m_digest[3] = 0x10325476; - m_digest[4] = 0xC3D2E1F0; - m_blockByteIndex = 0; - m_byteCount = 0; - } - - void process_byte(uint8_t octet) { - this->m_block[this->m_blockByteIndex++] = octet; - ++this->m_byteCount; - if (m_blockByteIndex == block_bytes) { - this->m_blockByteIndex = 0; - process_block(); - } - } - - void process_block(void const* const start, void const* const end) { - const uint8_t* begin = static_cast(start); - const uint8_t* finish = static_cast(end); - while (begin != finish) { - process_byte(*begin); - begin++; - } - } - - void process_bytes(void const* const data, size_t const len) { - const uint8_t* block = static_cast(data); - process_block(block, block + len); - } - - uint32_t const* get_digest(digest32_t digest) { - size_t const bitCount = this->m_byteCount * 8; - process_byte(0x80); - if (this->m_blockByteIndex > 56) { - while (m_blockByteIndex != 0) { - process_byte(0); - } - while (m_blockByteIndex < 56) { - process_byte(0); - } - } else { - while (m_blockByteIndex < 56) { - process_byte(0); - } - } - process_byte(0); - process_byte(0); - process_byte(0); - process_byte(0); - 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)); - - memcpy(digest, m_digest, 5 * sizeof(uint32_t)); - return digest; - } - - uint8_t const* get_digest_bytes(digest8_t digest) { - digest32_t d32; - get_digest(d32); - size_t di = 0; - digest[di++] = static_cast(d32[0] >> 24); - digest[di++] = static_cast(d32[0] >> 16); - digest[di++] = static_cast(d32[0] >> 8); - digest[di++] = static_cast(d32[0] >> 0); - - digest[di++] = static_cast(d32[1] >> 24); - digest[di++] = static_cast(d32[1] >> 16); - digest[di++] = static_cast(d32[1] >> 8); - digest[di++] = static_cast(d32[1] >> 0); - - digest[di++] = static_cast(d32[2] >> 24); - digest[di++] = static_cast(d32[2] >> 16); - digest[di++] = static_cast(d32[2] >> 8); - digest[di++] = static_cast(d32[2] >> 0); - - digest[di++] = static_cast(d32[3] >> 24); - digest[di++] = static_cast(d32[3] >> 16); - digest[di++] = static_cast(d32[3] >> 8); - digest[di++] = static_cast(d32[3] >> 0); - - digest[di++] = static_cast(d32[4] >> 24); - digest[di++] = static_cast(d32[4] >> 16); - digest[di++] = static_cast(d32[4] >> 8); - digest[di++] = static_cast(d32[4] >> 0); - - return digest; - } - - private: - void process_block() { - uint32_t w[80]; - for (size_t i = 0; i < 16; i++) { - w[i] = static_cast(m_block[i * 4 + 0] << 24); - w[i] |= static_cast(m_block[i * 4 + 1] << 16); - w[i] |= static_cast(m_block[i * 4 + 2] << 8); - w[i] |= static_cast(m_block[i * 4 + 3]); - } - for (size_t i = 16; i < 80; i++) { - w[i] = left_rotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1); - } - - uint32_t a = m_digest[0]; - uint32_t b = m_digest[1]; - uint32_t c = m_digest[2]; - uint32_t d = m_digest[3]; - uint32_t e = m_digest[4]; - - for (std::size_t i = 0; i < 80; ++i) { - uint32_t f = 0; - uint32_t k = 0; - - if (i < 20) { - f = (b & c) | (~b & d); - k = 0x5A827999; - } else if (i < 40) { - f = b ^ c ^ d; - k = 0x6ED9EBA1; - } else if (i < 60) { - f = (b & c) | (b & d) | (c & d); - k = 0x8F1BBCDC; - } else { - f = b ^ c ^ d; - k = 0xCA62C1D6; - } - uint32_t temp = left_rotate(a, 5) + f + e + k + w[i]; - e = d; - d = c; - c = left_rotate(b, 30); - b = a; - a = temp; - } - - m_digest[0] += a; - m_digest[1] += b; - m_digest[2] += c; - m_digest[3] += d; - m_digest[4] += e; - } - - private: - digest32_t m_digest; - uint8_t m_block[64]; - size_t m_blockByteIndex; - size_t m_byteCount; - }; - - template - inline constexpr CharT empty_guid[37] = "00000000-0000-0000-0000-000000000000"; - - template <> - inline constexpr wchar_t empty_guid[37] = L"00000000-0000-0000-0000-000000000000"; - - template - inline constexpr CharT guid_encoder[17] = "0123456789abcdef"; - - template <> - inline constexpr wchar_t guid_encoder[17] = L"0123456789abcdef"; -} // namespace Detail - -// -------------------------------------------------------------------------------------------------------------------------- -// UUID format https://tools.ietf.org/html/rfc4122 -// -------------------------------------------------------------------------------------------------------------------------- - -// -------------------------------------------------------------------------------------------------------------------------- -// Field NDR Data Type Octet # Note -// -------------------------------------------------------------------------------------------------------------------------- -// time_low unsigned long 0 - 3 The low field -// of the timestamp. time_mid unsigned short 4 - 5 -// The middle field of the timestamp. time_hi_and_version unsigned -// short 6 - 7 The high field of the timestamp multiplexed -// with the version number. clock_seq_hi_and_reserved unsigned small 8 -// The high field of the clock sequence multiplexed with the variant. -// clock_seq_low unsigned small 9 The low -// field of the clock sequence. node character 10 -// - 15 The spatially unique node identifier. -// -------------------------------------------------------------------------------------------------------------------------- -// 0 1 2 3 -// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | time_low | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | time_mid | time_hi_and_version | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// |clk_seq_hi_res | clk_seq_low | node (0-1) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -// | node (2-5) | -// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - -// -------------------------------------------------------------------------------------------------------------------------- -// enumerations -// -------------------------------------------------------------------------------------------------------------------------- - -// indicated by a bit pattern in octet 8, marked with N in -// xxxxxxxx-xxxx-xxxx-Nxxx-xxxxxxxxxxxx -enum class uuid_variant { - // NCS backward compatibility (with the obsolete Apollo Network Computing - // System 1.5 UUID format) N bit pattern: 0xxx > the first 6 octets of the - // UUID are a 48-bit timestamp (the number of 4 microsecond units of time - // since 1 Jan 1980 UTC); > the next 2 octets are reserved; > the next octet - // is the "address family"; > the final 7 octets are a 56-bit host ID in the - // form specified by the address family - ncs, - - // RFC 4122/DCE 1.1 - // N bit pattern: 10xx - // > big-endian byte order - rfc, - - // Microsoft Corporation backward compatibility - // N bit pattern: 110x - // > little endian byte order - // > formely used in the Component Object Model (COM) library - microsoft, - - // reserved for possible future definition - // N bit pattern: 111x - reserved -}; - -// indicated by a bit pattern in octet 6, marked with M in -// xxxxxxxx-xxxx-Mxxx-xxxx-xxxxxxxxxxxx -enum class uuid_version { - none = 0, // only possible for nil or invalid uuids - time_based = 1, // The time-based version specified in RFC 4122 - dce_security = 2, // DCE Security version, with embedded POSIX UIDs. - name_based_md5 = 3, // The name-based version specified in RFS 4122 with MD5 hashing - random_number_based = 4, // The randomly or pseudo-randomly generated version - // specified in RFS 4122 - name_based_sha1 = 5 // The name-based version specified in RFS 4122 with SHA1 hashing -}; - -// Forward declare uuid & to_string so that we can declare to_string as a friend -// later. -class uuid; -template , - class Allocator = std::allocator> -std::basic_string to_string(uuid const& id); - -// -------------------------------------------------------------------------------------------------------------------------- -// uuid class -// -------------------------------------------------------------------------------------------------------------------------- -class uuid { - public: - using value_type = uint8_t; - - constexpr uuid() noexcept = default; - - uuid(value_type (&arr)[16]) noexcept { - std::copy(std::cbegin(arr), std::cend(arr), std::begin(data)); - } - - constexpr uuid(std::array const& arr) noexcept : data{arr} {} - - explicit uuid(span bytes) { - std::copy(std::cbegin(bytes), std::cend(bytes), std::begin(data)); - } - - template - explicit uuid(ForwardIterator first, ForwardIterator last) { - if (std::distance(first, last) == 16) std::copy(first, last, std::begin(data)); - } - - [[nodiscard]] constexpr uuid_variant variant() const noexcept { - if ((data[8] & 0x80) == 0x00) - return uuid_variant::ncs; - else if ((data[8] & 0xC0) == 0x80) - return uuid_variant::rfc; - else if ((data[8] & 0xE0) == 0xC0) - return uuid_variant::microsoft; - else - return uuid_variant::reserved; - } - - [[nodiscard]] constexpr uuid_version version() const noexcept { - if ((data[6] & 0xF0) == 0x10) - return uuid_version::time_based; - else if ((data[6] & 0xF0) == 0x20) - return uuid_version::dce_security; - else if ((data[6] & 0xF0) == 0x30) - return uuid_version::name_based_md5; - else if ((data[6] & 0xF0) == 0x40) - return uuid_version::random_number_based; - else if ((data[6] & 0xF0) == 0x50) - return uuid_version::name_based_sha1; - else - return uuid_version::none; - } - - [[nodiscard]] constexpr bool is_nil() const noexcept { - for (size_t i = 0; i < data.size(); ++i) - if (data[i] != 0) return false; - return true; - } - - void swap(uuid& other) noexcept { data.swap(other.data); } - - [[nodiscard]] inline span as_bytes() const { - return span(reinterpret_cast(data.data()), 16); - } - - template - [[nodiscard]] constexpr static bool is_valid_uuid(StringType const& in_str) noexcept { - auto str = Detail::to_string_view(in_str); - bool firstDigit = true; - size_t hasBraces = 0; - size_t index = 0; - - if (str.empty()) return false; - - if (str.front() == '{') hasBraces = 1; - if (hasBraces && str.back() != '}') return false; - - for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) { - if (str[i] == '-') continue; - - if (index >= 16 || !std::isxdigit(static_cast(str[i]))) { - return false; - } - - if (firstDigit) { - firstDigit = false; - } else { - index++; - firstDigit = true; - } - } - - if (index < 16) { - return false; - } - - return true; - } - - template - [[nodiscard]] constexpr static std::optional from_string( - StringType const& in_str) noexcept { - auto str = Detail::to_string_view(in_str); - bool firstDigit = true; - size_t hasBraces = 0; - size_t index = 0; - - std::array data{{0}}; - - if (str.empty()) return {}; - - if (str.front() == '{') hasBraces = 1; - if (hasBraces && str.back() != '}') return {}; - - for (size_t i = hasBraces; i < str.size() - hasBraces; ++i) { - if (str[i] == '-') continue; - - if (index >= 16 || !std::isxdigit(static_cast(str[i]))) { - return {}; - } - - if (firstDigit) { - data[index] = static_cast(Detail::hex2char(str[i]) << 4); - firstDigit = false; - } else { - data[index] = static_cast(data[index] | Detail::hex2char(str[i])); - index++; - firstDigit = true; - } - } - - if (index < 16) { - return {}; - } - - return uuid{data}; - } - - private: - std::array data{{0}}; - - friend bool operator==(uuid const& lhs, uuid const& rhs) noexcept; - friend bool operator<(uuid const& lhs, uuid const& rhs) noexcept; - - template - friend std::basic_ostream& operator<<(std::basic_ostream& s, - uuid const& id); - - template - friend std::basic_string to_string(uuid const& id); - - friend std::hash; -}; - -// -------------------------------------------------------------------------------------------------------------------------- -// operators and non-member functions -// -------------------------------------------------------------------------------------------------------------------------- - -[[nodiscard]] inline bool operator==(uuid const& lhs, uuid const& rhs) noexcept { - return lhs.data == rhs.data; -} - -[[nodiscard]] inline bool operator!=(uuid const& lhs, uuid const& rhs) noexcept { - return !(lhs == rhs); -} - -[[nodiscard]] inline bool operator<(uuid const& lhs, uuid const& rhs) noexcept { - return lhs.data < rhs.data; -} - -template -[[nodiscard]] inline std::basic_string to_string(uuid const& id) { - std::basic_string uustr{Detail::empty_guid}; - - for (size_t i = 0, index = 0; i < 36; ++i) { - if (i == 8 || i == 13 || i == 18 || i == 23) { - continue; - } - uustr[i] = Detail::guid_encoder[id.data[index] >> 4 & 0x0f]; - uustr[++i] = Detail::guid_encoder[id.data[index] & 0x0f]; - index++; - } - - return uustr; -} - -template -std::basic_ostream& operator<<(std::basic_ostream& s, uuid const& id) { - s << to_string(id); - return s; -} - -inline void swap(uuids::uuid& lhs, uuids::uuid& rhs) noexcept { - lhs.swap(rhs); -} - -// -------------------------------------------------------------------------------------------------------------------------- -// namespace IDs that could be used for generating name-based uuids -// -------------------------------------------------------------------------------------------------------------------------- - -// Name string is a fully-qualified domain name -static uuid uuid_namespace_dns{{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is a URL -static uuid uuid_namespace_url{{0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is an ISO OID (See https://oidref.com/, -// https://en.wikipedia.org/wiki/Object_identifier) -static uuid uuid_namespace_oid{{0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// Name string is an X.500 DN, in DER or a text output format (See -// https://en.wikipedia.org/wiki/X.500, -// https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One) -static uuid uuid_namespace_x500{{0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, - 0xc0, 0x4f, 0xd4, 0x30, 0xc8}}; - -// -------------------------------------------------------------------------------------------------------------------------- -// uuid generators -// -------------------------------------------------------------------------------------------------------------------------- - -#ifdef UUID_SYSTEM_GENERATOR -class uuid_system_generator { - public: - using result_type = uuid; - - uuid operator()() { -#ifdef _WIN32 - GUID newId{}; /// AMLALE: Should be zero-initialized. - HRESULT hr = ::CoCreateGuid(&newId); - - if (FAILED(hr)) { - throw std::system_error(hr, std::system_category(), "CoCreateGuid failed"); - } - - std::array bytes = {{static_cast((newId.Data1 >> 24) & 0xFF), - static_cast((newId.Data1 >> 16) & 0xFF), - static_cast((newId.Data1 >> 8) & 0xFF), - static_cast((newId.Data1) & 0xFF), - static_cast((newId.Data2 >> 8) & 0xFF), - static_cast((newId.Data2) & 0xFF), - static_cast((newId.Data3 >> 8) & 0xFF), - static_cast((newId.Data3) & 0xFF), - newId.Data4[0], newId.Data4[1], newId.Data4[2], - newId.Data4[3], newId.Data4[4], newId.Data4[5], - newId.Data4[6], newId.Data4[7]}}; - - return uuid{std::begin(bytes), std::end(bytes)}; - -#elif defined(__linux__) || defined(__unix__) - - uuid_t id; - uuid_generate(id); - - std::array bytes = {{id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], - id[9], id[10], id[11], id[12], id[13], id[14], id[15]}}; - - return uuid{std::begin(bytes), std::end(bytes)}; - -#elif defined(__APPLE__) - auto newId = CFUUIDCreate(NULL); - auto bytes = CFUUIDGetUUIDBytes(newId); - CFRelease(newId); - - std::array arrbytes = {{bytes.byte0, bytes.byte1, bytes.byte2, bytes.byte3, - bytes.byte4, bytes.byte5, bytes.byte6, bytes.byte7, - bytes.byte8, bytes.byte9, bytes.byte10, bytes.byte11, - bytes.byte12, bytes.byte13, bytes.byte14, bytes.byte15}}; - return uuid{std::begin(arrbytes), std::end(arrbytes)}; -#else - return uuid{}; -#endif - } -}; -#endif - -template -class basic_uuid_random_generator { - public: - using engine_type = UniformRandomNumberGenerator; - - explicit basic_uuid_random_generator(engine_type& gen) : generator(&gen, [](auto) {}) {} - explicit basic_uuid_random_generator(engine_type* gen) : generator(gen, [](auto) {}) {} - - [[nodiscard]] uuid operator()() { - alignas(uint32_t) uint8_t bytes[16]; - for (int i = 0; i < 16; i += 4) - *reinterpret_cast(bytes + i) = distribution(*generator); - - // variant must be 10xxxxxx - bytes[8] &= 0xBF; - bytes[8] |= 0x80; - - // version must be 0100xxxx - bytes[6] &= 0x4F; - bytes[6] |= 0x40; - - return uuid{std::begin(bytes), std::end(bytes)}; - } - - private: - std::uniform_int_distribution distribution; - std::shared_ptr generator; -}; - -using uuid_random_generator = basic_uuid_random_generator; - -class uuid_name_generator { - public: - explicit uuid_name_generator(uuid const& namespace_uuid) noexcept : nsuuid(namespace_uuid) {} - - template - [[nodiscard]] uuid operator()(StringType const& name) { - reset(); - process_characters(Detail::to_string_view(name)); - return make_uuid(); - } - - private: - void reset() { - hasher.reset(); - std::byte bytes[16]; - auto nsbytes = nsuuid.as_bytes(); - std::copy(std::cbegin(nsbytes), std::cend(nsbytes), bytes); - hasher.process_bytes(bytes, 16); - } - - template - void process_characters(std::basic_string_view const str) { - for (uint32_t c : str) { - hasher.process_byte(static_cast(c & 0xFF)); - if constexpr (!std::is_same_v) { - hasher.process_byte(static_cast((c >> 8) & 0xFF)); - hasher.process_byte(static_cast((c >> 16) & 0xFF)); - hasher.process_byte(static_cast((c >> 24) & 0xFF)); - } - } - } - - [[nodiscard]] uuid make_uuid() { - Detail::sha1::digest8_t digest; - hasher.get_digest_bytes(digest); - - // variant must be 0b10xxxxxx - digest[8] &= 0xBF; - digest[8] |= 0x80; - - // version must be 0b0101xxxx - digest[6] &= 0x5F; - digest[6] |= 0x50; - - return uuid{digest, digest + 16}; - } - - private: - uuid nsuuid; - Detail::sha1 hasher; -}; - -#ifdef UUID_TIME_GENERATOR -// !!! DO NOT USE THIS IN PRODUCTION -// this implementation is unreliable for good uuids -class uuid_time_generator { - using mac_address = std::array; - - std::optional device_address; - - [[nodiscard]] bool get_mac_address() { - if (device_address.has_value()) { - return true; - } - -#ifdef _WIN32 - DWORD len = 0; - auto ret = GetAdaptersInfo(nullptr, &len); - if (ret != ERROR_BUFFER_OVERFLOW) return false; - std::vector buf(len); - auto pips = reinterpret_cast(&buf.front()); - ret = GetAdaptersInfo(pips, &len); - if (ret != ERROR_SUCCESS) return false; - mac_address addr; - std::copy(pips->Address, pips->Address + 6, std::begin(addr)); - device_address = addr; -#endif - - return device_address.has_value(); - } - - [[nodiscard]] long long get_time_intervals() { - auto start = std::chrono::system_clock::from_time_t(time_t(-12219292800)); - auto diff = std::chrono::system_clock::now() - start; - auto ns = std::chrono::duration_cast(diff).count(); - return ns / 100; - } - - [[nodiscard]] static unsigned short get_clock_sequence() { - static std::mt19937 clock_gen(std::random_device{}()); - static std::uniform_int_distribution clock_dis; - static std::atomic_ushort clock_sequence = clock_dis(clock_gen); - return clock_sequence++; - } - - public: - [[nodiscard]] uuid operator()() { - if (get_mac_address()) { - std::array data; - - auto tm = get_time_intervals(); - - auto clock_seq = get_clock_sequence(); - - auto ptm = reinterpret_cast(&tm); - - memcpy(&data[0], ptm + 4, 4); - memcpy(&data[4], ptm + 2, 2); - memcpy(&data[6], ptm, 2); - - memcpy(&data[8], &clock_seq, 2); - - // variant must be 0b10xxxxxx - data[8] &= 0xBF; - data[8] |= 0x80; - - // version must be 0b0001xxxx - data[6] &= 0x1F; - data[6] |= 0x10; - - memcpy(&data[10], &device_address.value()[0], 6); - - return uuids::uuid{std::cbegin(data), std::cend(data)}; - } - - return {}; - } -}; -#endif -} // namespace uuids - -namespace std { -template <> -struct hash { - using argument_type = uuids::uuid; - using result_type = std::size_t; - - [[nodiscard]] result_type operator()(argument_type const& uuid) const { -#ifdef UUID_HASH_STRING_BASED - std::hash hasher; - return static_cast(hasher(uuids::to_string(uuid))); -#else - uint64_t l = - static_cast(uuid.data[0]) << 56 | static_cast(uuid.data[1]) << 48 | - static_cast(uuid.data[2]) << 40 | static_cast(uuid.data[3]) << 32 | - static_cast(uuid.data[4]) << 24 | static_cast(uuid.data[5]) << 16 | - static_cast(uuid.data[6]) << 8 | static_cast(uuid.data[7]); - uint64_t h = - static_cast(uuid.data[8]) << 56 | static_cast(uuid.data[9]) << 48 | - static_cast(uuid.data[10]) << 40 | static_cast(uuid.data[11]) << 32 | - static_cast(uuid.data[12]) << 24 | static_cast(uuid.data[13]) << 16 | - static_cast(uuid.data[14]) << 8 | static_cast(uuid.data[15]); - - if constexpr (sizeof(result_type) > 4) { - return result_type(l ^ h); - } else { - uint64_t hash64 = l ^ h; - return result_type(uint32_t(hash64 >> 32) ^ uint32_t(hash64)); - } -#endif - } -}; -} // namespace std - -#endif /* STDUUID_H */ diff --git a/src/CompilerKit/Utilities/Assembler.h b/src/CompilerKit/Utilities/Assembler.h deleted file mode 100644 index fc965f0..0000000 --- a/src/CompilerKit/Utilities/Assembler.h +++ /dev/null @@ -1,92 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include -#include - -using namespace CompilerKit; - -/// @brief Get Number from lineBuffer. -/// @param lineBuffer the lineBuffer to fetch from. -/// @param numberKey where to seek that number. -/// @return A numbercast of 32-bit width. -static NumberCast32 GetNumber32(STLString lineBuffer, STLString numberKey) { - auto pos = lineBuffer.find(numberKey) + numberKey.size(); - - while (lineBuffer[pos] == ' ') { - ++pos; - } - - switch (lineBuffer[pos + 1]) { - case 'x': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 16); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid hex number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_hex"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 16)); - - if (kVerbose) { - kStdOut << "asm: found a base 16 number here: " << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - case 'b': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 2); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid binary number:" + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_bin"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 2)); - - if (kVerbose) { - kStdOut << "asm: found a base 2 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - case 'o': { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 7); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid octal number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_octal"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 7)); - - if (kVerbose) { - kStdOut << "asm: found a base 8 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - default: { - if (auto res = strtol(lineBuffer.substr(pos).c_str(), nullptr, 10); !res) { - if (errno != 0) { - CompilerKit::Detail::print_error("invalid hex number: " + lineBuffer, "CompilerKit"); - throw std::runtime_error("invalid_hex"); - } - } - - NumberCast32 numOffset(strtol(lineBuffer.substr(pos).c_str(), nullptr, 10)); - - if (kVerbose) { - kStdOut << "asm: found a base 10 number here:" << lineBuffer.substr(pos) << "\n"; - } - - return numOffset; - } - } -} diff --git a/src/CompilerKit/Utilities/Compiler.h b/src/CompilerKit/Utilities/Compiler.h deleted file mode 100644 index bbca020..0000000 --- a/src/CompilerKit/Utilities/Compiler.h +++ /dev/null @@ -1,123 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#define kZero64Section ".zero64" -#define kCode64Section ".code64" -#define kData64Section ".data64" - -#define kZero128Section ".zero128" -#define kCode128Section ".code128" -#define kData128Section ".data128" - -#define kBlank "\e[0;30m" -#define kRed "\e[0;31m" -#define kWhite "\e[0;97m" -#define kYellow "\e[0;33m" - -#define kStdOut (std::cout << kRed << "drv: " << kWhite) -#define kStdErr (std::cerr << kYellow << "drv: " << kWhite) - -#define kPrintF kStdOut -#define kPrintErr kStdErr - -inline static UInt32 kErrorLimit = 10; -inline static UInt32 kAcceptableErrors = 0; -inline static bool kVerbose = false; -inline static bool kOutputAsBinary = false; - -namespace CompilerKit::Detail { -/// @brief Blob structure -struct Blob final { - std::vector mBlob{}; // PEF code/bss/data blob. - UIntPtr mOffset{0UL}; // the offset of the PEF container header... - - explicit operator bool() { - return mBlob.empty() && mOffset > 0UL; - } -}; - -inline void print_error(STLString reason, STLString file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - kStdErr << reason << kBlank << std::endl; - - if (kAcceptableErrors > kErrorLimit) std::exit(NECTI_EXEC_ERROR); - - ++kAcceptableErrors; -} - -inline void print_warning(STLString reason, STLString file) noexcept { - if (reason[0] == '\n') reason.erase(0, 1); - - kStdOut << kYellow << reason << kBlank << std::endl; -} - -/// @internal -/// @brief Handler for SIGSEGV signal. -inline void drvi_crash_handler(std::int32_t id) { - CompilerKit::STLString verbose_header = "LIBCOMPILER CRASH REPORT - "; - verbose_header += kDistVersion; - verbose_header += " - "; - verbose_header += CompilerKit::current_date(); - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::cout << verbose_header << std::endl; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - kStdOut << "DATE: " << CompilerKit::current_date() << std::endl; - kStdOut << "VERSION: " << kDistVersion << std::endl; - kStdOut << "ERRNO: " << errno << std::endl; - kStdOut << "ERRNO(STRING): " << strerror(errno) << std::endl; - - switch (id) { - case SIGSEGV: { - kStdOut << "SIGNAL: Segmentation Fault." << kBlank << std::endl; - break; - } - case SIGABRT: { - kStdOut << "SIGNAL: Aborted." << kBlank << std::endl; - break; - } - } - - std::cout << kWhite; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::cout << verbose_header << std::endl; - - for (auto& ch : verbose_header) { - std::cout << '='; - } - - std::cout << std::endl; - - std::exit(NECTI_EXEC_ERROR); -} -} // namespace Detail diff --git a/src/CompilerKit/Utilities/DLL.h b/src/CompilerKit/Utilities/DLL.h deleted file mode 100644 index 5bfe032..0000000 --- a/src/CompilerKit/Utilities/DLL.h +++ /dev/null @@ -1,67 +0,0 @@ -/* ======================================== - - Copyright (C) 2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - -======================================== */ - -#pragma once - -#include -#include -#include - -struct CompilerKitDylibTraits; - -typedef Int32 (*CompilerKitEntrypoint)(Int32 argc, Char const* argv[]); -typedef VoidPtr CompilerKitDylib; - -struct CompilerKitDylibTraits final { - CompilerKitDylib fDylib{nullptr}; - CompilerKitEntrypoint fEntrypoint{nullptr}; - std::mutex fMutex; - - explicit operator bool() { - return fDylib && fEntrypoint; - } - - CompilerKitDylibTraits& operator()(const Char* path, const Char* fEntrypoint) { - std::lock_guard lock(this->fMutex); - - if (!path || !fEntrypoint) return *this; - - if (this->fDylib) { - dlclose(this->fDylib); - this->fDylib = nullptr; - } - - this->fDylib = dlopen(path, RTLD_LAZY); - - if (!this->fDylib) { - return *this; - } - - this->fEntrypoint = (CompilerKitEntrypoint) dlsym(this->fDylib, fEntrypoint); - - if (!this->fEntrypoint) { - dlclose(this->fDylib); - this->fDylib = nullptr; - - return *this; - } - - return *this; - } - - NECTI_COPY_DELETE(CompilerKitDylibTraits); - - CompilerKitDylibTraits() = default; - - ~CompilerKitDylibTraits() { - if (this->fDylib) { - dlclose(this->fDylib); - this->fDylib = nullptr; - } - - this->fEntrypoint = nullptr; - } -}; diff --git a/src/CompilerKit/XCOFF.h b/src/CompilerKit/XCOFF.h deleted file mode 100644 index 777f501..0000000 --- a/src/CompilerKit/XCOFF.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license - - File: XCOFF.h - Purpose: XCOFF for NeKernel. - - Revision History: - - 04/07/24: Added file (Amlal El Mahrouss) - -======================================== */ - -#ifndef _NECTI_XCOFF_H_ -#define _NECTI_XCOFF_H_ - -#include - -#define kXCOFF64Magic 0x01F7 - -#define kXCOFFRelFlg 0x0001 -#define kXCOFFExecutable 0x0002 -#define kXCOFFLnno 0x0004 -#define kXCOFFLSyms 0x0008 - -namespace CompilerKit { -struct XCoffFileHeader; - -/// @brief XCoff file header. -typedef struct XCoffFileHeader { - UInt16 fMagic; - UInt16 fTarget; - UInt16 fNumSecs; - UInt32 fTimeDat; - UIntPtr fSymPtr; - UInt32 fNumSyms; - UInt16 fOptHdr; // ?: Number of bytes in optional header -} XCoffFileHeader; - -typedef struct XCoffFileHeader* XCoffFileHeaderPtr; -} // namespace CompilerKit - -#endif // ifndef _NECTI_XCOFF_H_ diff --git a/src/CompilerKit/ck-osx-san.json b/src/CompilerKit/ck-osx-san.json index df1c36b..c0913aa 100644 --- a/src/CompilerKit/ck-osx-san.json +++ b/src/CompilerKit/ck-osx-san.json @@ -2,11 +2,11 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl", - "/opt/homebrew/Cellar/boost/1.87.0/include" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl", + "/opt/homebrew/Cellar/boost/1.89.0/include" ], "sources_path": [ "src/*.cc", diff --git a/src/CompilerKit/ck-osx.json b/src/CompilerKit/ck-osx.json index cab0221..a17d483 100644 --- a/src/CompilerKit/ck-osx.json +++ b/src/CompilerKit/ck-osx.json @@ -2,11 +2,11 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl", - "/opt/homebrew/Cellar/boost/1.87.0/include" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl", + "/opt/homebrew/Cellar/boost/1.89.0/include" ], "sources_path": [ "src/*.cc", diff --git a/src/CompilerKit/ck-posix.json b/src/CompilerKit/ck-posix.json index b748f7a..3f6127c 100644 --- a/src/CompilerKit/ck-posix.json +++ b/src/CompilerKit/ck-posix.json @@ -2,10 +2,10 @@ "compiler_path": "clang++", "compiler_std": "c++20", "headers_path": [ - "../CompilerKit", - "../", - "../CompilerKit/src/", - "../CompilerKit/src/impl" + "../../include/CompilerKit", + "../../include/", + "../../include/CompilerKit/src/", + "../../include/CompilerKit/src/impl" ], "sources_path": [ "src/*.cc", -- cgit v1.2.3