Appearance
aowlspt_inspect.h
Source: abi/aowlspt_inspect.h — 447 lines, 40 file-scope functions.
What this header owns
Reproduced verbatim from the header's own banner comment — these notes are frequently the only written record of why the subsystem is shaped the way it is.
text
aowlspt_inspect.h -- the native half of the LIVE INSPECTOR / REPL.
WHY THIS EXISTS
---------------
Every client-side question on this build costs an edit, a full rebuild, a
deploy, a launch and ninety seconds to the menu -- and answers exactly ONE
log line, the one somebody had to predict in advance. Reflection is dead
here (`il2cpp_object_get_class`, `il2cpp_class_get_name`, `il2cpp_value_box`
and field iteration all fault), so the only way to learn anything about a
live object is to assert an offset and see whether it faults. That is the
whole reason the loop is slow: we cannot LOOK.
This header is the instrument that lets us look. It provides, to
`host/Aowlspt.Host.Il2Cpp/inspect.nim`:
* a lock and a pending flag, so the host's tick thread can hand a batch of
commands to Unity's main thread without a new socket, thread or port;
* a BREADCRUMB -- a short string plus the pointer that was about to be
dereferenced -- written before every hop, so a caught fault names WHERE
it landed instead of only that it happened;
* guarded byte reads and writes;
* code-pointer verification: committed, executable, inside the `il2cpp`
PE section (generated code does NOT live in `.text` on this build), and
NOT already carrying somebody's detour;
* generic direct-RVA call thunks in IL2CPP's convention.
THE CALLING CONVENTION, as the project has it disassembled (see
`abi/aowlspt_invoke2.h` for the evidence):
instance: RCX = this, RDX/R8/R9 = args, then a HIDDEN TRAILING
`const MethodInfo*`;
static: RCX.. = args, then the same hidden trailing MethodInfo*;
floats: XMM0-3 BY POSITION -- so a C prototype that declares the
argument as `double` in that position lands it in the right
register with no assembly at all. That is why the thunks below
are ordinary C functions: the ABI does the work.
A NULL MethodInfo* is fine for everything except SHARED GENERIC code, which
dereferences it (`AddComponent<T>` reads it at +0x38). So every thunk takes
the MethodInfo* as an explicit parameter rather than hardcoding NULL, and
the REPL's `call` grammar has a `mi=` token for the generic case.
WHAT IS DELIBERATELY NOT HERE
-----------------------------
No struct returns. `RectTransform::get_rect` returns a `Rect` by hidden
pointer and `Camera::WorldToScreenPoint` takes a `Vector3` by value; both
need a shape-specific prototype, and a generic thunk that guessed would
corrupt the stack. Those stay in `aowlspt_debugui.h` where they have real
prototypes. The REPL reports "unsupported signature" rather than trying.
Everything here is `static`, like the rest of `abi/`: these headers are
included into the single translation unit nimony emits per module.Constants
AOWLSPT_INSPECT_H
Functions
| Signature | Line |
|---|---|
void aowl_insp_lock(void) | 75 |
void aowl_insp_unlock(void) | 80 |
int32_t aowl_insp_have(void) | 88 |
void aowl_insp_set_pending(int32_t v) | 91 |
void aowl_insp_mark(const char* what, void* p) | 115 |
char aowl_insp_crumb_get(void) | 125 |
void aowl_insp_crumb_ptr_get(void) | 126 |
int32_t aowl_insp_crumb_seq_get(void) | 127 |
int32_t aowl_insp_read_bytes(void* p, int32_t off, int32_t n, unsigned char* out) | 137 |
int32_t aowl_insp_readable_span(void* p, int32_t off, int32_t n) | 150 |
int32_t aowl_insp_write_bytes(void* p, int32_t off, int32_t n, const unsigned char* src) | 164 |
void aowl_insp_bounds(void) | 197 |
void aowl_insp_module_base(void) | 231 |
uint64_t aowl_insp_il2cpp_start(void) | 235 |
uint64_t aowl_insp_il2cpp_end(void) | 238 |
int32_t aowl_insp_last_reason(void) | 257 |
int32_t aowl_insp_is_detoured(const unsigned char* p) | 259 |
void aowl_insp_code(uint64_t rva) | 271 |
int32_t aowl_insp_prologue_ok(void* p, const char* hex) | 301 |
uint64_t aowl_insp_u_v(void* fn, void* mi) | 340 |
uint64_t aowl_insp_u_p(void* fn, void* a0, void* mi) | 344 |
uint64_t aowl_insp_u_pp(void* fn, void* a0, void* a1, void* mi) | 348 |
uint64_t aowl_insp_u_ppp(void* fn, void* a0, void* a1, void* a2, void* mi) | 353 |
uint64_t aowl_insp_u_pppp(void* fn, void* a0, void* a1, void* a2, void* a3, void* mi) | 359 |
uint64_t aowl_insp_u_pi(void* fn, void* a0, int32_t a1, void* mi) | 365 |
uint64_t aowl_insp_u_pl(void* fn, void* a0, int64_t a1, void* mi) | 370 |
uint64_t aowl_insp_u_pf(void* fn, void* a0, float a1, void* mi) | 378 |
uint64_t aowl_insp_u_pff(void* fn, void* a0, float a1, float a2, void* mi) | 383 |
uint64_t aowl_insp_u_i(void* fn, int32_t a0, void* mi) | 389 |
uint64_t aowl_insp_u_f(void* fn, float a0, void* mi) | 393 |
float aowl_insp_f_v(void* fn, void* mi) | 399 |
float aowl_insp_f_p(void* fn, void* a0, void* mi) | 403 |
float aowl_insp_f_pp(void* fn, void* a0, void* a1, void* mi) | 407 |
float aowl_insp_f_pi(void* fn, void* a0, int32_t a1, void* mi) | 411 |
float aowl_insp_f_pf(void* fn, void* a0, float a1, void* mi) | 416 |
float aowl_insp_f_i(void* fn, int32_t a0, void* mi) | 420 |
float aowl_insp_bits_to_f32(uint32_t b) | 433 |
double aowl_insp_bits_to_f64(uint64_t b) | 436 |
uint32_t aowl_insp_f32_to_bits(float v) | 439 |
uint64_t aowl_insp_f64_to_bits(double v) | 442 |

