Augment
Loading...
Searching...
No Matches
manifest_internal.hpp
1
3
4#pragma once
5#include <cstdint>
6#include <cstring>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11namespace augment::manifest {
12
13struct ArgView { const char* name; const char* kind; const char* view; };
14struct FuncView { const char* mangled; bool member; const char* self_view; uint64_t rva;
15 const char* loc; const char* ret; const ArgView* args; uint32_t nargs; };
16struct FieldView { const char* name; uint32_t offset; const char* kind; int32_t len; const char* view; };
17
18class Reader {
19public:
20 bool load(const char* path);
21 uint32_t version() const { return m_version; }
22
23 uint32_t func_count(const char* flat) const;
24 bool func_at(const char* flat, uint32_t i, FuncView* out) const;
25 bool func_by_mangled(const char* mangled, FuncView* out) const;
26 bool struct_field(const char* name, const char* field, FieldView* out) const;
27 bool enum_value(const char* name, const char* value_name, int64_t* out) const;
28 bool global(const char* name, const char** kind_out, uint64_t* addr_out) const;
29 uint64_t rva_of(const char* mangled) const;
30
31 template <class F> void each_function(F&& cb) const {
32 for (auto& kv : m_index[0]) {
33 std::vector<const uint8_t*> recs; records(0, kv.first.c_str(), recs);
34 for (auto* p : recs) { FuncView f{}; read_func(p, &f); cb(kv.first.c_str(), f); }
35 }
36 }
37 template <class F> void each_field(const char* name, F&& cb) const {
38 std::vector<const uint8_t*> recs; records(1, name, recs);
39 if (recs.empty()) return;
40 const uint8_t* p = recs[0];
41 uint32_t nf = rdu32(p + 4); const uint8_t* q = p + 8;
42 for (uint32_t i = 0; i < nf; ++i) {
43 int32_t ln; std::memcpy(&ln, q + 12, 4);
44 FieldView fv{ str(rdu32(q)), rdu32(q + 4), str(rdu32(q + 8)), ln, str(rdu32(q + 16)) };
45 q += 20; cb(fv);
46 }
47 }
48 template <class F> void each_enum_value(const char* name, F&& cb) const {
49 std::vector<const uint8_t*> recs; records(2, name, recs);
50 if (recs.empty()) return;
51 const uint8_t* p = recs[0];
52 uint32_t nv = rdu32(p + 4); const uint8_t* q = p + 8;
53 for (uint32_t i = 0; i < nv; ++i) {
54 int64_t v; std::memcpy(&v, q + 4, 8);
55 const char* vn = str(rdu32(q)); q += 12; cb(vn, v);
56 }
57 }
58
59private:
60 const char* str(uint32_t off) const { return m_buf.data() + m_stoff + off; }
61 static uint32_t rdu32(const uint8_t* p) { uint32_t v; std::memcpy(&v, p, 4); return v; }
62 void records(int section, const char* name, std::vector<const uint8_t*>& out) const;
63 void read_func(const uint8_t* p, FuncView* out) const;
64
65 std::string m_buf;
66 uint32_t m_version = 0;
67 uint32_t m_stoff = 0;
68 std::vector<std::unordered_map<std::string, uint32_t>> m_index;
69 uint32_t m_pbase = 0;
70 std::unordered_map<std::string, uint64_t> m_rva;
71 std::unordered_map<std::string, std::string> m_flat_of;
72};
73
74Reader& global_reader();
75
76} // namespace augment::manifest
77