debug_internal.h (6613B)
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 sibling_visited; /* internal: layout pass */ 49 u8 base_encoding; /* DebugBaseEncoding (only for DTK_BASE) */ 50 u8 pad[3]; 51 Sym name; /* base / typedef / record / enum tag */ 52 u32 byte_size; /* base / record */ 53 u32 align; /* record */ 54 DebugTypeId inner; /* ptr/array/qualified/typedef/enum-base */ 55 u32 array_count; /* array; 0 = unknown bound */ 56 /* func */ 57 DebugTypeId* params; 58 u32 nparams; 59 /* record */ 60 DebugRecField* fields; 61 u32 nfields; 62 /* enum */ 63 DebugEnumVal* enum_vals; 64 u32 nenums; 65 /* placement after layout */ 66 u32 die_offset; /* offset within .debug_info CU body, set during emit */ 67 } DebugType; 68 69 /* Builder handles. The builder structures are private to debug.c; only 70 * pointers escape through the public API. */ 71 struct DebugTypeBuilder { 72 Debug* d; 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 pad[3]; 97 u32 param_idx; /* for params */ 98 Sym name; 99 DebugTypeId type; 100 SrcLoc decl; 101 DebugVarLoc loc; 102 /* Scope index (into func->scopes) or -1 if directly inside the subprogram */ 103 i32 scope_idx; 104 u32 die_offset; /* set during emit */ 105 } DebugVarDIE; 106 107 typedef struct DebugScope { 108 i32 parent_idx; /* index into func->scopes, -1 means func body */ 109 SrcLoc begin; 110 SrcLoc end; 111 u32 die_offset; 112 } DebugScope; 113 114 typedef struct DebugFunc { 115 ObjSymId sym; 116 DebugTypeId fn_type; 117 SrcLoc decl; 118 /* PC range — set by debug_func_pc_range. */ 119 ObjSecId text_section; 120 u32 begin_ofs; 121 u32 end_ofs; 122 int has_pc_range; 123 124 /* Variables and scopes — flattened. */ 125 DebugVarDIE* vars; 126 u32 nvars; 127 u32 vars_cap; 128 129 DebugScope* scopes; 130 u32 nscopes; 131 u32 scopes_cap; 132 133 /* Open scope stack while parsing — indexes into scopes. */ 134 i32* scope_stack; 135 u32 scope_stack_n; 136 u32 scope_stack_cap; 137 138 /* Line rows belonging to this function (chronological). */ 139 struct LineRow* rows; 140 u32 nrows; 141 u32 rows_cap; 142 143 u32 die_offset; /* set during emit */ 144 } DebugFunc; 145 146 /* Line program rows — function-local. */ 147 typedef struct LineRow { 148 ObjSecId section_id; 149 u32 offset; 150 SrcLoc loc; 151 u8 is_stmt; 152 u8 pad[3]; 153 } LineRow; 154 155 /* File table entry — DWARF index → SourceManager file_id. */ 156 typedef struct DebugFile { 157 u32 src_file_id; 158 Sym dir; /* interned remapped directory */ 159 Sym base; /* interned remapped basename */ 160 } DebugFile; 161 162 /* Shared Sym/u32 hashmaps. SymToU32 backs the .debug_str / .debug_line_str 163 * string tables (Sym → byte offset; see StrTab in debug_emit.c). */ 164 165 #include "core/hashmap.h" 166 HASHMAP_DEFINE(SymToU32, Sym, u32, hash_u32); 167 HASHMAP_DEFINE(U32ToU32, u32, u32, hash_u32); 168 HASHMAP_DEFINE(PtrToU32, u64, u32, hash_u64); 169 170 /* Loclist entry (Phase 5 placeholder; we register the storage but do not 171 * yet emit .debug_loclists). */ 172 typedef struct DebugLocListEntry { 173 u32 begin_pc; 174 u32 end_pc; 175 DebugVarLoc loc; 176 } DebugLocListEntry; 177 178 typedef struct DebugLocList { 179 DebugLocListEntry* entries; 180 u32 nentries; 181 u32 cap; 182 } DebugLocList; 183 184 /* Abbrev pool — see debug_abbrev.c for encoding. */ 185 typedef struct DebugAbbrevAttr { 186 u16 attr; 187 u16 form; 188 /* For DW_FORM_implicit_const, would carry a value. We don't use it. */ 189 i64 implicit_const; 190 } DebugAbbrevAttr; 191 192 typedef struct DebugAbbrev { 193 u32 code; /* 1-based ULEB code */ 194 u16 tag; 195 u8 has_children; 196 u8 pad; 197 DebugAbbrevAttr* attrs; 198 u32 nattrs; 199 } DebugAbbrev; 200 201 typedef struct DebugAbbrevPool { 202 DebugAbbrev* items; 203 u32 n; 204 u32 cap; 205 } DebugAbbrevPool; 206 207 /* ---------------------------------------------------------------- */ 208 /* Debug master state. */ 209 210 struct Debug { 211 Compiler* c; 212 ObjBuilder* ob; 213 Heap* heap; 214 215 /* File table */ 216 DebugFile* files; 217 u32 nfiles; 218 u32 files_cap; 219 U32ToU32 src_to_file; /* src file_id → dwarf_idx (0-based; we map to the 220 entry in `files`). +1 stored to avoid 0-key. */ 221 222 /* Type pool */ 223 DebugType* types; 224 u32 ntypes; 225 u32 types_cap; 226 227 /* Function lifecycle */ 228 DebugFunc* funcs; 229 u32 nfuncs; 230 u32 funcs_cap; 231 i32 cur_func; /* -1 if none open */ 232 233 /* Line rows pending: latest set_loc */ 234 SrcLoc pending_loc; 235 236 /* Loclists */ 237 DebugLocList* loclists; 238 u32 nloclists; 239 u32 loclists_cap; 240 241 /* Pre-built type ids for void/builtin reuse — c_debug uses these. */ 242 DebugTypeId void_type; 243 }; 244 245 /* ---------------------------------------------------------------- */ 246 /* Form encoders (debug_form.c) */ 247 void form_u8(Buf*, u8); 248 void form_u16(Buf*, u16); 249 void form_u32(Buf*, u32); 250 void form_u64(Buf*, u64); 251 void form_uleb(Buf*, u64); 252 void form_sleb(Buf*, i64); 253 size_t form_uleb_size(u64); 254 size_t form_sleb_size(i64); 255 256 /* Abbrev pool ops (debug_abbrev.c). Teardown is abbrev_fini_heap (declared 257 * in debug_abbrev.c) — it needs the heap to free the per-abbrev attr arrays. */ 258 void abbrev_init(DebugAbbrevPool*, Heap*); 259 /* Find or insert; attrs are copied. Returns 1-based code. */ 260 u32 abbrev_intern(DebugAbbrevPool*, Heap*, u16 tag, u8 has_children, 261 const DebugAbbrevAttr* attrs, u32 nattrs); 262 /* Encode the entire pool to bytes in `buf`. */ 263 void abbrev_encode(const DebugAbbrevPool*, Buf*); 264 265 /* Internal helpers exposed for debug_emit.c */ 266 const char* debug_remap_path(Debug*, Sym original, size_t* len_out); 267 268 #endif