mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[gamecode] Load extended debug data
And add function to get a source file's base directory if available.
This commit is contained in:
parent
59f48e5e32
commit
cf7c4780eb
2 changed files with 98 additions and 10 deletions
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue