- fixed some bugs in StackWalk (claimed for but forgotten in last

patch)
- removed location field in symt_data, and reworked the actual
  location of information based on the 'kind' field
- shorten debug channel name
- added support for bitfield in struct:s
- cleaned up source line information support
- now storing constants values as VARIANT
This commit is contained in:
Eric Pouech 2004-04-30 04:15:41 +00:00 committed by Alexandre Julliard
parent c5524e1e6b
commit c5e0a696d9
4 changed files with 95 additions and 121 deletions

View File

@ -132,18 +132,16 @@ struct symt_data
enum DataKind kind;
struct symt* container;
struct symt* type;
enum LocationType location;
union /* depends on location */
union /* depends on kind */
{
unsigned long address; /* used by Static, Tls, ThisRel */
int offset; /* used by RegRel */
unsigned reg_id; /* used by Enregistered */
unsigned long address; /* DataIs{Global, FileStatic} */
struct
{
unsigned position;
unsigned length;
} bitfield; /* used by BitField */
VARIANT value; /* LocIsConstant */
long offset; /* DataIs{Member,Local,Param} in bits*/
unsigned long length; /* DataIs{Member} in bits */
unsigned long reg_id; /* DataIs{Local} (0 if frame relative) */
} s;
VARIANT value; /* DataIsConstant */
} u;
};

View File

@ -70,14 +70,12 @@ static const char* wine_dbgstr_addr(const ADDRESS* addr)
* StackWalk (DBGHELP.@)
*/
BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
LPSTACKFRAME frame, LPVOID _ctx,
LPSTACKFRAME frame, LPVOID ctx,
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem,
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr)
{
#ifdef __i386__
CONTEXT* ctx = (CONTEXT*)_ctx;
STACK32FRAME frame32;
STACK16FRAME frame16;
char ch;
@ -87,7 +85,7 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
BOOL do_switch;
TRACE("(%ld, %p, %p, %p, %p, %p, %p, %p, %p)\n",
MachineType, hProcess, hThread, frame, _ctx,
MachineType, hProcess, hThread, frame, ctx,
f_read_mem, FunctionTableAccessRoutine,
GetModuleBaseRoutine, f_xlat_adr);
@ -119,13 +117,6 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
curr_mode = (frame->AddrPC.Mode == AddrModeFlat) ?
stm_32bit : stm_16bit;
/* Get the current ESP (don't know if this is valid) */
if (ctx)
{
frame->AddrStack.Segment = 0;
frame->AddrStack.Offset = ctx->Esp;
frame->AddrStack.Mode = AddrModeFlat;
}
/* cur_switch holds address of curr_stack's field in TEB in debuggee
* address space
*/
@ -155,11 +146,6 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
&ch, sizeof(ch), NULL))
curr_switch = 0xFFFFFFFF;
frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrMode1616;
/* "pop up" previous BP value */
if (!f_read_mem(hProcess, (void*)frame->AddrFrame.Offset,
&val, sizeof(WORD), NULL))
goto done_err;
frame->AddrFrame.Offset = val;
}
else
{
@ -177,11 +163,10 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
if (!f_read_mem(hProcess, (void*)curr_switch, &ch, sizeof(ch), NULL))
curr_switch = 0xFFFFFFFF;
frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrModeFlat;
/* "pop up" previous EBP value */
if (!f_read_mem(hProcess, (void*)frame->AddrFrame.Offset,
&frame->AddrFrame.Offset, sizeof(DWORD), NULL))
goto done_err;
}
/* don't set up AddrStack on first call. Either the caller has set it up, or
* we will get it in the next frame
*/
}
else
{
@ -393,11 +378,4 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
done_err:
curr_mode = stm_done;
return FALSE;
#else /* __i386__ */
FIXME("(%ld, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",
MachineType, hProcess, hThread, frame, _ctx,
f_read_mem, FunctionTableAccessRoutine,
GetModuleBaseRoutine, f_xlat_adr);
return FALSE;
#endif
}

View File

@ -35,21 +35,18 @@
#include "dbghelp_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symtype);
#define DLIT_OFFSET 0x00
#define DLIT_FIRST 0x01
#define DLIT_LAST 0x02
#define DLIT_SOURCEFILE 0x04
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
struct line_info
{
unsigned long cookie : 3,
unsigned long is_first : 1,
is_last : 1,
is_source_file : 1,
line_number;
union
{
unsigned long pc_offset;
unsigned source_file;
unsigned long pc_offset; /* if is_source_file isn't set */
unsigned source_file; /* if is_source_file is set */
} u;
};
@ -138,8 +135,8 @@ struct symt_compiland* symt_new_compiland(struct module* module, const char* nam
{
struct symt_compiland* sym;
TRACE_(dbghelp_symtype)("Adding compiland symbol %s:%s\n",
module->module.ModuleName, name);
TRACE_(dbghelp_symt)("Adding compiland symbol %s:%s\n",
module->module.ModuleName, name);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagCompiland;
@ -158,8 +155,8 @@ struct symt_public* symt_new_public(struct module* module,
struct symt_public* sym;
struct symt** p;
TRACE_(dbghelp_symtype)("Adding public symbol %s:%s @%lx\n",
module->module.ModuleName, name, address);
TRACE_(dbghelp_symt)("Adding public symbol %s:%s @%lx\n",
module->module.ModuleName, name, address);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagPublicSymbol;
@ -189,8 +186,8 @@ struct symt_data* symt_new_global_variable(struct module* module,
struct symt_data* sym;
struct symt** p;
TRACE_(dbghelp_symtype)("Adding global symbol %s:%s @%lx %p\n",
module->module.ModuleName, name, addr, type);
TRACE_(dbghelp_symt)("Adding global symbol %s:%s @%lx %p\n",
module->module.ModuleName, name, addr, type);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagData;
@ -200,7 +197,6 @@ struct symt_data* symt_new_global_variable(struct module* module,
sym->kind = is_static ? DataIsFileStatic : DataIsGlobal;
sym->container = compiland ? &compiland->symt : NULL;
sym->type = type;
sym->location = LocIsStatic; /* FIXME */
sym->u.address = addr;
if (compiland)
{
@ -220,8 +216,8 @@ struct symt_function* symt_new_function(struct module* module,
struct symt_function* sym;
struct symt** p;
TRACE_(dbghelp_symtype)("Adding global function %s:%s @%lx-%lx\n",
module->module.ModuleName, name, addr, addr + size - 1);
TRACE_(dbghelp_symt)("Adding global function %s:%s @%lx-%lx\n",
module->module.ModuleName, name, addr, addr + size - 1);
assert(!sig_type || sig_type->tag == SymTagFunctionType);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
@ -254,16 +250,16 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
if (func == NULL || !(dbghelp_options & SYMOPT_LOAD_LINES)) return;
TRACE_(dbghelp_symtype)("(%p)%s:%lx %s:%u\n",
func, func->hash_elt.name, offset,
source_get(module, source_idx), line_num);
TRACE_(dbghelp_symt)("(%p)%s:%lx %s:%u\n",
func, func->hash_elt.name, offset,
source_get(module, source_idx), line_num);
assert(func->symt.tag == SymTagFunction);
dli = NULL;
while ((dli = vector_iter_down(&func->vlines, dli)))
{
if (dli->cookie & DLIT_SOURCEFILE)
if (dli->is_source_file)
{
last_matches = (source_idx == dli->u.source_file);
break;
@ -274,14 +270,16 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
{
/* we shouldn't have line changes on first line of function */
dli = vector_add(&func->vlines, &module->pool);
dli->cookie = DLIT_SOURCEFILE;
dli->line_number = 0;
dli->u.source_file = source_idx;
dli->is_source_file = 1;
dli->is_first = dli->is_last = 0;
dli->line_number = 0;
dli->u.source_file = source_idx;
}
dli = vector_add(&func->vlines, &module->pool);
dli->cookie = DLIT_OFFSET;
dli->line_number = line_num;
dli->u.pc_offset = func->addr + offset;
dli->is_source_file = 0;
dli->is_first = dli->is_last = 0;
dli->line_number = line_num;
dli->u.pc_offset = func->addr + offset;
}
struct symt_data* symt_add_func_local(struct module* module,
@ -296,9 +294,9 @@ struct symt_data* symt_add_func_local(struct module* module,
assert(func);
assert(func->symt.tag == SymTagFunction);
TRACE_(dbghelp_symtype)("Adding local symbol (%s:%s): %s %p\n",
module->module.ModuleName, func->hash_elt.name,
name, type);
TRACE_(dbghelp_symt)("Adding local symbol (%s:%s): %s %p\n",
module->module.ModuleName, func->hash_elt.name,
name, type);
locsym = pool_alloc(&module->pool, sizeof(*locsym));
locsym->symt.tag = SymTagData;
locsym->hash_elt.name = pool_strdup(&module->pool, name);
@ -308,14 +306,15 @@ struct symt_data* symt_add_func_local(struct module* module,
locsym->type = type;
if (regno)
{
locsym->location = LocIsEnregistered;
locsym->u.reg_id = regno;
locsym->u.s.reg_id = regno;
locsym->u.s.offset = 0;
locsym->u.s.length = 0;
}
else
{
locsym->location = LocIsRegRel;
locsym->u.reg_id = CV_REG_EBP;
locsym->u.offset = offset;
locsym->u.s.reg_id = 0;
locsym->u.s.offset = offset * 8;
locsym->u.s.length = 0;
}
if (block)
p = vector_add(&block->vchildren, &module->pool);
@ -400,8 +399,8 @@ BOOL symt_normalize_function(struct module* module, struct symt_function* func)
len = vector_length(&func->vlines);
if (len--)
{
dli = vector_at(&func->vlines, 0); dli->cookie |= DLIT_FIRST;
dli = vector_at(&func->vlines, len); dli->cookie |= DLIT_LAST;
dli = vector_at(&func->vlines, 0); dli->is_first = 1;
dli = vector_at(&func->vlines, len); dli->is_last = 1;
}
return TRUE;
}
@ -422,25 +421,32 @@ static void symt_fill_sym_info(const struct module* module,
case SymTagData:
{
struct symt_data* data = (struct symt_data*)sym;
switch (data->location)
switch (data->kind)
{
case LocIsEnregistered:
sym_info->Flags |= SYMFLAG_REGISTER;
sym_info->Register = data->u.reg_id;
sym_info->Address = 0;
case DataIsLocal:
case DataIsParam:
if (data->u.s.reg_id)
{
sym_info->Flags |= SYMFLAG_REGISTER;
sym_info->Register = data->u.s.reg_id;
sym_info->Address = 0;
}
else
{
if (data->u.s.offset < 0)
sym_info->Flags |= SYMFLAG_LOCAL | SYMFLAG_FRAMEREL;
else
sym_info->Flags |= SYMFLAG_PARAMETER | SYMFLAG_FRAMEREL;
sym_info->Register = CV_REG_EBP; /* FIXME: needed ? */
sym_info->Address = data->u.s.offset;
}
break;
case LocIsRegRel:
sym_info->Flags |=
((data->u.offset < 0) ? SYMFLAG_LOCAL : SYMFLAG_PARAMETER) |
SYMFLAG_FRAMEREL;
sym_info->Register = data->u.reg_id;
sym_info->Address = data->u.offset;
break;
case LocIsStatic:
case DataIsGlobal:
case DataIsFileStatic:
symt_get_info(sym, TI_GET_ADDRESS, &sym_info->Address);
sym_info->Register = 0;
break;
case LocIsConstant:
case DataIsConstant:
sym_info->Flags |= SYMFLAG_VALUEPRESENT;
switch (data->u.value.n1.n2.vt)
{
@ -455,7 +461,7 @@ static void symt_fill_sym_info(const struct module* module,
}
break;
default:
FIXME("Unhandled loc (%u) in sym data\n", data->location);
FIXME("Unhandled kind (%u) in sym data\n", data->kind);
}
}
break;
@ -481,8 +487,8 @@ static void symt_fill_sym_info(const struct module* module,
strncpy(sym_info->Name, name, min(sym_info->NameLen, sym_info->MaxNameLen));
sym_info->Name[sym_info->MaxNameLen - 1] = '\0';
}
TRACE_(dbghelp_symtype)("%p => %s %lu %lx\n",
sym, sym_info->Name, sym_info->Size, sym_info->Address);
TRACE_(dbghelp_symt)("%p => %s %lu %lx\n",
sym, sym_info->Name, sym_info->Size, sym_info->Address);
}
static BOOL symt_enum_module(struct module* module, const char* mask,
@ -899,7 +905,7 @@ BOOL symt_fill_func_line_info(struct module* module, struct symt_function* func,
while ((dli = vector_iter_down(&func->vlines, dli)))
{
if (!(dli->cookie & DLIT_SOURCEFILE))
if (!dli->is_source_file)
{
if (found || dli->u.pc_offset > addr) continue;
line->LineNumber = dli->line_number;
@ -998,10 +1004,10 @@ BOOL WINAPI SymGetLinePrev(HANDLE hProcess, PIMAGEHLP_LINE Line)
* source file name for the DLIT_OFFSET element just before
* the first DLIT_SOURCEFILE
*/
while (!(li->cookie & DLIT_FIRST))
while (!li->is_first)
{
li--;
if (!(li->cookie & DLIT_SOURCEFILE))
if (!li->is_source_file)
{
Line->LineNumber = li->line_number;
Line->Address = li->u.pc_offset;
@ -1028,10 +1034,10 @@ BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line)
if (line->Key == 0) return FALSE;
li = (struct line_info*)line->Key;
while (!(li->cookie & DLIT_LAST))
while (!li->is_last)
{
li++;
if (!(li->cookie & DLIT_SOURCEFILE))
if (!li->is_source_file)
{
line->LineNumber = li->line_number;
line->Address = li->u.pc_offset;

View File

@ -34,7 +34,7 @@
#include "dbghelp_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symtype);
WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
static const char* symt_get_tag_str(DWORD tag)
{
@ -154,7 +154,7 @@ struct symt_udt* symt_new_udt(struct module* module, const char* typename,
{
struct symt_udt* sym;
TRACE_(dbghelp_symtype)("Adding udt %s:%s\n", module->module.ModuleName, typename);
TRACE_(dbghelp_symt)("Adding udt %s:%s\n", module->module.ModuleName, typename);
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
{
sym->symt.tag = SymTagUDT;
@ -176,8 +176,8 @@ BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned siz
if (vector_length(&udt->vchildren) != 0)
{
if (udt->size != size)
FIXME_(dbghelp_symtype)("Changing size for %s from %u to %u\n",
udt->hash_elt.name, udt->size, size);
FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n",
udt->hash_elt.name, udt->size, size);
return TRUE;
}
udt->size = size;
@ -201,7 +201,7 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
assert(udt_type->symt.tag == SymTagUDT);
TRACE_(dbghelp_symtype)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
p = NULL;
while ((p = vector_iter_up(&udt_type->vchildren, p)))
{
@ -221,18 +221,9 @@ BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
m->kind = DataIsMember;
m->container = &udt_type->symt;
m->type = elt_type;
if (!(offset & 7) && !(size & 7))
{
m->location = LocIsThisRel;
m->u.offset = offset >> 3;
/* we could check that elt_type's size is actually size */
}
else
{
m->location = LocIsBitField;
m->u.bitfield.position = offset;
m->u.bitfield.length = size;
}
m->u.s.offset = offset;
m->u.s.length = ((offset & 7) || (size & 7)) ? size : 0;
m->u.s.reg_id = 0;
p = vector_add(&udt_type->vchildren, &module->pool);
*p = &m->symt;
@ -269,7 +260,6 @@ BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
e->container = &enum_type->symt;
/* CV defines the underlying type for the enumeration */
e->type = &symt_new_basic(module, btInt, "int", 4)->symt;
e->location = LocIsConstant;
e->u.value.n1.n2.vt = VT_I4;
e->u.value.n1.n2.n3.lVal = value;
@ -491,9 +481,11 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
break;
case TI_GET_BITPOSITION:
if (type->tag != SymTagData || ((struct symt_data*)type)->location != LocIsBitField)
if (type->tag != SymTagData ||
((struct symt_data*)type)->kind != DataIsMember ||
((struct symt_data*)type)->u.s.length == 0)
return FALSE;
X(DWORD) = ((struct symt_data*)type)->u.bitfield.position;
X(DWORD) = ((struct symt_data*)type)->u.s.offset & 7;
break;
case TI_GET_CHILDRENCOUNT:
@ -560,10 +552,10 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
X(DWORD) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
break;
case SymTagData:
if (((struct symt_data*)type)->location == LocIsBitField)
X(DWORD) = ((struct symt_data*)type)->u.bitfield.length;
else
if (((struct symt_data*)type)->kind != DataIsMember ||
!((struct symt_data*)type)->u.s.length)
return FALSE;
X(DWORD) = ((struct symt_data*)type)->u.s.length;
break;
case SymTagArrayType:
if (!symt_get_info(((struct symt_array*)type)->basetype,
@ -622,10 +614,10 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
case DataIsParam:
case DataIsLocal:
case DataIsMember:
X(ULONG) = ((struct symt_data*)type)->u.offset;
X(ULONG) = ((struct symt_data*)type)->u.s.offset >> 3;
break;
default:
FIXME("Unknown kind (%u) for get-offset\n",
FIXME("Unknown kind (%u) for get-offset\n",
((struct symt_data*)type)->kind);
return FALSE;
}