Files
2026-11-03 15:22:24 -03:00

67 lines
2.6 KiB
C++

#pragma once
#include <cstddef>
#include <string>
#include <vector>
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<ExportedSymbol> readExportedSymbols(const std::string& imagePath, void* loadedBase);
}