code wiki / _hdl_build / rv64im_min_symtab.nx
rv64im_min_symtab.nx
buildroot/runtime/_hdl_build/rv64im_min_symtab.nx
about
rv64im_min_symtab.nx -- ELF64 symbol table parser.
Walks an ELF64 byte buffer (the same one the loader consumed) +
extracts the symbol table. Builds an in-memory list of FUNC
symbols with (address, size, name) so the hot-function reporter
(rv64im_min_hot_report.nx) can attribute cycles to source-level
function names.
This + per-PC cycle attribution + the GEMM/AES benchmarks =
silicon-feedback loop M3 closure per ZERO_TO_ADVANCED.md.
Why we parse this ourselves instead of `nm` / `objdump`:
- sovereignty: external binutils tools are third-party deps per
[[feedback-open-source-licensed-is-still-third-party]]
- the ELF format spec is open; the IMPLEMENTATION is what's
licensed -- parsing it ourselves is bytes-up sovereign
Status: SEED. 2026-05-26. Parses .symtab + .strtab; filters to
FUNC symbols; returns array of NxElfFuncSymbol.
dependencies 3 imports · 2 importers
imports: nx_syscalls.nxnishi_hdl_primitives.nxrv64im_min_elf_loader.nx
imported by: rv64im_min_hot_report.nxrv64im_min_multi_tier_roi.nx
structs
| 74 | struct NxElfFuncSymbol |
| 83 | struct NxSymtab |
consts
| 26 | const NX_ELF_SHT_NULL: i64 = 0 |
| 27 | const NX_ELF_SHT_PROGBITS: i64 = 1 |
| 28 | const NX_ELF_SHT_SYMTAB: i64 = 2 |
| 29 | const NX_ELF_SHT_STRTAB: i64 = 3 |
| 32 | const NX_ELF_SH_OFF_NAME: i64 = 0 // u32: offset into .shstrtab |
| 33 | const NX_ELF_SH_OFF_TYPE: i64 = 4 // u32 |
| 34 | const NX_ELF_SH_OFF_FLAGS: i64 = 8 |
| 35 | const NX_ELF_SH_OFF_ADDR: i64 = 16 |
| 36 | const NX_ELF_SH_OFF_OFFSET: i64 = 24 |
| 37 | const NX_ELF_SH_OFF_SIZE: i64 = 32 |
| 38 | const NX_ELF_SH_OFF_LINK: i64 = 40 // u32: for SYMTAB, index of STRTAB |
| 39 | const NX_ELF_SH_OFF_INFO: i64 = 44 |
| 40 | const NX_ELF_SH_OFF_ADDRALIGN: i64 = 48 |
| 41 | const NX_ELF_SH_OFF_ENTSIZE: i64 = 56 |
| 42 | const NX_ELF_SHDR_SIZE: i64 = 64 |
| 45 | const NX_ELF_SYM_OFF_NAME: i64 = 0 // u32: offset into .strtab |
| 46 | const NX_ELF_SYM_OFF_INFO: i64 = 4 // u8: binding | type (low 4 bits) |
| 47 | const NX_ELF_SYM_OFF_OTHER: i64 = 5 |
| 48 | const NX_ELF_SYM_OFF_SHNDX: i64 = 6 // u16 |
| 49 | const NX_ELF_SYM_OFF_VALUE: i64 = 8 // u64: function address |
| 50 | const NX_ELF_SYM_OFF_SIZE: i64 = 16 // u64: function byte count |
| 51 | const NX_ELF_SYM_SIZE: i64 = 24 |
| 54 | const NX_ELF_STT_NOTYPE: i64 = 0 |
| 55 | const NX_ELF_STT_OBJECT: i64 = 1 |
| 56 | const NX_ELF_STT_FUNC: i64 = 2 |
| 57 | const NX_ELF_STT_SECTION: i64 = 3 |
| 58 | const NX_ELF_STT_FILE: i64 = 4 |
| 61 | const NX_SYMTAB_OK: i64 = 0 |
| 62 | const NX_SYMTAB_NO_SYMTAB_SECTION: i64 = 1 |
| 63 | const NX_SYMTAB_NO_STRTAB: i64 = 2 |
| 64 | const NX_SYMTAB_BAD_LINK: i64 = 3 |
| 65 | const NX_SYMTAB_BAD_ENTSIZE: i64 = 4 |
| 66 | const NX_SYMTAB_TRUNCATED: i64 = 5 |
| 67 | const NX_SYMTAB_OVERFLOW: i64 = 6 |
functions
| 97 | func nx_elf_find_section_by_type(buf: *u8, buf_size: i64, target_type: i64) -> i64 |
| 114 | func nx_elf_section_at(buf: *u8, idx: i64) -> i64 |
| 126 | func nx_elf_load_symtab(buf: *u8, buf_size: i64, |
| 196 | func nx_symtab_func_for_pc(symtab: *NxSymtab, pc: i64) -> i64 called by 1: nx_hot_aggregate_by_function |
| 213 | func nx_symtab_name_len(name_ptr: *u8) -> i64 |