summaryrefslogtreecommitdiffhomepage
path: root/Comm/StdKit
diff options
context:
space:
mode:
authorAmlal EL Mahrouss <amlal@softwarelabs.com>2024-06-09 19:57:20 +0200
committerAmlal EL Mahrouss <amlal@softwarelabs.com>2024-06-09 19:57:20 +0200
commit0aebad569eef2989e32d9825ce52708371685ff9 (patch)
tree29faa339ef63d65f02cbb8c549dd6f5f047a4f68 /Comm/StdKit
parent54ace477f90b5bd17ddd7c5d11c2e319f19555bd (diff)
MHR-21: Finish C++ compiler.
Signed-off-by: Amlal EL Mahrouss <amlal@softwarelabs.com>
Diffstat (limited to 'Comm/StdKit')
-rw-r--r--Comm/StdKit/AE.hpp143
-rw-r--r--Comm/StdKit/ELF.hpp389
-rw-r--r--Comm/StdKit/ErrorID.hpp22
-rw-r--r--Comm/StdKit/ErrorOr.hpp61
-rw-r--r--Comm/StdKit/PEF.hpp132
-rw-r--r--Comm/StdKit/Ref.hpp91
-rw-r--r--Comm/StdKit/String.hpp90
-rw-r--r--Comm/StdKit/XCOFF.hxx41
8 files changed, 969 insertions, 0 deletions
diff --git a/Comm/StdKit/AE.hpp b/Comm/StdKit/AE.hpp
new file mode 100644
index 0000000..505ed77
--- /dev/null
+++ b/Comm/StdKit/AE.hpp
@@ -0,0 +1,143 @@
+/*
+ * ========================================================
+ *
+ * MPCC
+ * Copyright SoftwareLabs, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <Comm/Defines.hpp>
+
+#define kAEMag0 'A'
+#define kAEMag1 'E'
+
+#define kAESymbolLen 64
+#define kAEPad 8
+#define kAEMagLen 2
+#define kAEInvalidOpcode 0x00
+
+// Advanced Executable File Format for MetroLink.
+// 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
+ {
+ CharType fMagic[kAEMagLen];
+ CharType fArch;
+ CharType fSubArch;
+ SizeType fCount;
+ CharType fSize;
+ SizeType fStartCode;
+ SizeType fCodeSize;
+ CharType 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
+ {
+ CharType fName[kAESymbolLen];
+ SizeType fKind;
+ SizeType fSize;
+ SizeType fFlags;
+ UIntPtr fOffset;
+ CharType fPad[kAEPad];
+ } PACKED AERecordHeader, *AERecordHeaderPtr;
+
+ enum
+ {
+ kKindRelocationByOffset = 0x23f,
+ kKindRelocationAtRuntime = 0x34f,
+ };
+} // namespace CompilerKit
+
+// provide operator<< for AE
+
+std::ofstream& operator<<(std::ofstream& fp, CompilerKit::AEHeader& container)
+{
+ fp.write((char*)&container, sizeof(CompilerKit::AEHeader));
+
+ return fp;
+}
+
+std::ofstream& operator<<(std::ofstream& fp,
+ CompilerKit::AERecordHeader& container)
+{
+ fp.write((char*)&container, sizeof(CompilerKit::AERecordHeader));
+
+ return fp;
+}
+
+std::ifstream& operator>>(std::ifstream& fp, CompilerKit::AEHeader& container)
+{
+ fp.read((char*)&container, sizeof(CompilerKit::AEHeader));
+ return fp;
+}
+
+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 FP;
+
+ public:
+ explicit AEReadableProtocol() = default;
+ ~AEReadableProtocol() = default;
+
+ MPCC_COPY_DELETE(AEReadableProtocol);
+
+ /**
+ * @brief Read AE record
+ *
+ * @param raw the containing buffer
+ * @param sz it's size (without sizeof(AERecordHeader) added to it.)
+ * @return AERecordHeaderPtr
+ */
+ AERecordHeaderPtr Read(char* raw, std::size_t sz)
+ {
+ if (!raw)
+ return nullptr;
+
+ return this->_Read<AERecordHeader>(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 <typename TypeClass>
+ TypeClass* _Read(char* raw, std::size_t sz)
+ {
+ FP.read(raw, std::streamsize(sz));
+ return reinterpret_cast<TypeClass*>(raw);
+ }
+ };
+} // namespace CompilerKit::Utils
diff --git a/Comm/StdKit/ELF.hpp b/Comm/StdKit/ELF.hpp
new file mode 100644
index 0000000..4f0d0ae
--- /dev/null
+++ b/Comm/StdKit/ELF.hpp
@@ -0,0 +1,389 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct file;
+
+#ifndef elf_read_implies_exec
+/* Executables for which elf_read_implies_exec() returns TRUE will
+ have the READ_IMPLIES_EXEC personality flag set automatically.
+ Override in asm/elf.h as needed. */
+#define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
+#endif
+
+/* 32-bit ELF base types. */
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+/* 64-bit ELF base types. */
+typedef uintptr_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef int16_t Elf64_SHalf;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Sword;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+/* These constants are for the segment types stored in the image headers */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* OS-specific */
+#define PT_HIOS 0x6fffffff /* OS-specific */
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+#define PT_GNU_EH_FRAME 0x6474e550
+
+#define PT_GNU_STACK (PT_LOOS + 0x474e551)
+
+/* These constants define the different elf file types */
+#define ET_NONE 0
+#define ET_REL 1
+#define ET_EXEC 2
+#define ET_DYN 3
+#define ET_CORE 4
+#define ET_LOPROC 0xff00
+#define ET_HIPROC 0xffff
+
+/* This is the info that is needed to parse the dynamic section of the file */
+#define DT_NULL 0
+#define DT_NEEDED 1
+#define DT_PLTRELSZ 2
+#define DT_PLTGOT 3
+#define DT_HASH 4
+#define DT_STRTAB 5
+#define DT_SYMTAB 6
+#define DT_RELA 7
+#define DT_RELASZ 8
+#define DT_RELAENT 9
+#define DT_STRSZ 10
+#define DT_SYMENT 11
+#define DT_INIT 12
+#define DT_FINI 13
+#define DT_SONAME 14
+#define DT_RPATH 15
+#define DT_SYMBOLIC 16
+#define DT_REL 17
+#define DT_RELSZ 18
+#define DT_RELENT 19
+#define DT_PLTREL 20
+#define DT_DEBUG 21
+#define DT_TEXTREL 22
+#define DT_JMPREL 23
+#define DT_ENCODING 32
+#define OLD_DT_LOOS 0x60000000
+#define DT_LOOS 0x6000000d
+#define DT_HIOS 0x6ffff000
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_VERSYM 0x6ffffff0
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+#define DT_FLAGS_1 0x6ffffffb
+#define DT_VERDEF 0x6ffffffc
+#define DT_VERDEFNUM 0x6ffffffd
+#define DT_VERNEED 0x6ffffffe
+#define DT_VERNEEDNUM 0x6fffffff
+#define OLD_DT_HIOS 0x6fffffff
+#define DT_LOPROC 0x70000000
+#define DT_HIPROC 0x7fffffff
+
+/* This info is needed when parsing the symbol table */
+#define STB_LOCAL 0
+#define STB_GLOBAL 1
+#define STB_WEAK 2
+
+#define STT_NOTYPE 0
+#define STT_OBJECT 1
+#define STT_FUNC 2
+#define STT_SECTION 3
+#define STT_FILE 4
+#define STT_COMMON 5
+#define STT_TLS 6
+
+#define ELF_ST_BIND(x) ((x) >> 4)
+#define ELF_ST_TYPE(x) (((unsigned int)x) & 0xf)
+#define ELF32_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF32_ST_TYPE(x) ELF_ST_TYPE(x)
+#define ELF64_ST_BIND(x) ELF_ST_BIND(x)
+#define ELF64_ST_TYPE(x) ELF_ST_TYPE(x)
+
+typedef struct dynamic
+{
+ Elf32_Sword d_tag;
+ union {
+ Elf32_Sword d_val;
+ Elf32_Addr d_ptr;
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+ Elf64_Sxword d_tag; /* entry tag value */
+ union {
+ Elf64_Xword d_val;
+ Elf64_Addr d_ptr;
+ } d_un;
+} Elf64_Dyn;
+
+/* The following are used with relocations */
+#define ELF32_R_SYM(x) ((x) >> 8)
+#define ELF32_R_TYPE(x) ((x)&0xff)
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i)&0xffffffff)
+
+typedef struct elf32_rel
+{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+} Elf32_Rel;
+
+typedef struct elf64_rel
+{
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+} Elf64_Rel;
+
+typedef struct elf32_rela
+{
+ Elf32_Addr r_offset;
+ Elf32_Word r_info;
+ Elf32_Sword r_addend;
+} Elf32_Rela;
+
+typedef struct elf64_rela
+{
+ Elf64_Addr r_offset; /* Location at which to apply the action */
+ Elf64_Xword r_info; /* index and type of relocation */
+ Elf64_Sxword r_addend; /* Constant addend used to compute value */
+} Elf64_Rela;
+
+typedef struct elf32_sym
+{
+ Elf32_Word st_name;
+ Elf32_Addr st_value;
+ Elf32_Word st_size;
+ unsigned char st_info;
+ unsigned char st_other;
+ Elf32_Half st_shndx;
+} Elf32_Sym;
+
+typedef struct elf64_sym
+{
+ Elf64_Word st_name; /* Symbol name, index in string tbl */
+ unsigned char st_info; /* Type and binding attributes */
+ unsigned char st_other; /* No defined meaning, 0 */
+ Elf64_Half st_shndx; /* Associated section index */
+ Elf64_Addr st_value; /* Value of the symbol */
+ Elf64_Xword st_size; /* Associated symbol size */
+} Elf64_Sym;
+
+#define EI_NIDENT 16
+
+typedef struct elf32_hdr
+{
+ unsigned char e_ident[EI_NIDENT];
+ Elf32_Half e_type;
+ Elf32_Half e_machine;
+ Elf32_Word e_version;
+ Elf32_Addr e_entry; /* Entry point */
+ Elf32_Off e_phoff;
+ Elf32_Off e_shoff;
+ Elf32_Word e_flags;
+ Elf32_Half e_ehsize;
+ Elf32_Half e_phentsize;
+ Elf32_Half e_phnum;
+ Elf32_Half e_shentsize;
+ Elf32_Half e_shnum;
+ Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+typedef struct elf64_hdr
+{
+ unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
+ Elf64_Half e_type;
+ Elf64_Half e_machine;
+ Elf64_Word e_version;
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags;
+ Elf64_Half e_ehsize;
+ Elf64_Half e_phentsize;
+ Elf64_Half e_phnum;
+ Elf64_Half e_shentsize;
+ Elf64_Half e_shnum;
+ Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* These constants define the permissions on sections in the program
+ header, p_flags. */
+#define PF_R 0x4
+#define PF_W 0x2
+#define PF_X 0x1
+
+typedef struct elf32_phdr
+{
+ Elf32_Word p_type;
+ Elf32_Off p_offset;
+ Elf32_Addr p_vaddr;
+ Elf32_Addr p_paddr;
+ Elf32_Word p_filesz;
+ Elf32_Word p_memsz;
+ Elf32_Word p_flags;
+ Elf32_Word p_align;
+} Elf32_Phdr;
+
+typedef struct elf64_phdr
+{
+ Elf64_Word p_type;
+ Elf64_Word p_flags;
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment, file & memory */
+} Elf64_Phdr;
+
+/* sh_type */
+#define SHT_NULL 0
+#define SHT_PROGBITS 1
+#define SHT_SYMTAB 2
+#define SHT_STRTAB 3
+#define SHT_RELA 4
+#define SHT_HASH 5
+#define SHT_DYNAMIC 6
+#define SHT_NOTE 7
+#define SHT_NOBITS 8
+#define SHT_REL 9
+#define SHT_SHLIB 10
+#define SHT_DYNSYM 11
+#define SHT_NUM 12
+#define SHT_LOPROC 0x70000000
+#define SHT_HIPROC 0x7fffffff
+#define SHT_LOUSER 0x80000000
+#define SHT_HIUSER 0xffffffff
+
+/* sh_flags */
+#define SHF_WRITE 0x1
+#define SHF_ALLOC 0x2
+#define SHF_EXECINSTR 0x4
+#define SHF_MASKPROC 0xf0000000
+
+/* special section indexes */
+#define SHN_UNDEF 0
+#define SHN_LORESERVE 0xff00
+#define SHN_LOPROC 0xff00
+#define SHN_HIPROC 0xff1f
+#define SHN_ABS 0xfff1
+#define SHN_COMMON 0xfff2
+#define SHN_HIRESERVE 0xffff
+
+typedef struct
+{
+ Elf32_Word sh_name;
+ Elf32_Word sh_type;
+ Elf32_Word sh_flags;
+ Elf32_Addr sh_addr;
+ Elf32_Off sh_offset;
+ Elf32_Word sh_size;
+ Elf32_Word sh_link;
+ Elf32_Word sh_info;
+ Elf32_Word sh_addralign;
+ Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+typedef struct elf64_shdr
+{
+ Elf64_Word sh_name; /* Section name, index in string tbl */
+ Elf64_Word sh_type; /* Type of section */
+ Elf64_Xword sh_flags; /* Miscellaneous section attributes */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Size of section in bytes */
+ Elf64_Word sh_link; /* Index of another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+#define EI_MAG0 0 /* e_ident[] indexes */
+#define EI_MAG1 1
+#define EI_MAG2 2
+#define EI_MAG3 3
+#define EI_CLASS 4
+#define EI_DATA 5
+#define EI_VERSION 6
+#define EI_OSABI 7
+#define EI_PAD 8
+
+#define ELFMAG0 0x7f /* EI_MAG */
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define ELFCLASSNONE 0 /* EI_CLASS */
+#define ELFCLASS32 1
+#define ELFCLASS64 2
+#define ELFCLASSNUM 3
+
+#define ELFDATANONE 0 /* e_ident[EI_DATA] */
+#define ELFDATA2LSB 1
+#define ELFDATA2MSB 2
+
+#define EV_NONE 0 /* e_version, EI_VERSION */
+#define EV_CURRENT 1
+#define EV_NUM 2
+
+#define ELFOSABI_NONE 0
+#define ELFOSABI_LINUX 3
+
+#ifndef ELF_OSABI
+#define ELF_OSABI ELFOSABI_NONE
+#endif
+
+/* Notes used in ET_CORE */
+#define NT_PRSTATUS 1
+#define NT_PRFPREG 2
+#define NT_PRPSINFO 3
+#define NT_TASKSTRUCT 4
+#define NT_AUXV 6
+#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
+#define NT_PPC_VMX 0x100 /* POWER Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* POWER SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* POWER VSX registers */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_PRXSTATUS 0x300 /* s390 upper register halves */
+
+/* Note header in a PT_NOTE section */
+typedef struct elf32_note
+{
+ Elf32_Word n_namesz; /* Name size */
+ Elf32_Word n_descsz; /* Content size */
+ Elf32_Word n_type; /* Content type */
+} Elf32_Nhdr;
+
+/* Note header in a PT_NOTE section */
+typedef struct elf64_note
+{
+ Elf64_Word n_namesz; /* Name size */
+ Elf64_Word n_descsz; /* Content size */
+ Elf64_Word n_type; /* Content type */
+} Elf64_Nhdr;
diff --git a/Comm/StdKit/ErrorID.hpp b/Comm/StdKit/ErrorID.hpp
new file mode 100644
index 0000000..bea70ae
--- /dev/null
+++ b/Comm/StdKit/ErrorID.hpp
@@ -0,0 +1,22 @@
+/*
+ * ========================================================
+ *
+ * CompilerKit
+ * Copyright SoftwareLabs, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <Comm/Defines.hpp>
+#include <Comm/StdKit/ErrorOr.hpp>
+
+#define MPCC_EXEC_ERROR -30
+#define MPCC_FILE_NOT_FOUND -31
+#define MPCC_DIR_NOT_FOUND -32
+#define MPCC_FILE_EXISTS -33
+#define MPCC_TOO_LONG -34
+#define MPCC_INVALID_DATA -35
+#define MPCC_UNIMPLEMENTED -36
+#define MPCC_FAT_ERROR -37
diff --git a/Comm/StdKit/ErrorOr.hpp b/Comm/StdKit/ErrorOr.hpp
new file mode 100644
index 0000000..0125f82
--- /dev/null
+++ b/Comm/StdKit/ErrorOr.hpp
@@ -0,0 +1,61 @@
+/*
+ * ========================================================
+ *
+ * CompilerKit
+ * Copyright SoftwareLabs, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <Comm/Defines.hpp>
+#include <Comm/StdKit/Ref.hpp>
+
+namespace CompilerKit
+{
+ using ErrorT = UInt32;
+
+ template <typename T>
+ class ErrorOr final
+ {
+ public:
+ ErrorOr() = default;
+ ~ErrorOr() = default;
+
+ public:
+ explicit ErrorOr(Int32 err)
+ : mId(err)
+ {
+ }
+
+ explicit ErrorOr(nullPtr Null)
+ {
+ }
+
+ explicit ErrorOr(T Class)
+ : mRef(Class)
+ {
+ }
+
+ ErrorOr& operator=(const ErrorOr&) = default;
+ ErrorOr(const ErrorOr&) = default;
+
+ Ref<T> Leak()
+ {
+ return mRef;
+ }
+
+ operator bool()
+ {
+ return mRef;
+ }
+
+ private:
+ Ref<T> mRef;
+ Int32 mId{0};
+ };
+
+ using ErrorOrAny = ErrorOr<voidPtr>;
+
+} // namespace CompilerKit
diff --git a/Comm/StdKit/PEF.hpp b/Comm/StdKit/PEF.hpp
new file mode 100644
index 0000000..e790d6a
--- /dev/null
+++ b/Comm/StdKit/PEF.hpp
@@ -0,0 +1,132 @@
+/* -------------------------------------------
+
+ Copyright SoftwareLabs
+
+------------------------------------------- */
+
+#pragma once
+
+#include <Comm/Defines.hpp>
+
+// @file PEF.hpp
+// @brief Preferred Executable Format
+
+#define kPefMagic "Joy!"
+#define kPefMagicFat "yoJ!"
+
+#define kPefExt ".exec"
+#define kPefDylibExt ".lib"
+#define kPefLibExt ".slib"
+#define kPefObjectExt ".obj"
+#define kPefDebugExt ".dbg"
+
+#define kPefMagicLen 5
+
+#define kPefVersion 2
+#define kPefNameLen 255
+
+#define kPefBaseOrigin (0x1000000)
+
+#define kPefStart "__ImageStart"
+
+namespace CompilerKit
+{
+ enum
+ {
+ kPefArchIntel86S = 100,
+ kPefArchAMD64,
+ kPefArchRISCV,
+ kPefArch64000, /* 64x0 RISC architecture. */
+ kPefArch32000,
+ kPefArchPowerPC, /* 64-bit POWER architecture. */
+ kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1,
+ kPefArchInvalid = 0xFF,
+ };
+
+ enum
+ {
+ kPefSubArchAMD,
+ kPefSubArchIntel,
+ kPefSubArchGeneric,
+ kPefSubArchIBM,
+ };
+
+ enum
+ {
+ kPefKindExec = 1, /* .exe */
+ kPefKindSharedObject = 2, /* .lib */
+ kPefKindObject = 4, /* .obj */
+ kPefKindDebug = 5, /* .dbg */
+ kPefKindDriver = 6,
+ kPefKindCount,
+ };
+
+ /* PEF container */
+ typedef struct PEFContainer final
+ {
+ CharType Magic[kPefMagicLen];
+ UInt32 Linker;
+ 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 */
+ } PACKED PEFContainer;
+
+ /* First PEFCommandHeader starts after PEFContainer */
+ /* Last container is __exec_end */
+
+ /* PEF executable section and commands. */
+
+ typedef struct PEFCommandHeader final
+ {
+ CharType 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 Size; /* file size */
+ } PACKED PEFCommandHeader;
+
+ enum
+ {
+ kPefCode = 0xC,
+ kPefData = 0xD,
+ kPefZero = 0xE,
+ kPefLinkerID = 0x1,
+ kPefCount = 4,
+ kPefInvalid = 0xFF,
+ };
+} // 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;
+}
+
+std::ifstream& operator>>(std::ifstream& fp,
+ CompilerKit::PEFContainer& container)
+{
+ fp.read((char*)&container, sizeof(CompilerKit::PEFContainer));
+ return fp;
+}
+
+std::ifstream& operator>>(std::ifstream& fp,
+ CompilerKit::PEFCommandHeader& container)
+{
+ fp.read((char*)&container, sizeof(CompilerKit::PEFCommandHeader));
+ return fp;
+}
diff --git a/Comm/StdKit/Ref.hpp b/Comm/StdKit/Ref.hpp
new file mode 100644
index 0000000..f4a11c0
--- /dev/null
+++ b/Comm/StdKit/Ref.hpp
@@ -0,0 +1,91 @@
+
+/*
+ * ========================================================
+ *
+ * CompilerKit
+ * Copyright SoftwareLabs, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+namespace CompilerKit
+{
+ // @author SoftwareLabs
+ // @brief Reference class, refers to a pointer of data in static memory.
+ template <typename T>
+ class Ref final
+ {
+ public:
+ explicit Ref() = default;
+ ~Ref() = default;
+
+ 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;
+ }
+
+ operator bool()
+ {
+ return m_Class;
+ }
+
+ private:
+ T m_Class;
+ bool m_Strong{false};
+ };
+
+ template <typename T>
+ class NonNullRef final
+ {
+ public:
+ NonNullRef() = delete;
+ NonNullRef(nullPtr) = delete;
+
+ explicit NonNullRef(T* ref)
+ : m_Ref(ref, true)
+ {
+ }
+
+ Ref<T>& operator->()
+ {
+ MUST_PASS(m_Ref);
+ return m_Ref;
+ }
+
+ NonNullRef& operator=(const NonNullRef<T>& ref) = delete;
+ NonNullRef(const NonNullRef<T>& ref) = default;
+
+ private:
+ Ref<T> m_Ref{nullptr};
+ };
+} // namespace CompilerKit
diff --git a/Comm/StdKit/String.hpp b/Comm/StdKit/String.hpp
new file mode 100644
index 0000000..c6589cc
--- /dev/null
+++ b/Comm/StdKit/String.hpp
@@ -0,0 +1,90 @@
+/*
+ * ========================================================
+ *
+ * CompilerKit
+ * Copyright SoftwareLabs, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <Comm/Defines.hpp>
+#include <Comm/StdKit/ErrorOr.hpp>
+
+namespace CompilerKit
+{
+ /**
+ * @brief StringView class, contains a C string and manages it.
+ * @note No need to manage it it's getting deleted by default.
+ */
+
+ class StringView final
+ {
+ public:
+ explicit StringView() = delete;
+
+ explicit StringView(SizeType Sz) noexcept
+ : m_Sz(Sz)
+ {
+ m_Data = new char[Sz];
+ assert(m_Data);
+ }
+
+ ~StringView() noexcept
+ {
+ if (m_Data)
+ {
+ memset(m_Data, 0, m_Sz);
+ delete[] m_Data;
+
+ m_Data = nullptr;
+ }
+ }
+
+ MPCC_COPY_DEFAULT(StringView);
+
+ CharType* Data();
+ const CharType* CData() const;
+ SizeType Length() const;
+
+ bool operator==(const CharType* rhs) const;
+ bool operator!=(const CharType* rhs) const;
+
+ bool operator==(const StringView& rhs) const;
+ bool operator!=(const StringView& rhs) const;
+
+ StringView& operator+=(const CharType* rhs);
+ StringView& operator+=(const StringView& rhs);
+
+ operator bool()
+ {
+ return m_Data && m_Data[0] != 0;
+ }
+
+ bool operator!()
+ {
+ return !m_Data || m_Data[0] == 0;
+ }
+
+ private:
+ char* m_Data{nullptr};
+ SizeType m_Sz{0};
+ SizeType m_Cur{0};
+
+ friend class StringBuilder;
+ };
+
+ /**
+ * @brief StringBuilder class
+ * @note These results shall call delete[] after they're used.
+ */
+ struct StringBuilder final
+ {
+ static StringView Construct(const CharType* data);
+ static const char* FromInt(const char* fmt, int n);
+ static const char* FromBool(const char* fmt, bool n);
+ static const char* Format(const char* fmt, const char* from);
+ static bool Equals(const char* lhs, const char* rhs);
+ };
+} // namespace CompilerKit
diff --git a/Comm/StdKit/XCOFF.hxx b/Comm/StdKit/XCOFF.hxx
new file mode 100644
index 0000000..fee1888
--- /dev/null
+++ b/Comm/StdKit/XCOFF.hxx
@@ -0,0 +1,41 @@
+/* -------------------------------------------
+
+ Copyright SoftwareLabs
+
+ File: XCOFF.hpp
+ Purpose: XCOFF for NewOS.
+
+ Revision History:
+
+ 04/07/24: Added file (amlel)
+
+------------------------------------------- */
+
+#ifndef __XCOFF__
+#define __XCOFF__
+
+#include <Comm/Defines.hpp>
+
+#define kXCOFF64Magic 0x01F7
+
+#define kXCOFFRelFlg 0x0001
+#define kXCOFFExecutable 0x0002
+#define kXCOFFLnno 0x0004
+#define kXCOFFLSyms 0x0008
+
+namespace CompilerKit
+{
+ /// @brief XCoff identification 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;
+} // namespace CompilerKit
+
+#endif // ifndef __XCOFF__ \ No newline at end of file