summaryrefslogtreecommitdiffhomepage
path: root/include/CompilerKit/AE.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/CompilerKit/AE.h')
-rw-r--r--include/CompilerKit/AE.h138
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