summaryrefslogtreecommitdiff
path: root/elf_image.h
diff options
context:
space:
mode:
Diffstat (limited to 'elf_image.h')
-rw-r--r--elf_image.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/elf_image.h b/elf_image.h
new file mode 100644
index 0000000..b7c7123
--- /dev/null
+++ b/elf_image.h
@@ -0,0 +1,55 @@
+#pragma once
+
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#include "elf_format.h"
+#include "data_buffer.h"
+
+#include <cstdlib>
+
+namespace ELF {
+
+struct ProgramHeader32Table {
+ const ProgramHeader32 *headers{};
+ size_t size{};
+ static ProgramHeader32Table FromBytes(const DataView &, DataEncoding);
+};
+
+struct Segment {
+ Segment *next{};
+ const DataView view{};
+};
+
+class Image {
+ const DataBuffer _data;
+ char *const _error;
+ const Header32 _h;
+ const ProgramHeader32Table _pht;
+public:
+ explicit Image(DataBuffer&&);
+ ~Image();
+ constexpr bool IsValid() const { return _error == nullptr; }
+ constexpr const DataBuffer &Data() const { return _data; };
+ constexpr const DataView ProgramView() const
+ {
+ if (!IsValid()) {
+ return DataView{};
+ }
+ for (size_t i = 0; i < _pht.size; i++) {
+ const auto ph = _pht.headers[i];
+ const bool is_code = (ph.flags & (kPHFlagX | kPHFlagW | kPHFlagR)) ==
+ (kPHFlagX | kPHFlagR);
+ const bool is_load = ParsePHType(ph.type) == PHType::kLoad;
+ const bool contains_entry = _h.entry >= ph.vaddr && _h.entry < ph.vaddr + ph.memsz;
+ if (is_load && is_code && ph.vaddr == 0 && contains_entry)
+ {
+ return _data.View(ph.offset, ph.filesz);
+ }
+ }
+ return DataView{};
+ };
+ constexpr const char *Error() const { return _error; }
+};
+
+}