nx_addr2line.nx
buildroot/runtime/nx_addr2line.nx
about
nx_addr2line.nx -- sovereign addr2line.
Given an ELF + a code address, walk the DWARF .debug_line program
and return the source (file_idx, line) at that address. Foundation
for the future nx_dbg.nx debugger ("show me the source line at PC")
+ sovereign nx_panic backtraces with file:line locations.
What we do (DWARF v5 ยง6.2 line-program VM):
1. Locate .debug_line section via nx_elf_read.
2. Decode the line-program header (file table + dir table).
3. Run the line-program VM until address >= target_addr or end.
4. Return the (file_idx, line) of the most recent committed row
whose address <= target.
Pairs with nx_dwarf_line.nx which BUILDS the section; together,
produce + consume the same byte format with our own code only.
v0.0.1 scope:
* Decode the standard opcodes our nx_dwarf_line emits:
DW_LNS_copy, DW_LNS_advance_pc, DW_LNS_advance_line,
DW_LNS_set_file
* Decode extended ops:
DW_LNE_end_sequence, DW_LNE_set_address
Special opcodes (the compact bias-encoded form) NOT yet decoded;
our emitter doesn't use them today. Add when the emitter does.
dependencies 4 imports · 1 importers
imports: syscalls.nxnx_elf_read.nxnx_dwarf_line.nxnx_addr2line_lib.nx
imported by: nx_dbg.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 225 | const A2L_CAP: i64 = 4194304 |
functions
| 53 | func a2l_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 54 | func a2l_num(v: i64) -> i64 |
| 67 | func a2l_streq(a: *u8, b: *u8) -> i64 |
| 78 | func a2l_parse_hex(s: *u8) -> i64 called by 1: main |
| 97 | func a2l_read_file(path: *u8, buf: *u8, cap: i64) -> i64 called by 1: main |
| 114 | func a2l_find_section(buf: *u8, len: i64, want: *u8, outbox: *i64) -> i64 |
| 133 | func a2l_find_debug_line(buf: *u8, len: i64, outbox: *i64) -> i64 |
| 152 | func a2l_selftest() -> i64 |
| 229 | func main(argc: i64, argv: *i64) -> i64 |