Commit b7c231c7 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Rely on first/last type index from type header.

Code now follows these guidelines: - define PDB & Codeview internals in cvconst.h and mscvinfo.h (instead of having definitions in .c files, some of them being duplicate of .h content, and their "duplicate" values eventually diverged over time) - index of first type comes from PDB type header (instead of always being hardcoded as FIRST_DEFINABLE_TYPE) - use index of last typex from type header (instead of guessing the right value while parsing types, which also allows a single allocation instead of enlarging buffer while parsing). Signed-off-by: 's avatarEric Pouech <eric.pouech@gmail.com>
parent ba12b5ae
...@@ -132,15 +132,13 @@ static void dump(const void* ptr, unsigned len) ...@@ -132,15 +132,13 @@ static void dump(const void* ptr, unsigned len)
* Process CodeView type information. * Process CodeView type information.
*/ */
#define MAX_BUILTIN_TYPES 0x06FF static struct symt* cv_basic_types[T_MAXPREDEFINEDTYPE];
#define FIRST_DEFINABLE_TYPE 0x1000
static struct symt* cv_basic_types[MAX_BUILTIN_TYPES];
struct cv_defined_module struct cv_defined_module
{ {
BOOL allowed; BOOL allowed;
unsigned int num_defined_types; unsigned int first_type_index;
unsigned int last_type_index;
struct symt** defined_types; struct symt** defined_types;
}; };
/* FIXME: don't make it static */ /* FIXME: don't make it static */
...@@ -532,15 +530,12 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet) ...@@ -532,15 +530,12 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet)
/* /*
* Convert Codeview type numbers into something we can grok internally. * Convert Codeview type numbers into something we can grok internally.
* Numbers < FIRST_DEFINABLE_TYPE are all fixed builtin types. * Numbers < T_MAXPREDEFINEDTYPE all fixed builtin types.
* Numbers from FIRST_DEFINABLE_TYPE and up are all user defined (structs, etc). * Numbers from T_FIRSTDEFINABLETYPE and up are all user defined (structs, etc).
*/ */
if (typeno < FIRST_DEFINABLE_TYPE) if (typeno < T_MAXPREDEFINEDTYPE)
{ symt = cv_basic_types[typeno];
if (typeno < MAX_BUILTIN_TYPES) else if (typeno >= T_FIRSTDEFINABLETYPE)
symt = cv_basic_types[typeno];
}
else
{ {
unsigned mod_index = typeno >> 24; unsigned mod_index = typeno >> 24;
unsigned mod_typeno = typeno & 0x00FFFFFF; unsigned mod_typeno = typeno & 0x00FFFFFF;
...@@ -548,12 +543,12 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet) ...@@ -548,12 +543,12 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet)
mod = (mod_index == 0) ? cv_current_module : &cv_zmodules[mod_index]; mod = (mod_index == 0) ? cv_current_module : &cv_zmodules[mod_index];
if (mod_index >= CV_MAX_MODULES || !mod->allowed) if (mod_index >= CV_MAX_MODULES || !mod->allowed)
FIXME("Module of index %d isn't loaded yet (%x)\n", mod_index, typeno); FIXME("Module of index %d isn't loaded yet (%x)\n", mod_index, typeno);
else else
{ {
if (mod_typeno - FIRST_DEFINABLE_TYPE < mod->num_defined_types) if (mod_typeno >= mod->first_type_index && mod_typeno < mod->last_type_index)
symt = mod->defined_types[mod_typeno - FIRST_DEFINABLE_TYPE]; symt = mod->defined_types[mod_typeno - mod->first_type_index];
} }
} }
if (!quiet && !symt && typeno) FIXME("Returning NULL symt for type-id %x\n", typeno); if (!quiet && !symt && typeno) FIXME("Returning NULL symt for type-id %x\n", typeno);
...@@ -563,22 +558,20 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet) ...@@ -563,22 +558,20 @@ static struct symt* codeview_get_type(unsigned int typeno, BOOL quiet)
struct codeview_type_parse struct codeview_type_parse
{ {
struct module* module; struct module* module;
PDB_TYPES header;
const BYTE* table; const BYTE* table;
const DWORD* offset; const DWORD* offset;
DWORD num;
}; };
static inline const void* codeview_jump_to_type(const struct codeview_type_parse* ctp, DWORD idx) static inline const void* codeview_jump_to_type(const struct codeview_type_parse* ctp, DWORD idx)
{ {
if (idx < FIRST_DEFINABLE_TYPE) return NULL; return (idx >= ctp->header.first_index && idx < ctp->header.last_index) ?
idx -= FIRST_DEFINABLE_TYPE; ctp->table + ctp->offset[idx - ctp->header.first_index] : NULL;
return (idx >= ctp->num) ? NULL : (ctp->table + ctp->offset[idx]);
} }
static int codeview_add_type(unsigned int typeno, struct symt* dt) static int codeview_add_type(unsigned int typeno, struct symt* dt)
{ {
if (typeno < FIRST_DEFINABLE_TYPE) unsigned idx;
FIXME("What the heck\n");
if (!cv_current_module) if (!cv_current_module)
{ {
FIXME("Adding %x to non allowed module\n", typeno); FIXME("Adding %x to non allowed module\n", typeno);
...@@ -587,31 +580,19 @@ static int codeview_add_type(unsigned int typeno, struct symt* dt) ...@@ -587,31 +580,19 @@ static int codeview_add_type(unsigned int typeno, struct symt* dt)
if ((typeno >> 24) != 0) if ((typeno >> 24) != 0)
FIXME("No module index while inserting type-id assumption is wrong %x\n", FIXME("No module index while inserting type-id assumption is wrong %x\n",
typeno); typeno);
if (typeno - FIRST_DEFINABLE_TYPE >= cv_current_module->num_defined_types) if (typeno < cv_current_module->first_type_index || typeno >= cv_current_module->last_type_index)
{ {
if (cv_current_module->defined_types) FIXME("Type number %x out of bounds [%x, %x)\n",
{ typeno, cv_current_module->first_type_index, typeno >= cv_current_module->last_type_index);
cv_current_module->num_defined_types = max( cv_current_module->num_defined_types * 2, return FALSE;
typeno - FIRST_DEFINABLE_TYPE + 1 );
cv_current_module->defined_types = HeapReAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, cv_current_module->defined_types,
cv_current_module->num_defined_types * sizeof(struct symt*));
}
else
{
cv_current_module->num_defined_types = max( 256, typeno - FIRST_DEFINABLE_TYPE + 1 );
cv_current_module->defined_types = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
cv_current_module->num_defined_types * sizeof(struct symt*));
}
if (cv_current_module->defined_types == NULL) return FALSE;
} }
if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE]) idx = typeno - cv_current_module->first_type_index;
if (cv_current_module->defined_types[idx])
{ {
if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] != dt) if (cv_current_module->defined_types[idx] != dt)
FIXME("Overwriting at %x\n", typeno); FIXME("Overwriting at %x\n", typeno);
} }
cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE] = dt; cv_current_module->defined_types[idx] = dt;
return TRUE; return TRUE;
} }
...@@ -622,10 +603,11 @@ static void codeview_clear_type_table(void) ...@@ -622,10 +603,11 @@ static void codeview_clear_type_table(void)
for (i = 0; i < CV_MAX_MODULES; i++) for (i = 0; i < CV_MAX_MODULES; i++)
{ {
if (cv_zmodules[i].allowed) if (cv_zmodules[i].allowed)
HeapFree(GetProcessHeap(), 0, cv_zmodules[i].defined_types); free(cv_zmodules[i].defined_types);
cv_zmodules[i].allowed = FALSE; cv_zmodules[i].allowed = FALSE;
cv_zmodules[i].defined_types = NULL; cv_zmodules[i].defined_types = NULL;
cv_zmodules[i].num_defined_types = 0; cv_zmodules[i].first_type_index = 0;
cv_zmodules[i].last_type_index = 0;
} }
cv_current_module = NULL; cv_current_module = NULL;
} }
...@@ -1381,10 +1363,15 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, ...@@ -1381,10 +1363,15 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp,
static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp)
{ {
unsigned int curr_type = FIRST_DEFINABLE_TYPE; unsigned int curr_type;
const union codeview_type* type; const union codeview_type* type;
for (curr_type = FIRST_DEFINABLE_TYPE; curr_type < FIRST_DEFINABLE_TYPE + ctp->num; curr_type++) cv_current_module->first_type_index = ctp->header.first_index;
cv_current_module->last_type_index = ctp->header.last_index;
cv_current_module->defined_types = calloc(ctp->header.last_index - ctp->header.first_index,
sizeof(*cv_current_module->defined_types));
for (curr_type = ctp->header.first_index; curr_type < ctp->header.last_index; curr_type++)
{ {
type = codeview_jump_to_type(ctp, curr_type); type = codeview_jump_to_type(ctp, curr_type);
...@@ -3053,15 +3040,14 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg, ...@@ -3053,15 +3040,14 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg,
struct codeview_type_parse* ctp, struct codeview_type_parse* ctp,
BYTE* image) BYTE* image)
{ {
PDB_TYPES types;
DWORD total;
const BYTE* ptr; const BYTE* ptr;
DWORD* offset; DWORD* offset;
int i;
pdb_convert_types_header(&types, image); pdb_convert_types_header(&ctp->header, image);
/* Check for unknown versions */ /* Check for unknown versions */
switch (types.version) switch (ctp->header.version)
{ {
case 19950410: /* VC 4.0 */ case 19950410: /* VC 4.0 */
case 19951122: case 19951122:
...@@ -3070,22 +3056,22 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg, ...@@ -3070,22 +3056,22 @@ static BOOL pdb_init_type_parse(const struct msc_debug_info* msc_dbg,
case 20040203: /* VC 8.0 */ case 20040203: /* VC 8.0 */
break; break;
default: default:
ERR("-Unknown type info version %d\n", types.version); ERR("-Unknown type info version %d\n", ctp->header.version);
return FALSE; return FALSE;
} }
ctp->module = msc_dbg->module; ctp->module = msc_dbg->module;
/* reconstruct the types offset... /* Reconstruct the types offset table
* FIXME: maybe it's present in the newest PDB_TYPES structures * Note: the hash subfile of the PDB_TYPES only contains a partial table
* (not all the indexes are present, so it requires first a binary search in partial table,
* followed by a linear search...)
*/ */
total = types.last_index - types.first_index + 1; offset = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * (ctp->header.last_index - ctp->header.first_index));
offset = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) * total);
if (!offset) return FALSE; if (!offset) return FALSE;
ctp->table = ptr = image + types.type_offset; ctp->table = ptr = image + ctp->header.type_offset;
ctp->num = 0; for (i = ctp->header.first_index; i < ctp->header.last_index; i++)
while (ptr < ctp->table + types.type_size && ctp->num < total)
{ {
offset[ctp->num++] = ptr - ctp->table; offset[i - ctp->header.first_index] = ptr - ctp->table;
ptr += ((const union codeview_type*)ptr)->generic.len + 2; ptr += ((const union codeview_type*)ptr)->generic.len + 2;
} }
ctp->offset = offset; ctp->offset = offset;
...@@ -3882,7 +3868,9 @@ static BOOL codeview_process_info(const struct process* pcs, ...@@ -3882,7 +3868,9 @@ static BOOL codeview_process_info(const struct process* pcs,
types = (const OMFGlobalTypes*)(msc_dbg->root + ent->lfo); types = (const OMFGlobalTypes*)(msc_dbg->root + ent->lfo);
ctp.module = msc_dbg->module; ctp.module = msc_dbg->module;
ctp.offset = (const DWORD*)(types + 1); ctp.offset = (const DWORD*)(types + 1);
ctp.num = types->cTypes; memset(&ctp.header, 0, sizeof(ctp.header));
ctp.header.first_index = T_FIRSTDEFINABLETYPE;
ctp.header.last_index = ctp.header.first_index + types->cTypes;
ctp.table = (const BYTE*)(ctp.offset + types->cTypes); ctp.table = (const BYTE*)(ctp.offset + types->cTypes);
cv_current_module = &cv_zmodules[0]; cv_current_module = &cv_zmodules[0];
......
...@@ -1172,7 +1172,8 @@ union codeview_fieldtype ...@@ -1172,7 +1172,8 @@ union codeview_fieldtype
#define T_64PCHAR8 0x067c /* 64 near pointer to 8-bit unicode char */ #define T_64PCHAR8 0x067c /* 64 near pointer to 8-bit unicode char */
/* counts, bit masks, and shift values needed to access various parts of the built-in type numbers */ /* counts, bit masks, and shift values needed to access various parts of the built-in type numbers */
#define T_MAXPREDEFINEDTYPE 0x0580 /* maximum type index for all built-in types */ #define T_FIRSTDEFINABLETYPE 0x1000 /* first type index that's not predefined */
#define T_MAXPREDEFINEDTYPE 0x0680 /* maximum type index for all built-in types */
#define T_MAXBASICTYPE 0x0080 /* maximum type index all non-pointer built-in types */ #define T_MAXBASICTYPE 0x0080 /* maximum type index all non-pointer built-in types */
#define T_BASICTYPE_MASK 0x00ff /* mask of bits that can potentially identify a non-pointer basic type */ #define T_BASICTYPE_MASK 0x00ff /* mask of bits that can potentially identify a non-pointer basic type */
#define T_BASICTYPE_SHIFT 8 /* shift count to push out the basic type bits from a type number */ #define T_BASICTYPE_SHIFT 8 /* shift count to push out the basic type bits from a type number */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment