From cf7c4780eb2ec6f1e650487ca78427bbb3f1d0cc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 4 Apr 2020 12:50:25 +0900 Subject: [PATCH] [gamecode] Load extended debug data And add function to get a source file's base directory if available. --- include/QF/progs.h | 1 + libs/gamecode/pr_debug.c | 107 +++++++++++++++++++++++++++++++++++---- 2 files changed, 98 insertions(+), 10 deletions(-) diff --git a/include/QF/progs.h b/include/QF/progs.h index 1445081fd..abc92f7f5 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -1689,6 +1689,7 @@ typedef struct type_view_s { void PR_Debug_Init (progs_t *pr); void PR_Debug_Init_Cvars (void); int PR_LoadDebug (progs_t *pr); +const char *PR_Debug_GetBaseDirectory (progs_t *pr, const char *file); void PR_Debug_Watch (progs_t *pr, const char *expr); void PR_Debug_Print (progs_t *pr, const char *expr); pr_auxfunction_t *PR_Debug_AuxFunction (progs_t *pr, pr_uint_t func) __attribute__((pure)); diff --git a/libs/gamecode/pr_debug.c b/libs/gamecode/pr_debug.c index f5f1650af..3d99da30a 100644 --- a/libs/gamecode/pr_debug.c +++ b/libs/gamecode/pr_debug.c @@ -70,6 +70,11 @@ typedef struct { progs_t *pr; } file_t; +typedef struct compunit_s { + const char *file; + pr_compunit_t *unit; +} compunit_t; + typedef struct prdeb_resources_s { progs_t *pr; dstring_t *string; @@ -85,6 +90,11 @@ typedef struct prdeb_resources_s { pr_def_t *type_encodings_def; qfot_type_t void_type; qfot_type_t *type_encodings[ev_type_count]; + pr_def_t *debug_defs; + pr_type_t *debug_data; + hashtab_t *debug_syms; + hashtab_t *compunits; // by source file + PR_RESMAP (compunit_t) compmap; // handy allocation/freeing hashtab_t *file_hash; } prdeb_resources_t; @@ -174,6 +184,21 @@ file_free (void *_f, void *unused) free (f); } +static const char * +def_get_key (const void *d, void *p) +{ + __auto_type def = (pr_def_t *) d; + __auto_type pr = (progs_t *) p; + return PR_GetString (pr, def->name); +} + +static const char * +compunit_get_key (const void *cu, void *p) +{ + __auto_type compunit = (compunit_t *) cu; + return compunit->file; +} + static void source_path_f (cvar_t *var) { @@ -345,9 +370,10 @@ pr_debug_clear (progs_t *pr, void *data) if (res->debug) pr->free_progs_mem (pr, res->debug); - if (res->file_hash) { - Hash_FlushTable (res->file_hash); - } + Hash_FlushTable (res->file_hash); + Hash_FlushTable (res->debug_syms); + Hash_FlushTable (res->compunits); + PR_RESRESET (compunit_t, res->compmap); res->debug = 0; res->auxfunctions = 0; if (res->auxfunction_map) @@ -422,6 +448,36 @@ PR_Load_Source_File (progs_t *pr, const char *fname) return f; } +static void +byteswap_def (pr_def_t *def) +{ + def->type = LittleShort (def->type); + def->size = LittleShort (def->size); + def->ofs = LittleLong (def->ofs); + def->name = LittleLong (def->name); + def->type_encoding = LittleLong (def->type_encoding); +} + +static compunit_t * +new_compunit (prdeb_resources_t *res) +{ + PR_RESNEW (compunit_t, res->compmap); +} + +static void +process_compunit (prdeb_resources_t *res, pr_def_t *def) +{ + progs_t *pr = res->pr; + __auto_type compunit = (pr_compunit_t *) (res->debug_data + def->ofs); + + for (unsigned i = 0; i < compunit->num_files; i++) { + compunit_t *cu = new_compunit (res); + cu->unit = compunit; + cu->file = PR_GetString (pr, compunit->files[i]); + Hash_Add (res->compunits, cu); + } +} + VISIBLE int PR_LoadDebug (progs_t *pr) { @@ -436,7 +492,9 @@ PR_LoadDebug (progs_t *pr) pointer_t type_encodings = 0; pointer_t type_ptr; qfot_type_t *type; + string_t compunit_str; + pr->pr_debug_resources = res; if (!pr_debug->int_val) return 1; @@ -490,11 +548,17 @@ PR_LoadDebug (progs_t *pr) res->debug->num_linenos = LittleLong (res->debug->num_linenos); res->debug->locals = LittleLong (res->debug->locals); res->debug->num_locals = LittleLong (res->debug->num_locals); + res->debug->debug_defs = LittleLong (res->debug->debug_defs); + res->debug->num_debug_defs = LittleLong (res->debug->num_debug_defs); + res->debug->debug_data = LittleLong (res->debug->debug_data); + res->debug->debug_data_size = LittleLong (res->debug->debug_data_size); res->auxfunctions = (pr_auxfunction_t*)((char*)res->debug + res->debug->auxfunctions); res->linenos = (pr_lineno_t*)((char*)res->debug + res->debug->linenos); res->local_defs = (pr_def_t*)((char*)res->debug + res->debug->locals); + res->debug_defs = (pr_def_t*)((char*)res->debug + res->debug->debug_defs); + res->debug_data = (pr_type_t*)((char*)res->debug + res->debug->debug_data); i = pr->progs->numfunctions * sizeof (pr_auxfunction_t *); res->auxfunction_map = pr->allocate_progs_mem (pr, i); @@ -530,16 +594,23 @@ PR_LoadDebug (progs_t *pr) res->linenos[i].line = LittleLong (res->linenos[i].line); } for (i = 0; i < res->debug->num_locals; i++) { - res->local_defs[i].type = LittleShort (res->local_defs[i].type); - res->local_defs[i].size = LittleShort (res->local_defs[i].size); - res->local_defs[i].ofs = LittleLong (res->local_defs[i].ofs); - res->local_defs[i].name = LittleLong (res->local_defs[i].name); - res->local_defs[i].type_encoding - = LittleLong (res->local_defs[i].type_encoding); + byteswap_def (&res->local_defs[i]); if (type_encodings) { res->local_defs[i].type_encoding += type_encodings; } } + compunit_str = PR_FindString (pr, ".compile_unit"); + for (i = 0; i < res->debug->num_debug_defs; i++) { + pr_def_t *def = &res->debug_defs[i]; + byteswap_def (def); + if (type_encodings) { + def->type_encoding += type_encodings; + } + Hash_Add (res->debug_syms, def); + if (def->name == compunit_str) { + process_compunit (res, def); + } + } if (encodings) { for (type_ptr = 4; type_ptr < encodings->size; type_ptr += type->size) { @@ -553,6 +624,18 @@ PR_LoadDebug (progs_t *pr) return 1; } +VISIBLE const char * +PR_Debug_GetBaseDirectory (progs_t *pr, const char *file) +{ + prdeb_resources_t *res = pr->pr_debug_resources; + __auto_type cu = (compunit_t *) Hash_Find (res->compunits, file); + + if (cu) { + return PR_GetString (pr, cu->unit->basedir); + } + return 0; +} + VISIBLE pr_auxfunction_t * PR_Debug_AuxFunction (progs_t *pr, pr_uint_t func) { @@ -1615,7 +1698,11 @@ PR_Debug_Init (progs_t *pr) for (int i = 0; i < ev_type_count; i++ ) { res->type_encodings[i] = &res->void_type; } - res->file_hash = Hash_NewTable (1024, file_get_key, file_free, 0, + res->file_hash = Hash_NewTable (509, file_get_key, file_free, 0, + pr->hashlink_freelist); + res->debug_syms = Hash_NewTable (509, def_get_key, 0, pr, + pr->hashlink_freelist); + res->compunits = Hash_NewTable (509, compunit_get_key, 0, pr, pr->hashlink_freelist); PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear);