debug_internal.h (6400B)
1 #ifndef KIT_DEBUG_INTERNAL_H 2 #define KIT_DEBUG_INTERNAL_H 3 4 /* Internal types shared between debug.c, debug_form.c, debug_abbrev.c, 5 * debug_emit.c, and c_debug.c. Not exposed to consumers. */ 6 7 #include "core/buf.h" 8 #include "core/core.h" 9 #include "core/heap.h" 10 #include "debug/debug.h" 11 #include "debug/dwarf_defs.h" 12 #include "obj/obj.h" 13 14 /* ---------------------------------------------------------------- */ 15 /* Type DIE pool */ 16 17 typedef enum DebugTypeKind { 18 DTK_VOID, 19 DTK_BASE, 20 DTK_PTR, 21 DTK_ARRAY, 22 DTK_CONST, 23 DTK_VOLATILE, 24 DTK_RESTRICT, 25 DTK_TYPEDEF, 26 DTK_FUNC, 27 DTK_RECORD, /* struct or union */ 28 DTK_ENUM, 29 } DebugTypeKind; 30 31 typedef struct DebugRecField { 32 Sym name; 33 DebugTypeId type; 34 u32 byte_offset; 35 u16 bit_offset; 36 u16 bit_width; /* 0 for non-bitfield */ 37 } DebugRecField; 38 39 typedef struct DebugEnumVal { 40 Sym name; 41 i64 value; 42 } DebugEnumVal; 43 44 typedef struct DebugType { 45 u8 kind; /* DebugTypeKind */ 46 u8 is_union; /* DTK_RECORD only */ 47 u8 variadic; /* DTK_FUNC only */ 48 u8 base_encoding; /* DebugBaseEncoding (only for DTK_BASE) */ 49 u8 pad[4]; 50 Sym name; /* base / typedef / record / enum tag */ 51 u32 byte_size; /* base / record */ 52 u32 align; /* record */ 53 DebugTypeId inner; /* ptr/array/qualified/typedef/enum-base */ 54 u32 array_count; /* array; 0 = unknown bound */ 55 /* func */ 56 DebugTypeId* params; 57 u32 nparams; 58 /* record */ 59 DebugRecField* fields; 60 u32 nfields; 61 /* enum */ 62 DebugEnumVal* enum_vals; 63 u32 nenums; 64 /* placement after layout */ 65 u32 die_offset; /* offset within .debug_info CU body, set during emit */ 66 } DebugType; 67 68 /* Builder handles. The builder structures are private to debug.c; only 69 * pointers escape through the public API. */ 70 struct DebugTypeBuilder { 71 Debug* d; 72 DebugTypeId id; 73 u8 is_union; 74 Sym tag; 75 u32 byte_size; 76 u32 align; 77 DebugRecField* fields; 78 u32 nfields; 79 u32 fields_cap; 80 }; 81 82 struct DebugEnumBuilder { 83 Debug* d; 84 Sym tag; 85 DebugTypeId base; 86 DebugEnumVal* vals; 87 u32 nvals; 88 u32 vals_cap; 89 }; 90 91 /* ---------------------------------------------------------------- */ 92 /* Function & scope tracking */ 93 94 typedef struct DebugVarDIE { 95 u8 is_param; /* 1 = formal_parameter; 0 = variable */ 96 u8 external; /* top-level variable only */ 97 u8 pad[2]; 98 u32 param_idx; /* for params */ 99 Sym name; 100 DebugTypeId type; 101 SrcLoc decl; 102 DebugVarLoc loc; 103 /* Scope index (into func->scopes) or -1 if directly inside the subprogram */ 104 i32 scope_idx; 105 u32 die_offset; /* set during emit */ 106 } DebugVarDIE; 107 108 typedef struct DebugScope { 109 i32 parent_idx; /* index into func->scopes, -1 means func body */ 110 SrcLoc begin; 111 SrcLoc end; 112 u32 die_offset; 113 } DebugScope; 114 115 typedef struct DebugFunc { 116 ObjSymId sym; 117 DebugTypeId fn_type; 118 SrcLoc decl; 119 /* PC range — set by debug_func_pc_range. */ 120 ObjSecId text_section; 121 u32 begin_ofs; 122 u32 end_ofs; 123 int has_pc_range; 124 125 /* Variables and scopes — flattened. */ 126 DebugVarDIE* vars; 127 u32 nvars; 128 u32 vars_cap; 129 130 DebugScope* scopes; 131 u32 nscopes; 132 u32 scopes_cap; 133 134 /* Open scope stack while parsing — indexes into scopes. */ 135 i32* scope_stack; 136 u32 scope_stack_n; 137 u32 scope_stack_cap; 138 139 /* Line rows belonging to this function (chronological). */ 140 struct LineRow* rows; 141 u32 nrows; 142 u32 rows_cap; 143 144 u32 die_offset; /* set during emit */ 145 } DebugFunc; 146 147 /* Line program rows — function-local. */ 148 typedef struct LineRow { 149 ObjSecId section_id; 150 u32 offset; 151 SrcLoc loc; 152 u8 is_stmt; 153 u8 pad[3]; 154 } LineRow; 155 156 /* File table entry — DWARF index → SourceManager file_id. */ 157 typedef struct DebugFile { 158 u32 src_file_id; 159 Sym dir; /* interned remapped directory */ 160 Sym base; /* interned remapped basename */ 161 } DebugFile; 162 163 /* Shared Sym/u32 hashmaps. SymToU32 backs the .debug_str / .debug_line_str 164 * string tables (Sym → byte offset; see StrTab in debug_emit.c). */ 165 166 #include "core/hashmap.h" 167 HASHMAP_DEFINE(SymToU32, Sym, u32, hash_u32); 168 HASHMAP_DEFINE(U32ToU32, u32, u32, hash_u32); 169 HASHMAP_DEFINE(PtrToU32, u64, u32, hash_u64); 170 171 /* Abbrev pool — see debug_abbrev.c for encoding. */ 172 typedef struct DebugAbbrevAttr { 173 u16 attr; 174 u16 form; 175 /* For DW_FORM_implicit_const, would carry a value. We don't use it. */ 176 i64 implicit_const; 177 } DebugAbbrevAttr; 178 179 typedef struct DebugAbbrev { 180 u32 code; /* 1-based ULEB code */ 181 u16 tag; 182 u8 has_children; 183 u8 pad; 184 DebugAbbrevAttr* attrs; 185 u32 nattrs; 186 } DebugAbbrev; 187 188 typedef struct DebugAbbrevPool { 189 DebugAbbrev* items; 190 u32 n; 191 u32 cap; 192 } DebugAbbrevPool; 193 194 /* ---------------------------------------------------------------- */ 195 /* Debug master state. */ 196 197 struct Debug { 198 Compiler* c; 199 ObjBuilder* ob; 200 Heap* heap; 201 202 /* File table */ 203 DebugFile* files; 204 u32 nfiles; 205 u32 files_cap; 206 U32ToU32 src_to_file; /* src file_id → dwarf_idx (0-based; we map to the 207 entry in `files`). +1 stored to avoid 0-key. */ 208 209 /* Type pool */ 210 DebugType* types; 211 u32 ntypes; 212 u32 types_cap; 213 214 /* Function lifecycle */ 215 DebugFunc* funcs; 216 u32 nfuncs; 217 u32 funcs_cap; 218 i32 cur_func; /* -1 if none open */ 219 220 /* Top-level static-storage object DIEs. Function-scope statics are still 221 * stored on the owning DebugFunc as variable DIEs with DVL_GLOBAL locations. 222 */ 223 DebugVarDIE* globals; 224 u32 nglobals; 225 u32 globals_cap; 226 227 /* Line rows pending: latest set_loc */ 228 SrcLoc pending_loc; 229 230 /* Pre-built type ids for void/builtin reuse — c_debug uses these. */ 231 DebugTypeId void_type; 232 }; 233 234 /* ---------------------------------------------------------------- */ 235 /* Form encoders (debug_form.c) */ 236 void form_u8(Buf*, u8); 237 void form_u16(Buf*, u16); 238 void form_u32(Buf*, u32); 239 void form_u64(Buf*, u64); 240 void form_uleb(Buf*, u64); 241 void form_sleb(Buf*, i64); 242 size_t form_uleb_size(u64); 243 size_t form_sleb_size(i64); 244 u32 form_uleb_inline(u8* buf, u64 v); 245 u32 form_sleb_inline(u8* buf, i64 v); 246 247 /* Abbrev pool ops (debug_abbrev.c). Teardown is abbrev_fini_heap (declared 248 * in debug_abbrev.c) — it needs the heap to free the per-abbrev attr arrays. */ 249 void abbrev_init(DebugAbbrevPool*, Heap*); 250 /* Find or insert; attrs are copied. Returns 1-based code. */ 251 u32 abbrev_intern(DebugAbbrevPool*, Heap*, u16 tag, u8 has_children, 252 const DebugAbbrevAttr* attrs, u32 nattrs); 253 /* Encode the entire pool to bytes in `buf`. */ 254 void abbrev_encode(const DebugAbbrevPool*, Buf*); 255 256 #endif