debug.h (5971B)
1 #ifndef KIT_DEBUG_H 2 #define KIT_DEBUG_H 3 4 #include "arch/mc.h" 5 #include "core/core.h" 6 7 /* DWARF debug info. The producer side (CG, CGTarget/MCEmitter, opt) feeds 8 * events here as compilation runs; the emitter side writes .debug_* 9 * sections into the same ObjBuilder when debug_emit is called. 10 * 11 * Type DIEs are addressed through opaque DebugTypeId handles. The core 12 * Debug module is language-neutral: it knows about DWARF type kinds (base, 13 * pointer, array, qualified, typedef, function, record, enum) but not 14 * about any source-language type representation. Frontends own their 15 * adapters and pass DebugTypeId values here. 16 * 17 * Producer responsibilities: 18 * - Parser: nothing directly; types are looked up on demand from those 19 * that reach debug_local / debug_param. 20 * - CG: function and scope lifecycle, parameter and local declarations, 21 * using frontend-provided DebugTypeId values. 22 * - MCEmitter (or the lowering pass inside opt at -O2): the line program 23 * and pc-range bounds for functions. 24 * - opt at -O2: location-list entries when a variable's location changes 25 * across the optimized function. */ 26 27 typedef struct Debug Debug; 28 29 Debug* debug_new(Compiler*, ObjBuilder*); 30 void debug_free(Debug*); 31 32 /* file table — SourceManager owns paths; returns DWARF file index */ 33 u32 debug_file(Debug*, u32 source_file_id); 34 35 /* ============================================================ 36 * Type DIE handles 37 * ============================================================ 38 * Construction is one-shot per type: callers describe the type to Debug, 39 * which records the DIE and returns an id. Ids are stable for the 40 * lifetime of the Debug object. DEBUG_TYPE_NONE is the sentinel used for 41 * "no type" (e.g. a void return without an explicit void DIE — callers 42 * normally supply debug_type_void()). 43 * 44 * The core Debug module does not intern by source-language identity. 45 * Constructing the same shape twice yields two distinct ids. */ 46 47 typedef u32 DebugTypeId; 48 #define DEBUG_TYPE_NONE 0u 49 50 typedef enum DebugBaseEncoding { 51 DEBUG_BE_BOOL, 52 DEBUG_BE_SIGNED, 53 DEBUG_BE_UNSIGNED, 54 DEBUG_BE_SIGNED_CHAR, 55 DEBUG_BE_UNSIGNED_CHAR, 56 DEBUG_BE_FLOAT, 57 DEBUG_BE_UTF, 58 DEBUG_BE_ADDRESS, 59 } DebugBaseEncoding; 60 61 DebugTypeId debug_type_base(Debug*, Sym name, DebugBaseEncoding, u32 byte_size); 62 DebugTypeId debug_type_void(Debug*); 63 DebugTypeId debug_type_ptr(Debug*, DebugTypeId pointee); 64 /* count == 0 means incomplete/unknown bound */ 65 DebugTypeId debug_type_array(Debug*, DebugTypeId elem, u32 count); 66 DebugTypeId debug_type_const(Debug*, DebugTypeId base); 67 DebugTypeId debug_type_volatile(Debug*, DebugTypeId base); 68 DebugTypeId debug_type_restrict(Debug*, DebugTypeId base); 69 DebugTypeId debug_type_typedef(Debug*, Sym name, DebugTypeId base); 70 DebugTypeId debug_type_func(Debug*, DebugTypeId ret, const DebugTypeId* params, 71 u32 nparams, int variadic); 72 73 /* Records (struct/union) and enums are built incrementally so that 74 * recursive shapes (a struct containing a pointer to itself) can be 75 * expressed: open the builder, get an id back from _end, and pass that id 76 * back through debug_type_ptr earlier if needed via the adapter's cache. */ 77 typedef struct DebugTypeBuilder DebugTypeBuilder; 78 DebugTypeBuilder* debug_type_record_begin(Debug*, Sym tag, int is_union, 79 u32 byte_size, u32 align); 80 DebugTypeId debug_type_record_id(DebugTypeBuilder*); 81 void debug_type_record_field(DebugTypeBuilder*, Sym name, DebugTypeId type, 82 u32 byte_offset); 83 void debug_type_record_bitfield(DebugTypeBuilder*, Sym name, DebugTypeId type, 84 u32 byte_offset, u16 bit_offset, u16 bit_width); 85 DebugTypeId debug_type_record_end(DebugTypeBuilder*); 86 87 typedef struct DebugEnumBuilder DebugEnumBuilder; 88 DebugEnumBuilder* debug_type_enum_begin(Debug*, Sym tag, DebugTypeId base); 89 void debug_type_enum_value(DebugEnumBuilder*, Sym name, i64 value); 90 DebugTypeId debug_type_enum_end(DebugEnumBuilder*); 91 92 /* ============================================================ 93 * Function and variable lifecycle 94 * ============================================================ */ 95 96 void debug_func_begin(Debug*, ObjSymId, DebugTypeId fn_type, SrcLoc decl); 97 void debug_func_select(Debug*, ObjSymId); 98 void debug_func_pc_range(Debug*, ObjSecId text_section_id, u32 begin_ofs, 99 u32 end_ofs); 100 void debug_func_end(Debug*); 101 void debug_prune_removed_funcs(Debug*); 102 103 /* lexical scopes (nested between func_begin/end) */ 104 void debug_scope_begin(Debug*, SrcLoc); 105 void debug_scope_end(Debug*, SrcLoc); 106 107 /* variable location */ 108 typedef enum DebugVarLocKind { 109 DVL_FRAME, 110 DVL_REG, 111 DVL_GLOBAL, 112 } DebugVarLocKind; 113 114 typedef struct DebugVarLoc { 115 u8 kind; 116 u8 pad[3]; 117 union { 118 i32 frame_ofs; 119 Reg reg; 120 ObjSymId global; 121 } v; 122 } DebugVarLoc; 123 124 void debug_param(Debug*, Sym name, DebugTypeId, SrcLoc, u32 idx, DebugVarLoc); 125 void debug_local(Debug*, Sym name, DebugTypeId, SrcLoc, DebugVarLoc); 126 void debug_global(Debug*, Sym name, DebugTypeId, SrcLoc, DebugVarLoc, 127 int external); 128 129 /* line program */ 130 void debug_line(Debug*, ObjSecId text_section_id, u32 text_offset, SrcLoc, 131 int is_stmt); 132 133 /* Stash the most recent SrcLoc reported by the parser/harness. CG calls this 134 * from cg_set_loc; the backend is free to read d->pending_loc when it doesn't 135 * already have a loc on hand. */ 136 void debug_set_pending_loc(Debug*, SrcLoc); 137 138 /* Backend-side line-program input: invoked after each emitted instruction. 139 * Forwards to debug_line with is_stmt=1 and dedupes back-to-back identical 140 * (section, offset, loc) triples. */ 141 void debug_emit_row(Debug*, ObjSecId text_section_id, u32 text_offset, SrcLoc); 142 143 /* Emit the accumulated debug info as DWARF sections into the ObjBuilder. 144 * Must be called after all code sections are finalized but before the 145 * file emitters run. */ 146 void debug_emit(Debug*); 147 148 #endif