kit

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

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