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 ---- */