diff options
Diffstat (limited to 'include/CompilerKit/AE.h')
| -rw-r--r-- | include/CompilerKit/AE.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/include/CompilerKit/AE.h b/include/CompilerKit/AE.h new file mode 100644 index 0000000..cf6e71b --- /dev/null +++ b/include/CompilerKit/AE.h @@ -0,0 +1,138 @@ +/* + * ======================================================== + * + * CompilerKit + * Copyright (C) 2024-2025 Amlal El Mahrouss, Licensed under the Apache 2.0 license. + * + * ======================================================== + */ + +#ifndef _NECTI_AE_H_ +#define _NECTI_AE_H_ + +#include <CompilerKit/Detail/Config.h> +#include <fstream> + +#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_<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) { + file_pointer_.read(raw, std::streamsize(sz)); + return reinterpret_cast<TypeClass*>(raw); + } +}; +} // namespace CompilerKit::Utils + +#endif /* ifndef _NECTI_AE_H_ */
\ No newline at end of file |
