From c5e0a696d952a344c5e7a02ba7e18716e1c285a8 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Fri, 30 Apr 2004 04:15:41 +0000 Subject: [PATCH] - 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 --- dlls/dbghelp/dbghelp_private.h | 16 ++--- dlls/dbghelp/stack.c | 32 ++------- dlls/dbghelp/symbol.c | 126 +++++++++++++++++---------------- dlls/dbghelp/type.c | 42 +++++------ 4 files changed, 95 insertions(+), 121 deletions(-) diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h index d5f3710ec83..5cd9c5b4ac6 100644 --- a/dlls/dbghelp/dbghelp_private.h +++ b/dlls/dbghelp/dbghelp_private.h @@ -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; }; diff --git a/dlls/dbghelp/stack.c b/dlls/dbghelp/stack.c index b094df97cbc..bf0843d503d 100644 --- a/dlls/dbghelp/stack.c +++ b/dlls/dbghelp/stack.c @@ -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 } diff --git a/dlls/dbghelp/symbol.c b/dlls/dbghelp/symbol.c index 4e78a66375a..98e595e4e7d 100644 --- a/dlls/dbghelp/symbol.c +++ b/dlls/dbghelp/symbol.c @@ -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; diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c index 8089dbc993b..15aae51d249 100644 --- a/dlls/dbghelp/type.c +++ b/dlls/dbghelp/type.c @@ -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; }