kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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