[PATCH 18/19] [DbgHelp]: rewrote the linetab access so that we don't need to allocate intermediate information
Eric Pouech
eric.pouech at orange.fr
Mon Sep 29 14:32:29 CDT 2008
A+
---
dlls/dbghelp/msc.c | 223 ++++++++++++++----------------------------------
include/wine/mscvpdb.h | 22 +----
2 files changed, 71 insertions(+), 174 deletions(-)
diff --git a/dlls/dbghelp/msc.c b/dlls/dbghelp/msc.c
index b9b9132..e18276d 100644
--- a/dlls/dbghelp/msc.c
+++ b/dlls/dbghelp/msc.c
@@ -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));
-
- for (k = 0; k < file_segcount; k++, this_seg++)
+ source = source_new(msc_dbg->module, NULL, (const char*)(start + nseg));
+
+ 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)
- linetab = codeview_snarf_linetab(msc_dbg->module,
- msc_dbg->root + next->lfo, next->cb,
- TRUE);
+ if (next && next->iMod == ent->iMod && next->SubSection == sstSrcModule)
+ codeview_snarf_linetab(msc_dbg, msc_dbg->root + next->lfo,
+ next->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);
+ if (prev && prev->iMod == ent->iMod && prev->SubSection == sstSrcModule)
+ codeview_snarf_linetab(msc_dbg, msc_dbg->root + prev->lfo,
+ prev->cb, TRUE);
- codeview_snarf(msc_dbg, msc_dbg->root + ent->lfo, sizeof(DWORD),
- ent->cb, linetab, TRUE);
}
}
diff --git a/include/wine/mscvpdb.h b/include/wine/mscvpdb.h
index caf6db9..9d52a65 100644
--- a/include/wine/mscvpdb.h
+++ b/include/wine/mscvpdb.h
@@ -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
More information about the wine-patches
mailing list