kit

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

debug.c (10878B)


      1 #include "cg/internal.h"
      2 
      3 /* Map the public debug encoding onto the DWARF producer's base-type encoding.
      4  * NONE has no DWARF spelling, so fall back to signed. */
      5 static DebugBaseEncoding debug_base_encoding(KitCgDebugEncoding enc) {
      6   switch (enc) {
      7     case KIT_CG_DEBUG_ENC_BOOL:
      8       return DEBUG_BE_BOOL;
      9     case KIT_CG_DEBUG_ENC_UNSIGNED:
     10       return DEBUG_BE_UNSIGNED;
     11     case KIT_CG_DEBUG_ENC_SIGNED_CHAR:
     12       return DEBUG_BE_SIGNED_CHAR;
     13     case KIT_CG_DEBUG_ENC_UNSIGNED_CHAR:
     14       return DEBUG_BE_UNSIGNED_CHAR;
     15     case KIT_CG_DEBUG_ENC_FLOAT:
     16       return DEBUG_BE_FLOAT;
     17     case KIT_CG_DEBUG_ENC_NONE:
     18     case KIT_CG_DEBUG_ENC_SIGNED:
     19       return DEBUG_BE_SIGNED;
     20   }
     21   return DEBUG_BE_SIGNED;
     22 }
     23 
     24 static int api_debug_type_cache_ensure(KitCg* g, KitCgTypeId id) {
     25   Heap* h;
     26   DebugTypeId* nt;
     27   u8* ns;
     28   u32 cap;
     29   if (!g || id == KIT_CG_TYPE_NONE) return 0;
     30   if (id < g->debug_type_cap) return 1;
     31   h = (Heap*)g->c->ctx->heap;
     32   cap = g->debug_type_cap ? g->debug_type_cap : 64u;
     33   while (cap <= id) cap *= 2u;
     34   nt = (DebugTypeId*)h->alloc(h, sizeof(*nt) * cap, _Alignof(DebugTypeId));
     35   ns = (u8*)h->alloc(h, sizeof(*ns) * cap, _Alignof(u8));
     36   if (!nt || !ns) {
     37     if (nt) h->free(h, nt, sizeof(*nt) * cap);
     38     if (ns) h->free(h, ns, sizeof(*ns) * cap);
     39     return 0;
     40   }
     41   memset(nt, 0, sizeof(*nt) * cap);
     42   memset(ns, 0, sizeof(*ns) * cap);
     43   if (g->debug_type_cache) {
     44     memcpy(nt, g->debug_type_cache,
     45            sizeof(*g->debug_type_cache) * g->debug_type_cap);
     46     h->free(h, g->debug_type_cache,
     47             sizeof(*g->debug_type_cache) * g->debug_type_cap);
     48   }
     49   if (g->debug_type_state) {
     50     memcpy(ns, g->debug_type_state,
     51            sizeof(*g->debug_type_state) * g->debug_type_cap);
     52     h->free(h, g->debug_type_state,
     53             sizeof(*g->debug_type_state) * g->debug_type_cap);
     54   }
     55   g->debug_type_cache = nt;
     56   g->debug_type_state = ns;
     57   g->debug_type_cap = cap;
     58   return 1;
     59 }
     60 
     61 static DebugTypeId api_debug_type_cache_get(KitCg* g, KitCgTypeId id) {
     62   if (!g || id == KIT_CG_TYPE_NONE || id >= g->debug_type_cap)
     63     return DEBUG_TYPE_NONE;
     64   return g->debug_type_cache[id];
     65 }
     66 
     67 static void api_debug_type_cache_put(KitCg* g, KitCgTypeId id, DebugTypeId dt,
     68                                      u8 state) {
     69   if (!api_debug_type_cache_ensure(g, id)) return;
     70   g->debug_type_cache[id] = dt;
     71   g->debug_type_state[id] = state;
     72 }
     73 
     74 KitCgDebugType kit_cg_debug_base(KitCg* g, KitSym name, KitCgDebugEncoding enc,
     75                                  uint32_t bytes) {
     76   if (!g || !g->debug || !name) return KIT_CG_DEBUG_TYPE_NONE;
     77   return (KitCgDebugType)debug_type_base(g->debug, (Sym)name,
     78                                          debug_base_encoding(enc), bytes);
     79 }
     80 
     81 KitCgDebugType kit_cg_debug_typedef(KitCg* g, KitSym name,
     82                                     KitCgDebugType base) {
     83   if (!g || !g->debug || !name) return KIT_CG_DEBUG_TYPE_NONE;
     84   if (base == KIT_CG_DEBUG_TYPE_NONE) base = debug_type_void(g->debug);
     85   return (KitCgDebugType)debug_type_typedef(g->debug, (Sym)name,
     86                                             (DebugTypeId)base);
     87 }
     88 
     89 KitCgDebugType kit_cg_debug_ptr(KitCg* g, KitCgDebugType pointee) {
     90   if (!g || !g->debug) return KIT_CG_DEBUG_TYPE_NONE;
     91   if (pointee == KIT_CG_DEBUG_TYPE_NONE) pointee = debug_type_void(g->debug);
     92   return (KitCgDebugType)debug_type_ptr(g->debug, (DebugTypeId)pointee);
     93 }
     94 
     95 KitCgDebugType kit_cg_debug_array(KitCg* g, KitCgDebugType elem,
     96                                   uint64_t count) {
     97   u32 n;
     98   if (!g || !g->debug) return KIT_CG_DEBUG_TYPE_NONE;
     99   if (elem == KIT_CG_DEBUG_TYPE_NONE) elem = debug_type_void(g->debug);
    100   n = count > UINT32_MAX ? 0u : (u32)count;
    101   return (KitCgDebugType)debug_type_array(g->debug, (DebugTypeId)elem, n);
    102 }
    103 
    104 KitCgDebugType kit_cg_debug_func(KitCg* g, KitCgDebugType ret,
    105                                  const KitCgDebugType* params, uint32_t nparams,
    106                                  int variadic) {
    107   Heap* h = NULL;
    108   DebugTypeId* tmp = NULL;
    109   DebugTypeId out;
    110   if (!g || !g->debug || (nparams && !params)) return KIT_CG_DEBUG_TYPE_NONE;
    111   if (ret == KIT_CG_DEBUG_TYPE_NONE) ret = debug_type_void(g->debug);
    112   if (nparams) {
    113     h = (Heap*)g->c->ctx->heap;
    114     tmp = (DebugTypeId*)h->alloc(h, sizeof(*tmp) * nparams,
    115                                  _Alignof(DebugTypeId));
    116     if (!tmp) return KIT_CG_DEBUG_TYPE_NONE;
    117     for (u32 i = 0; i < nparams; ++i) {
    118       tmp[i] = params[i] == KIT_CG_DEBUG_TYPE_NONE ? debug_type_void(g->debug)
    119                                                    : (DebugTypeId)params[i];
    120     }
    121   }
    122   out = debug_type_func(g->debug, (DebugTypeId)ret, tmp, nparams, variadic);
    123   if (tmp) h->free(h, tmp, sizeof(*tmp) * nparams);
    124   return (KitCgDebugType)out;
    125 }
    126 
    127 static DebugTypeId api_debug_of_type(KitCg* g, KitCgTypeId id) {
    128   const CgType* ty;
    129   DebugTypeId cached;
    130   DebugTypeId out = DEBUG_TYPE_NONE;
    131   if (!g || !g->debug) return DEBUG_TYPE_NONE;
    132   cached = api_debug_type_cache_get(g, id);
    133   if (cached != DEBUG_TYPE_NONE) return cached;
    134   ty = cg_type_get(g->c, id);
    135   if (!ty) return DEBUG_TYPE_NONE;
    136   switch (ty->kind) {
    137     case KIT_CG_TYPE_VOID:
    138       out = debug_type_void(g->debug);
    139       break;
    140     case KIT_CG_TYPE_BOOL:
    141       out = debug_type_base(g->debug,
    142                             pool_intern_slice(g->c->global, SLICE_LIT("_Bool")),
    143                             DEBUG_BE_BOOL, 1);
    144       break;
    145     case KIT_CG_TYPE_INT: {
    146       const char* name = "long long";
    147       if (ty->integer.width <= 8)
    148         name = "char";
    149       else if (ty->integer.width <= 16)
    150         name = "short";
    151       else if (ty->integer.width <= 32)
    152         name = "int";
    153       out = debug_type_base(
    154           g->debug, pool_intern_slice(g->c->global, slice_from_cstr(name)),
    155           DEBUG_BE_SIGNED, (u32)((ty->integer.width + 7u) / 8u));
    156       break;
    157     }
    158     case KIT_CG_TYPE_FLOAT: {
    159       const char* name = ty->fp.width <= 32 ? "float" : "double";
    160       out = debug_type_base(
    161           g->debug, pool_intern_slice(g->c->global, slice_from_cstr(name)),
    162           DEBUG_BE_FLOAT, (u32)((ty->fp.width + 7u) / 8u));
    163       break;
    164     }
    165     case KIT_CG_TYPE_PTR: {
    166       DebugTypeId pointee = api_debug_of_type(g, ty->ptr.pointee);
    167       if (pointee == DEBUG_TYPE_NONE) pointee = debug_type_void(g->debug);
    168       out = debug_type_ptr(g->debug, pointee);
    169       break;
    170     }
    171     case KIT_CG_TYPE_ARRAY: {
    172       DebugTypeId elem = api_debug_of_type(g, ty->array.elem);
    173       u32 count = ty->array.count > UINT32_MAX ? 0u : (u32)ty->array.count;
    174       if (elem == DEBUG_TYPE_NONE) elem = debug_type_void(g->debug);
    175       out = debug_type_array(g->debug, elem, count);
    176       break;
    177     }
    178     case KIT_CG_TYPE_FUNC: {
    179       Heap* h = (Heap*)g->c->ctx->heap;
    180       DebugTypeId ret = ty->func.result.type
    181                             ? api_debug_of_type(g, ty->func.result.type)
    182                             : DEBUG_TYPE_NONE;
    183       DebugTypeId* params = NULL;
    184       DebugTypeId fn;
    185       if (ret == DEBUG_TYPE_NONE) ret = debug_type_void(g->debug);
    186       if (ty->func.nparams) {
    187         params = (DebugTypeId*)h->alloc(h, sizeof(*params) * ty->func.nparams,
    188                                         _Alignof(DebugTypeId));
    189         if (!params) return DEBUG_TYPE_NONE;
    190         for (u32 i = 0; i < ty->func.nparams; ++i) {
    191           params[i] = api_debug_of_type(g, ty->func.params[i].type);
    192           if (params[i] == DEBUG_TYPE_NONE)
    193             params[i] = debug_type_void(g->debug);
    194         }
    195       }
    196       fn = debug_type_func(g->debug, ret, params, ty->func.nparams,
    197                            ty->func.abi_variadic);
    198       if (params) h->free(h, params, sizeof(*params) * ty->func.nparams);
    199       out = fn;
    200       break;
    201     }
    202     case KIT_CG_TYPE_RECORD: {
    203       const KitCgRecordLayout* layout =
    204           kit_cg_type_record_layout((KitCompiler*)g->c, id);
    205       DebugTypeBuilder* b;
    206       if (!layout) {
    207         b = debug_type_record_begin(g->debug, (Sym)ty->record.tag,
    208                                     ty->record.is_union, 0, 1);
    209         if (!b) return DEBUG_TYPE_NONE;
    210         return debug_type_record_end(b);
    211       }
    212       b = debug_type_record_begin(g->debug, (Sym)ty->record.tag,
    213                                   ty->record.is_union, (u32)layout->size,
    214                                   layout->align);
    215       if (!b) return DEBUG_TYPE_NONE;
    216       out = debug_type_record_id(b);
    217       api_debug_type_cache_put(g, id, out, 1);
    218       for (u32 i = 0; i < layout->nfields; ++i) {
    219         const KitCgFieldLayout* f = &layout->fields[i];
    220         DebugTypeId ft = api_debug_of_type(g, f->type);
    221         if (ft == DEBUG_TYPE_NONE) ft = debug_type_void(g->debug);
    222         if (f->bit_width) {
    223           debug_type_record_bitfield(b, (Sym)f->name, ft, (u32)f->offset,
    224                                      f->bit_offset, f->bit_width);
    225         } else {
    226           debug_type_record_field(b, (Sym)f->name, ft, (u32)f->offset);
    227         }
    228       }
    229       out = debug_type_record_end(b);
    230       api_debug_type_cache_put(g, id, out, 2);
    231       break;
    232     }
    233     case KIT_CG_TYPE_ENUM: {
    234       DebugTypeId base = api_debug_of_type(g, ty->enum_.base);
    235       DebugEnumBuilder* eb =
    236           debug_type_enum_begin(g->debug, (Sym)ty->enum_.tag, base);
    237       if (!eb) return DEBUG_TYPE_NONE;
    238       for (u32 i = 0; i < ty->enum_.nvalues; ++i) {
    239         debug_type_enum_value(eb, (Sym)ty->enum_.values[i].name,
    240                               (i64)ty->enum_.values[i].value);
    241       }
    242       out = debug_type_enum_end(eb);
    243       break;
    244     }
    245     case KIT_CG_TYPE_VARARG_STATE:
    246       out = debug_type_void(g->debug);
    247       break;
    248   }
    249   if (out != DEBUG_TYPE_NONE) api_debug_type_cache_put(g, id, out, 2);
    250   return out;
    251 }
    252 
    253 KitCgDebugType kit_cg_debug_enum(KitCg* g, KitCgTypeId enum_type,
    254                                  KitCgDebugType base) {
    255   const CgType* ty;
    256   DebugEnumBuilder* eb;
    257   if (!g || !g->debug) return KIT_CG_DEBUG_TYPE_NONE;
    258   ty = cg_type_get(g->c, enum_type);
    259   if (!ty || ty->kind != KIT_CG_TYPE_ENUM) return KIT_CG_DEBUG_TYPE_NONE;
    260   if (base == KIT_CG_DEBUG_TYPE_NONE)
    261     base = api_debug_of_type(g, ty->enum_.base);
    262   eb = debug_type_enum_begin(g->debug, (Sym)ty->enum_.tag, (DebugTypeId)base);
    263   if (!eb) return KIT_CG_DEBUG_TYPE_NONE;
    264   for (u32 i = 0; i < ty->enum_.nvalues; ++i) {
    265     debug_type_enum_value(eb, (Sym)ty->enum_.values[i].name,
    266                           (i64)ty->enum_.values[i].value);
    267   }
    268   return (KitCgDebugType)debug_type_enum_end(eb);
    269 }
    270 
    271 KitCgDebugType kit_cg_debug_of_type(KitCg* g, KitCgTypeId id) {
    272   return (KitCgDebugType)api_debug_of_type(g, id);
    273 }
    274 
    275 DebugTypeId api_debug_type(KitCg* g, KitCgDebugType debug_type,
    276                            KitCgTypeId fallback_type) {
    277   if (!g || !g->debug) return DEBUG_TYPE_NONE;
    278   if (debug_type != KIT_CG_DEBUG_TYPE_NONE) return (DebugTypeId)debug_type;
    279   return api_debug_of_type(g, fallback_type);
    280 }
    281 
    282 /* ---- value stack helpers ---- */