nx_dwarf_cfi.nx
buildroot/runtime/nx_dwarf_cfi.nx
about
nx_dwarf_cfi.nx -- DWARF .debug_frame / .eh_frame builder.
Encodes Call Frame Information used by stack unwinders (debuggers,
exception handlers, profilers, perf). Today our riscv.nx emits
.cfi_* DIRECTIVES for the gcc-as path; this module produces the
BINARY section directly so the off-C path doesn't need gcc-as.
CFI section structure (DWARF v5 ยง6.4):
Common Information Entry (CIE) -- shared header for many FDEs:
length u32 bytes after this field
CIE_id u32 = 0xFFFFFFFF for .debug_frame, 0 for .eh_frame
version u8 = 1
augstr NUL-term ASCII augmentation
code_align uleb128 multiplier for advance_loc
data_align sleb128 multiplier for cfa_offset
ra_reg uleb128 return-address register (typically 1=ra)
init_insns ... DW_CFA_* opcodes for default state
Frame Description Entry (FDE) per function:
length u32
CIE_ptr u32 offset back to the CIE (.debug_frame) /
relative offset (.eh_frame)
init_loc u64 function start address (RV64)
range u64 function size
insns ... DW_CFA_* opcodes describing per-PC state
What we ship today (v0.0.1):
* CIE writer (begin/end + opcode emit)
* FDE writer (begin/end + opcode emit)
* DW_CFA_* opcode constants
* advance_loc / def_cfa_offset / offset(reg, off) helpers
Pairs with riscv.nx's .cfi directive emission: same logical
information, different encoding (binary vs assembler-text).
When the off-C path is the only path, riscv.nx will swap to
emitting straight to nx_dwarf_cfi instead of textual directives.
dependencies 1 imports · 0 importers
imports: syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 70 | struct NxDwCfi |
consts
| 49 | const NX_DW_CFA_advance_loc: i64 = 0x40 // | delta (low 6 bits) |
| 50 | const NX_DW_CFA_offset: i64 = 0x80 // | reg (low 6 bits) |
| 51 | const NX_DW_CFA_restore: i64 = 0xC0 // | reg |
| 52 | const NX_DW_CFA_nop: i64 = 0x00 |
| 53 | const NX_DW_CFA_set_loc: i64 = 0x01 |
| 54 | const NX_DW_CFA_advance_loc1: i64 = 0x02 |
| 55 | const NX_DW_CFA_advance_loc2: i64 = 0x03 |
| 56 | const NX_DW_CFA_advance_loc4: i64 = 0x04 |
| 57 | const NX_DW_CFA_offset_extended: i64 = 0x05 |
| 58 | const NX_DW_CFA_restore_extended: i64 = 0x06 |
| 59 | const NX_DW_CFA_undefined: i64 = 0x07 |
| 60 | const NX_DW_CFA_same_value: i64 = 0x08 |
| 61 | const NX_DW_CFA_register: i64 = 0x09 |
| 62 | const NX_DW_CFA_remember_state: i64 = 0x0A |
| 63 | const NX_DW_CFA_restore_state: i64 = 0x0B |
| 64 | const NX_DW_CFA_def_cfa: i64 = 0x0C |
| 65 | const NX_DW_CFA_def_cfa_register: i64 = 0x0D |
| 66 | const NX_DW_CFA_def_cfa_offset: i64 = 0x0E |
| 78 | const NX_DW_CFI_BYTES: i64 = 40 |
functions
| 80 | func nx_dwcfi_new(cap: i64) -> *NxDwCfi called by 1: main |
| 93 | func nx_dwcfi_byte(c: *NxDwCfi, v: i64) -> i64 |
| 100 | func nx_dwcfi_u32(c: *NxDwCfi, v: i64) -> i64 |
| 108 | func nx_dwcfi_u64(c: *NxDwCfi, v: i64) -> i64 |
| 117 | func nx_dwcfi_uleb(c: *NxDwCfi, v: i64) -> i64 called by 4: nx_dwcfi_cie_beginnx_dwcfi_def_cfa_offsetnx_dwcfi_def_cfanx_dwcfi_offset calls 1: nx_dwcfi_byte |
| 130 | func nx_dwcfi_sleb(c: *NxDwCfi, v: i64) -> i64 |
| 150 | func nx_dwcfi_cie_begin(c: *NxDwCfi, code_align: i64, data_align: i64, |
| 169 | func nx_dwcfi_fde_begin(c: *NxDwCfi, cie_offset: i64, |
| 182 | func nx_dwcfi_end(c: *NxDwCfi) -> i64 called by 1: main |
| 197 | func nx_dwcfi_advance_loc(c: *NxDwCfi, delta: i64) -> i64 |
| 216 | func nx_dwcfi_def_cfa_offset(c: *NxDwCfi, off: i64) -> i64 |
| 222 | func nx_dwcfi_def_cfa(c: *NxDwCfi, reg: i64, off: i64) -> i64 |
| 230 | func nx_dwcfi_offset(c: *NxDwCfi, reg: i64, factored_off: i64) -> i64 |
| 240 | func nx_dwcfi_size(c: *NxDwCfi) -> i64 { return c.used } called by 1: main |
| 241 | func nx_dwcfi_bytes(c: *NxDwCfi) -> *u8 { return c.buf } |
| 245 | func main() -> i64 |