#pragma once #include #include #include namespace hot_reload::detail { /** * @brief One exported symbol found in a loaded module, already classified. */ struct ExportedSymbol { std::string name; /**< The symbol's real (possibly mangled) name. */ void* address = nullptr; /**< The symbol's runtime address. */ /** * The single load-bearing safety gate behind the "only * executable code changes" guarantee in `hot_reload.h`: false * for anything not mechanically identified as code (a data * object, a forwarder export, or a symbol kind this reader does * not recognize at all). `Context` never patches a * symbol where this is false, on either side of a reload. */ bool isFunction = false; /** * Compiled size in bytes if known, 0 if not. ELF gives this * exactly (the symbol table's `st_size` field); PE gives no such * field, so this holds a conservative estimate derived from the * distance to the next exported function in the same section -- * see the file comment in `SymbolTable.cpp` for exactly what * that heuristic can and cannot catch. */ std::size_t size = 0; }; /** * @brief Reads and classifies every exported, defined symbol in a loaded module. * * On POSIX this parses @p imagePath on disk (its ELF `.dynsym` / * `.dynstr` / section-header table) and adds @p loadedBase as the * runtime load bias. On Windows this ignores @p imagePath and reads * directly from the already-mapped image at @p loadedBase (its PE * export directory and section table) -- see the per-platform * implementation blocks in `SymbolTable.cpp` for why each platform * reads from a different place. * * A file that is truncated or otherwise corrupt in the parts this reader relies on (the * section header table and the tables it points at) is treated like any other unparseable * image: every offset and length read from the file is range-checked against the file's size * before it is used, so a damaged image yields fewer (or no) symbols rather than an * out-of-bounds read. * * @param imagePath Path to the module on disk (POSIX only -- see above). * @param loadedBase The base address `dlopen()`/`LoadLibrary()` returned for it. * @return Every exported symbol, classified via ExportedSymbol::isFunction. * Empty (never throws) if the image could not be parsed as * this platform's native format (including the rare case of * a `.so` with its section header table deliberately * stripped -- see the file comment in `SymbolTable.cpp`). */ std::vector readExportedSymbols(const std::string& imagePath, void* loadedBase); }