[gamecode] Load extended debug data

And add function to get a source file's base directory if available.
This commit is contained in:
Bill Currie 2020-04-04 12:50:25 +09:00
parent 59f48e5e32
commit cf7c4780eb
2 changed files with 98 additions and 10 deletions

View file

@ -1689,6 +1689,7 @@ typedef struct type_view_s {
void PR_Debug_Init (progs_t *pr); void PR_Debug_Init (progs_t *pr);
void PR_Debug_Init_Cvars (void); void PR_Debug_Init_Cvars (void);
int PR_LoadDebug (progs_t *pr); 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_Watch (progs_t *pr, const char *expr);
void PR_Debug_Print (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)); pr_auxfunction_t *PR_Debug_AuxFunction (progs_t *pr, pr_uint_t func) __attribute__((pure));

View file

@ -70,6 +70,11 @@ typedef struct {
progs_t *pr; progs_t *pr;
} file_t; } file_t;
typedef struct compunit_s {
const char *file;
pr_compunit_t *unit;
} compunit_t;
typedef struct prdeb_resources_s { typedef struct prdeb_resources_s {
progs_t *pr; progs_t *pr;
dstring_t *string; dstring_t *string;
@ -85,6 +90,11 @@ typedef struct prdeb_resources_s {
pr_def_t *type_encodings_def; pr_def_t *type_encodings_def;
qfot_type_t void_type; qfot_type_t void_type;
qfot_type_t *type_encodings[ev_type_count]; 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; hashtab_t *file_hash;
} prdeb_resources_t; } prdeb_resources_t;
@ -174,6 +184,21 @@ file_free (void *_f, void *unused)
free (f); 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 static void
source_path_f (cvar_t *var) source_path_f (cvar_t *var)
{ {
@ -345,9 +370,10 @@ pr_debug_clear (progs_t *pr, void *data)
if (res->debug) if (res->debug)
pr->free_progs_mem (pr, 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->debug = 0;
res->auxfunctions = 0; res->auxfunctions = 0;
if (res->auxfunction_map) if (res->auxfunction_map)
@ -422,6 +448,36 @@ PR_Load_Source_File (progs_t *pr, const char *fname)
return f; 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 VISIBLE int
PR_LoadDebug (progs_t *pr) PR_LoadDebug (progs_t *pr)
{ {
@ -436,7 +492,9 @@ PR_LoadDebug (progs_t *pr)
pointer_t type_encodings = 0; pointer_t type_encodings = 0;
pointer_t type_ptr; pointer_t type_ptr;
qfot_type_t *type; qfot_type_t *type;
string_t compunit_str;
pr->pr_debug_resources = res;
if (!pr_debug->int_val) if (!pr_debug->int_val)
return 1; return 1;
@ -490,11 +548,17 @@ PR_LoadDebug (progs_t *pr)
res->debug->num_linenos = LittleLong (res->debug->num_linenos); res->debug->num_linenos = LittleLong (res->debug->num_linenos);
res->debug->locals = LittleLong (res->debug->locals); res->debug->locals = LittleLong (res->debug->locals);
res->debug->num_locals = LittleLong (res->debug->num_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->auxfunctions = (pr_auxfunction_t*)((char*)res->debug +
res->debug->auxfunctions); res->debug->auxfunctions);
res->linenos = (pr_lineno_t*)((char*)res->debug + res->debug->linenos); res->linenos = (pr_lineno_t*)((char*)res->debug + res->debug->linenos);
res->local_defs = (pr_def_t*)((char*)res->debug + res->debug->locals); 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 *); i = pr->progs->numfunctions * sizeof (pr_auxfunction_t *);
res->auxfunction_map = pr->allocate_progs_mem (pr, i); 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); res->linenos[i].line = LittleLong (res->linenos[i].line);
} }
for (i = 0; i < res->debug->num_locals; i++) { for (i = 0; i < res->debug->num_locals; i++) {
res->local_defs[i].type = LittleShort (res->local_defs[i].type); byteswap_def (&res->local_defs[i]);
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);
if (type_encodings) { if (type_encodings) {
res->local_defs[i].type_encoding += 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) { if (encodings) {
for (type_ptr = 4; type_ptr < encodings->size; for (type_ptr = 4; type_ptr < encodings->size;
type_ptr += type->size) { type_ptr += type->size) {
@ -553,6 +624,18 @@ PR_LoadDebug (progs_t *pr)
return 1; 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 * VISIBLE pr_auxfunction_t *
PR_Debug_AuxFunction (progs_t *pr, pr_uint_t func) 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++ ) { for (int i = 0; i < ev_type_count; i++ ) {
res->type_encodings[i] = &res->void_type; 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->hashlink_freelist);
PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear); PR_Resources_Register (pr, "PR_Debug", res, pr_debug_clear);