dbghelp: Rewrote the linetab access so that we don't need to allocate intermediate information.
This commit is contained in:
parent
ac42ebb5dc
commit
3dc37cbf94
|
@ -1256,108 +1256,72 @@ static int codeview_parse_type_table(struct codeview_type_parse* ctp)
|
|||
/*========================================================================
|
||||
* Process CodeView line number information.
|
||||
*/
|
||||
static unsigned codeview_get_address(const struct msc_debug_info* msc_dbg,
|
||||
unsigned seg, unsigned offset);
|
||||
|
||||
static struct codeview_linetab* codeview_snarf_linetab(struct module* module,
|
||||
const BYTE* linetab, int size,
|
||||
BOOL pascal_str)
|
||||
static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const BYTE* linetab,
|
||||
int size, BOOL pascal_str)
|
||||
{
|
||||
int file_segcount;
|
||||
char filename[PATH_MAX];
|
||||
const BYTE* ptr = linetab;
|
||||
int nfile, nseg;
|
||||
int i, j, k;
|
||||
const unsigned int* filetab;
|
||||
const struct p_string* p_fn;
|
||||
int i;
|
||||
int k;
|
||||
struct codeview_linetab* lt_hdr;
|
||||
const unsigned int* lt_ptr;
|
||||
int nfile;
|
||||
int nseg;
|
||||
union any_size pnt;
|
||||
union any_size pnt2;
|
||||
const unsigned short* linenos;
|
||||
const struct startend* start;
|
||||
int this_seg;
|
||||
unsigned source;
|
||||
unsigned addr, func_addr0;
|
||||
struct symt_function* func;
|
||||
const struct codeview_linetab_block* ltb;
|
||||
|
||||
/*
|
||||
* Now get the important bits.
|
||||
*/
|
||||
pnt.uc = linetab;
|
||||
nfile = *pnt.s++;
|
||||
nseg = *pnt.s++;
|
||||
nfile = *(const short*)linetab;
|
||||
filetab = (const unsigned int*)(linetab + 2 * sizeof(short));
|
||||
|
||||
filetab = (const unsigned int*) pnt.c;
|
||||
|
||||
/*
|
||||
* Now count up the number of segments in the file.
|
||||
*/
|
||||
nseg = 0;
|
||||
for (i = 0; i < nfile; i++)
|
||||
{
|
||||
pnt2.uc = linetab + filetab[i];
|
||||
nseg += *pnt2.s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next allocate the header we will be returning.
|
||||
* There is one header for each segment, so that we can reach in
|
||||
* and pull bits as required.
|
||||
*/
|
||||
lt_hdr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
(nseg + 1) * sizeof(*lt_hdr));
|
||||
if (lt_hdr == NULL)
|
||||
{
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now fill the header we will be returning, one for each segment.
|
||||
* Note that this will basically just contain pointers into the existing
|
||||
* line table, and we do not actually copy any additional information
|
||||
* or allocate any additional memory.
|
||||
*/
|
||||
|
||||
this_seg = 0;
|
||||
for (i = 0; i < nfile; i++)
|
||||
{
|
||||
/*
|
||||
* Get the pointer into the segment information.
|
||||
*/
|
||||
pnt2.uc = linetab + filetab[i];
|
||||
file_segcount = *pnt2.s;
|
||||
|
||||
pnt2.ui++;
|
||||
lt_ptr = (const unsigned int*) pnt2.c;
|
||||
start = (const struct startend*)(lt_ptr + file_segcount);
|
||||
ptr = linetab + filetab[i];
|
||||
nseg = *(const short*)ptr;
|
||||
lt_ptr = (const unsigned int*)(ptr + 2 * sizeof(short));
|
||||
start = (const struct startend*)(lt_ptr + nseg);
|
||||
|
||||
/*
|
||||
* Now snarf the filename for all of the segments for this file.
|
||||
*/
|
||||
if (pascal_str)
|
||||
{
|
||||
p_fn = (const struct p_string*)(start + file_segcount);
|
||||
memset(filename, 0, sizeof(filename));
|
||||
memcpy(filename, p_fn->name, p_fn->namelen);
|
||||
source = source_new(module, NULL, filename);
|
||||
}
|
||||
source = source_new(msc_dbg->module, NULL, terminate_string((const struct p_string*)(start + nseg)));
|
||||
else
|
||||
source = source_new(module, NULL, (const char*)(start + file_segcount));
|
||||
source = source_new(msc_dbg->module, NULL, (const char*)(start + nseg));
|
||||
|
||||
for (k = 0; k < file_segcount; k++, this_seg++)
|
||||
for (j = 0; j < nseg; j++)
|
||||
{
|
||||
pnt2.uc = linetab + lt_ptr[k];
|
||||
lt_hdr[this_seg].start = start[k].start;
|
||||
lt_hdr[this_seg].end = start[k].end;
|
||||
lt_hdr[this_seg].source = source;
|
||||
lt_hdr[this_seg].segno = *pnt2.s++;
|
||||
lt_hdr[this_seg].nline = *pnt2.s++;
|
||||
lt_hdr[this_seg].offtab = pnt2.ui;
|
||||
lt_hdr[this_seg].linetab = (const unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
|
||||
ltb = (const struct codeview_linetab_block*)(linetab + *lt_ptr++);
|
||||
linenos = (const unsigned short*)<b->offsets[ltb->num_lines];
|
||||
func_addr0 = codeview_get_address(msc_dbg, ltb->seg, start[j].start);
|
||||
if (!func_addr0) continue;
|
||||
for (func = NULL, k = 0; k < ltb->num_lines; k++)
|
||||
{
|
||||
/* now locate function (if any) */
|
||||
addr = func_addr0 + ltb->offsets[k] - start[j].start;
|
||||
/* unfortunetaly, we can have several functions in the same block, if there's no
|
||||
* gap between them... find the new function if needed
|
||||
*/
|
||||
if (!func || addr >= func->address + func->size)
|
||||
{
|
||||
func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
|
||||
/* FIXME: at least labels support line numbers */
|
||||
if (!func || func->symt.tag != SymTagFunction)
|
||||
{
|
||||
WARN("--not a func at %04x:%08x %x tag=%d\n",
|
||||
ltb->seg, ltb->offsets[k], addr, func ? func->symt.tag : -1);
|
||||
func = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
symt_add_func_line(msc_dbg->module, func, source,
|
||||
linenos[k], addr - func->address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leave:
|
||||
|
||||
return lt_hdr;
|
||||
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
|
@ -1381,24 +1345,6 @@ static unsigned int codeview_map_offset(const struct msc_debug_info* msc_dbg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct codeview_linetab*
|
||||
codeview_get_linetab(const struct codeview_linetab* linetab,
|
||||
unsigned seg, unsigned offset)
|
||||
{
|
||||
/*
|
||||
* Check whether we have line number information
|
||||
*/
|
||||
if (linetab)
|
||||
{
|
||||
for (; linetab->linetab; linetab++)
|
||||
if (linetab->segno == seg &&
|
||||
linetab->start <= offset && linetab->end > offset)
|
||||
break;
|
||||
if (!linetab->linetab) linetab = NULL;
|
||||
}
|
||||
return linetab;
|
||||
}
|
||||
|
||||
static unsigned codeview_get_address(const struct msc_debug_info* msc_dbg,
|
||||
unsigned seg, unsigned offset)
|
||||
{
|
||||
|
@ -1410,24 +1356,6 @@ static unsigned codeview_get_address(const struct msc_debug_info* msc_dbg,
|
|||
codeview_map_offset(msc_dbg, sectp[seg-1].VirtualAddress + offset);
|
||||
}
|
||||
|
||||
static void codeview_add_func_linenum(struct module* module,
|
||||
struct symt_function* func,
|
||||
const struct codeview_linetab* linetab,
|
||||
unsigned offset, unsigned size)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!linetab) return;
|
||||
for (i = 0; i < linetab->nline; i++)
|
||||
{
|
||||
if (linetab->offtab[i] >= offset && linetab->offtab[i] < offset + size)
|
||||
{
|
||||
symt_add_func_line(module, func, linetab->source,
|
||||
linetab->linetab[i], linetab->offtab[i] - offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name,
|
||||
|
@ -1448,12 +1376,10 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg,
|
|||
}
|
||||
|
||||
static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root,
|
||||
int offset, int size,
|
||||
struct codeview_linetab* linetab, BOOL do_globals)
|
||||
int offset, int size, BOOL do_globals)
|
||||
{
|
||||
struct symt_function* curr_func = NULL;
|
||||
int i, length;
|
||||
const struct codeview_linetab* flt;
|
||||
struct symt_block* block = NULL;
|
||||
struct symt* symt;
|
||||
const char* name;
|
||||
|
@ -1532,15 +1458,12 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
*/
|
||||
case S_GPROC_V1:
|
||||
case S_LPROC_V1:
|
||||
flt = codeview_get_linetab(linetab, sym->proc_v1.segment, sym->proc_v1.offset);
|
||||
if (curr_func) FIXME("nested function\n");
|
||||
curr_func = symt_new_function(msc_dbg->module, compiland,
|
||||
terminate_string(&sym->proc_v1.p_name),
|
||||
codeview_get_address(msc_dbg, sym->proc_v1.segment, sym->proc_v1.offset),
|
||||
sym->proc_v1.proc_len,
|
||||
codeview_get_type(sym->proc_v1.proctype, FALSE));
|
||||
codeview_add_func_linenum(msc_dbg->module, curr_func, flt,
|
||||
sym->proc_v1.offset, sym->proc_v1.proc_len);
|
||||
loc.kind = loc_absolute;
|
||||
loc.offset = sym->proc_v1.debug_start;
|
||||
symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
|
||||
|
@ -1549,15 +1472,12 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
break;
|
||||
case S_GPROC_V2:
|
||||
case S_LPROC_V2:
|
||||
flt = codeview_get_linetab(linetab, sym->proc_v2.segment, sym->proc_v2.offset);
|
||||
if (curr_func) FIXME("nested function\n");
|
||||
curr_func = symt_new_function(msc_dbg->module, compiland,
|
||||
terminate_string(&sym->proc_v2.p_name),
|
||||
codeview_get_address(msc_dbg, sym->proc_v2.segment, sym->proc_v2.offset),
|
||||
sym->proc_v2.proc_len,
|
||||
codeview_get_type(sym->proc_v2.proctype, FALSE));
|
||||
codeview_add_func_linenum(msc_dbg->module, curr_func, flt,
|
||||
sym->proc_v2.offset, sym->proc_v2.proc_len);
|
||||
loc.kind = loc_absolute;
|
||||
loc.offset = sym->proc_v2.debug_start;
|
||||
symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
|
||||
|
@ -1566,15 +1486,12 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
break;
|
||||
case S_GPROC_V3:
|
||||
case S_LPROC_V3:
|
||||
flt = codeview_get_linetab(linetab, sym->proc_v3.segment, sym->proc_v3.offset);
|
||||
if (curr_func) FIXME("nested function\n");
|
||||
curr_func = symt_new_function(msc_dbg->module, compiland,
|
||||
sym->proc_v3.name,
|
||||
codeview_get_address(msc_dbg, sym->proc_v3.segment, sym->proc_v3.offset),
|
||||
sym->proc_v3.proc_len,
|
||||
codeview_get_type(sym->proc_v3.proctype, FALSE));
|
||||
codeview_add_func_linenum(msc_dbg->module, curr_func, flt,
|
||||
sym->proc_v3.offset, sym->proc_v3.proc_len);
|
||||
loc.kind = loc_absolute;
|
||||
loc.offset = sym->proc_v3.debug_start;
|
||||
symt_add_function_point(msc_dbg->module, curr_func, SymTagFuncDebugStart, &loc, NULL);
|
||||
|
@ -1873,7 +1790,6 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
|
||||
if (curr_func) symt_normalize_function(msc_dbg->module, curr_func);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, linetab);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2477,10 +2393,10 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
if (globalimage)
|
||||
{
|
||||
codeview_snarf(msc_dbg, globalimage, 0,
|
||||
pdb_get_file_size(pdb_lookup, symbols.gsym_file), NULL, FALSE);
|
||||
pdb_get_file_size(pdb_lookup, symbols.gsym_file), FALSE);
|
||||
}
|
||||
|
||||
/* Read per-module symbol / linenumber tables */
|
||||
/* Read per-module symbols' tables */
|
||||
file = symbols_image + header_size;
|
||||
while (file - symbols_image < header_size + symbols.module_size)
|
||||
{
|
||||
|
@ -2494,17 +2410,15 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
|||
modimage = pdb_read_file(image, pdb_lookup, sfile.file);
|
||||
if (modimage)
|
||||
{
|
||||
struct codeview_linetab* linetab = NULL;
|
||||
|
||||
if (sfile.lineno_size)
|
||||
linetab = codeview_snarf_linetab(msc_dbg->module,
|
||||
modimage + sfile.symbol_size,
|
||||
sfile.lineno_size,
|
||||
pdb_lookup->kind == PDB_JG);
|
||||
|
||||
if (sfile.symbol_size)
|
||||
codeview_snarf(msc_dbg, modimage, sizeof(DWORD),
|
||||
sfile.symbol_size, linetab, TRUE);
|
||||
sfile.symbol_size, TRUE);
|
||||
|
||||
if (sfile.lineno_size)
|
||||
codeview_snarf_linetab(msc_dbg,
|
||||
modimage + sfile.symbol_size,
|
||||
sfile.lineno_size,
|
||||
pdb_lookup->kind == PDB_JG);
|
||||
|
||||
pdb_free(modimage);
|
||||
}
|
||||
|
@ -2662,6 +2576,9 @@ static BOOL codeview_process_info(const struct process* pcs,
|
|||
|
||||
if (ent->SubSection == sstAlignSym)
|
||||
{
|
||||
codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
|
||||
ent->cb, TRUE);
|
||||
|
||||
/*
|
||||
* Check the next and previous entry. If either is a
|
||||
* sstSrcModule, it contains the line number info for
|
||||
|
@ -2669,22 +2586,14 @@ static BOOL codeview_process_info(const struct process* pcs,
|
|||
*
|
||||
* FIXME: This is not a general solution!
|
||||
*/
|
||||
struct codeview_linetab* linetab = NULL;
|
||||
if (next && next->iMod == ent->iMod && next->SubSection == sstSrcModule)
|
||||
codeview_snarf_linetab(msc_dbg, msc_dbg->root + next->lfo,
|
||||
next->cb, TRUE);
|
||||
|
||||
if (next && next->iMod == ent->iMod &&
|
||||
next->SubSection == sstSrcModule)
|
||||
linetab = codeview_snarf_linetab(msc_dbg->module,
|
||||
msc_dbg->root + next->lfo, next->cb,
|
||||
TRUE);
|
||||
if (prev && prev->iMod == ent->iMod && prev->SubSection == sstSrcModule)
|
||||
codeview_snarf_linetab(msc_dbg, msc_dbg->root + prev->lfo,
|
||||
prev->cb, TRUE);
|
||||
|
||||
if (prev && prev->iMod == ent->iMod &&
|
||||
prev->SubSection == sstSrcModule)
|
||||
linetab = codeview_snarf_linetab(msc_dbg->module,
|
||||
msc_dbg->root + prev->lfo, prev->cb,
|
||||
TRUE);
|
||||
|
||||
codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
|
||||
ent->cb, linetab, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1628,13 +1628,12 @@ union codeview_symbol
|
|||
* Line number information
|
||||
* ======================================== */
|
||||
|
||||
union any_size
|
||||
struct codeview_linetab_block
|
||||
{
|
||||
const char* c;
|
||||
const unsigned char* uc;
|
||||
const short* s;
|
||||
const int* i;
|
||||
const unsigned int* ui;
|
||||
unsigned short seg;
|
||||
unsigned short num_lines;
|
||||
unsigned int offsets[1]; /* in fact num_lines */
|
||||
/* unsigned short linenos[]; */
|
||||
};
|
||||
|
||||
struct startend
|
||||
|
@ -1643,17 +1642,6 @@ struct startend
|
|||
unsigned int end;
|
||||
};
|
||||
|
||||
struct codeview_linetab
|
||||
{
|
||||
unsigned int nline;
|
||||
unsigned int segno;
|
||||
unsigned int start;
|
||||
unsigned int end;
|
||||
unsigned int source;
|
||||
const unsigned short* linetab;
|
||||
const unsigned int* offtab;
|
||||
};
|
||||
|
||||
/* there's a new line tab structure from MS Studio 2005 and after
|
||||
* it's made of:
|
||||
* DWORD 000000f4
|
||||
|
|
Loading…
Reference in New Issue