- removed file extension from module (and suffixed ELF modules with
<elf>) - added generic thunk support for builtin modules (with the help of winebuild's new markers for thunks) - for ELF modules, no longer generating SymTagPublicSymbols objects from ELF public symbol table - because of last point, rewrote stabs symbols' address and size management by parsing directly the symtab instead of using SymTagPublicSymbols objects - cleaned up SymTagPublicSymbols object names for native modules - fixed off by one errors in array management - SymLoadModule(hProc,0,0,0,0) (wine extension) will force the resynchronization of internal ELF modules list) - new option (0x40000000) for Sym{Get|Set}Option to report ELF modules in SymEnumModules (as well as loader with <wine-loader>) - some minor internal clean-ups - enhanced const correctness
This commit is contained in:
parent
d3f8f78c3a
commit
48a865983d
|
@ -42,9 +42,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
|||
* + we should add parameters' types to the function's signature
|
||||
* while processing a function's parameters
|
||||
* + get rid of MSC reading FIXME:s (lots of types are not defined)
|
||||
* + support the PUBLICS_ONLY, NO_PUBLICS and AUTO_PUBLICS options
|
||||
* + C++ management
|
||||
* - stabs:
|
||||
* + should identify the relay code in Wine and mark it as thunk type
|
||||
* + C++ management
|
||||
* - implement the callback notification mechanism
|
||||
*/
|
||||
|
@ -122,7 +122,7 @@ BOOL WINAPI SymGetSearchPath(HANDLE hProcess, LPSTR szSearchPath,
|
|||
static BOOL process_invade(HANDLE hProcess)
|
||||
{
|
||||
HMODULE hMods[256];
|
||||
char img[256], mod[256];
|
||||
char img[256];
|
||||
DWORD i, sz;
|
||||
MODULEINFO mi;
|
||||
|
||||
|
@ -133,8 +133,7 @@ static BOOL process_invade(HANDLE hProcess)
|
|||
{
|
||||
if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
|
||||
!GetModuleFileNameExA(hProcess, hMods[i], img, sizeof(img)) ||
|
||||
!GetModuleBaseNameA(hProcess, hMods[i], mod, sizeof(mod)) ||
|
||||
!SymLoadModule(hProcess, 0, img, mod, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage))
|
||||
!SymLoadModule(hProcess, 0, img, NULL, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -218,8 +217,7 @@ BOOL WINAPI SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProc
|
|||
|
||||
if (fInvadeProcess)
|
||||
{
|
||||
pcs->dbg_hdr_addr = elf_read_wine_loader_dbg_info(pcs);
|
||||
if (pcs->dbg_hdr_addr == 0)
|
||||
if (!elf_read_wine_loader_dbg_info(pcs))
|
||||
{
|
||||
SymCleanup(hProcess);
|
||||
return FALSE;
|
||||
|
|
|
@ -149,7 +149,7 @@ struct symt_function
|
|||
{
|
||||
struct symt symt;
|
||||
struct hash_table_elt hash_elt; /* if global symbol */
|
||||
unsigned long addr;
|
||||
unsigned long address;
|
||||
struct symt* container; /* compiland */
|
||||
struct symt* type; /* points to function_signature */
|
||||
unsigned long size;
|
||||
|
@ -176,6 +176,16 @@ struct symt_public
|
|||
is_function : 1;
|
||||
};
|
||||
|
||||
struct symt_thunk
|
||||
{
|
||||
struct symt symt;
|
||||
struct hash_table_elt hash_elt;
|
||||
struct symt* container; /* compiland */
|
||||
unsigned long address;
|
||||
unsigned long size;
|
||||
THUNK_ORDINAL ordinal; /* FIXME: doesn't seem to be accessible */
|
||||
};
|
||||
|
||||
/* class tree */
|
||||
struct symt_array
|
||||
{
|
||||
|
@ -229,15 +239,19 @@ struct symt_udt
|
|||
struct vector vchildren;
|
||||
};
|
||||
|
||||
enum DbgModuleType {DMT_UNKNOWN, DMT_ELF, DMT_NE, DMT_PE};
|
||||
enum module_type
|
||||
{
|
||||
DMT_UNKNOWN, /* for lookup, not actually used for a module */
|
||||
DMT_ELF, /* a real ELF shared module */
|
||||
DMT_PE, /* a native or builtin PE module */
|
||||
};
|
||||
|
||||
struct module
|
||||
{
|
||||
IMAGEHLP_MODULE module;
|
||||
struct module* next;
|
||||
enum DbgModuleType type;
|
||||
unsigned short elf_mark : 1;
|
||||
struct tagELF_DBG_INFO* elf_dbg_info;
|
||||
enum module_type type;
|
||||
struct elf_module_info* elf_info;
|
||||
|
||||
/* memory allocation pool */
|
||||
struct pool pool;
|
||||
|
@ -275,8 +289,7 @@ extern struct process* process_find_by_handle(HANDLE hProcess);
|
|||
extern SYM_TYPE elf_load_debug_info(struct module* module);
|
||||
extern struct module*
|
||||
elf_load_module(struct process* pcs, const char* name);
|
||||
extern unsigned long
|
||||
elf_read_wine_loader_dbg_info(struct process* pcs);
|
||||
extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs);
|
||||
extern BOOL elf_synchronize_module_list(struct process* pcs);
|
||||
|
||||
/* memory.c */
|
||||
|
@ -294,15 +307,15 @@ extern unsigned long WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDR
|
|||
/* module.c */
|
||||
extern struct module*
|
||||
module_find_by_addr(const struct process* pcs, unsigned long addr,
|
||||
enum DbgModuleType type);
|
||||
enum module_type type);
|
||||
extern struct module*
|
||||
module_find_by_name(const struct process* pcs,
|
||||
const char* name, enum DbgModuleType type);
|
||||
const char* name, enum module_type type);
|
||||
extern struct module*
|
||||
module_get_debug(const struct process* pcs, struct module*);
|
||||
extern struct module*
|
||||
module_new(struct process* pcs, const char* name,
|
||||
enum DbgModuleType type, unsigned long addr,
|
||||
enum module_type type, unsigned long addr,
|
||||
unsigned long size, unsigned long stamp,
|
||||
unsigned long checksum);
|
||||
|
||||
|
@ -312,7 +325,7 @@ extern BOOL module_remove(struct process* pcs,
|
|||
extern SYM_TYPE pe_load_debug_directory(const struct process* pcs,
|
||||
struct module* module,
|
||||
const BYTE* file_map,
|
||||
PIMAGE_DEBUG_DIRECTORY dbg, int nDbg);
|
||||
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
|
||||
/* pe_module.c */
|
||||
extern struct module*
|
||||
pe_load_module(struct process* pcs, char* name,
|
||||
|
@ -335,6 +348,7 @@ extern SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
/* symbol.c */
|
||||
extern const char* symt_get_name(const struct symt* sym);
|
||||
extern int symt_cmp_addr(const void* p1, const void* p2);
|
||||
extern int symt_find_nearest(struct module* module, DWORD addr);
|
||||
extern struct symt_compiland*
|
||||
symt_new_compiland(struct module* module,
|
||||
const char* filename);
|
||||
|
@ -351,10 +365,10 @@ extern struct symt_data*
|
|||
unsigned long addr, unsigned long size,
|
||||
struct symt* type);
|
||||
extern struct symt_function*
|
||||
symt_new_function(struct module* module,
|
||||
symt_new_function(struct module* module,
|
||||
struct symt_compiland* parent,
|
||||
const char* name,
|
||||
unsigned long addr, unsigned long size,
|
||||
unsigned long addr, unsigned long size,
|
||||
struct symt* type);
|
||||
extern BOOL symt_normalize_function(struct module* module,
|
||||
struct symt_function* func);
|
||||
|
@ -386,6 +400,11 @@ extern BOOL symt_fill_func_line_info(struct module* module,
|
|||
struct symt_function* func,
|
||||
DWORD addr, IMAGEHLP_LINE* line);
|
||||
extern BOOL symt_get_func_line_next(struct module* module, PIMAGEHLP_LINE line);
|
||||
extern struct symt_thunk*
|
||||
symt_new_thunk(struct module* module,
|
||||
struct symt_compiland* parent,
|
||||
const char* name, THUNK_ORDINAL ord,
|
||||
unsigned long addr, unsigned long size);
|
||||
|
||||
/* type.c */
|
||||
extern void symt_init_basic(struct module* module);
|
||||
|
@ -424,3 +443,7 @@ extern struct symt_pointer*
|
|||
extern struct symt_typedef*
|
||||
symt_new_typedef(struct module* module, struct symt* ref,
|
||||
const char* name);
|
||||
|
||||
|
||||
/* some more Wine extensions */
|
||||
#define SYMOPT_WINE_WITH_ELF_MODULES 0x40000000
|
||||
|
|
|
@ -70,10 +70,12 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
||||
|
||||
typedef struct tagELF_DBG_INFO
|
||||
struct elf_module_info
|
||||
{
|
||||
unsigned long elf_addr;
|
||||
} ELF_DBG_INFO;
|
||||
unsigned long elf_addr;
|
||||
unsigned short elf_mark : 1,
|
||||
elf_loader : 1;
|
||||
};
|
||||
|
||||
#ifdef __ELF__
|
||||
|
||||
|
@ -82,43 +84,57 @@ typedef struct tagELF_DBG_INFO
|
|||
|
||||
struct elf_info
|
||||
{
|
||||
unsigned flags; /* IN one (or several) of the ELF_INFO constants */
|
||||
unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
|
||||
struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
|
||||
unsigned flags; /* IN one (or several) of the ELF_INFO constants */
|
||||
unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
|
||||
struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
|
||||
};
|
||||
|
||||
struct symtab_elt
|
||||
{
|
||||
struct hash_table_elt ht_elt;
|
||||
const Elf32_Sym* symp;
|
||||
const char* filename;
|
||||
unsigned used;
|
||||
};
|
||||
|
||||
struct thunk_area
|
||||
{
|
||||
const char* symname;
|
||||
THUNK_ORDINAL ordinal;
|
||||
unsigned long rva_start;
|
||||
unsigned long rva_end;
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
* elf_load_symtab
|
||||
* elf_hash_symtab
|
||||
*
|
||||
* Walk through the entire symbol table and add any symbols we find there.
|
||||
* This can be used in cases where we have stripped ELF shared libraries,
|
||||
* or it can be used in cases where we have data symbols for which the address
|
||||
* isn't encoded in the stabs.
|
||||
*
|
||||
* This is all really quite easy, since we don't have to worry about line
|
||||
* numbers or local data variables.
|
||||
* creating an internal hash table to ease use ELF symtab information lookup
|
||||
*/
|
||||
static int elf_load_symtab(struct module* module, const char* addr,
|
||||
unsigned long load_addr, const Elf32_Shdr* symtab,
|
||||
const Elf32_Shdr* strtab)
|
||||
static void elf_hash_symtab(const struct module* module, struct pool* pool,
|
||||
struct hash_table* ht_symtab, const char* map_addr,
|
||||
const Elf32_Shdr* symtab, const Elf32_Shdr* strtab,
|
||||
unsigned num_areas, struct thunk_area* thunks)
|
||||
{
|
||||
int i, nsym;
|
||||
int i, j, nsym;
|
||||
const char* strp;
|
||||
const char* symname;
|
||||
const char* filename = NULL;
|
||||
const Elf32_Sym* symp;
|
||||
struct symt_compiland* compiland = NULL;
|
||||
struct symtab_elt* ste;
|
||||
|
||||
symp = (Elf32_Sym*)(addr + symtab->sh_offset);
|
||||
symp = (const Elf32_Sym*)(map_addr + symtab->sh_offset);
|
||||
nsym = symtab->sh_size / sizeof(*symp);
|
||||
strp = (char*)(addr + strtab->sh_offset);
|
||||
strp = (const char*)(map_addr + strtab->sh_offset);
|
||||
|
||||
for (j = 0; j < num_areas; j++)
|
||||
thunks[j].rva_start = thunks[j].rva_end = 0;
|
||||
|
||||
for (i = 0; i < nsym; i++, symp++)
|
||||
{
|
||||
/* Ignore certain types of entries which really aren't of that much
|
||||
* interest.
|
||||
*/
|
||||
if (ELF32_ST_TYPE(symp->st_info) == STT_SECTION ||
|
||||
symp->st_shndx == SHN_UNDEF)
|
||||
if (ELF32_ST_TYPE(symp->st_info) == STT_SECTION || symp->st_shndx == SHN_UNDEF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -127,14 +143,252 @@ static int elf_load_symtab(struct module* module, const char* addr,
|
|||
|
||||
if (ELF32_ST_TYPE(symp->st_info) == STT_FILE)
|
||||
{
|
||||
compiland = symt_new_compiland(module, symname);
|
||||
filename = symname;
|
||||
continue;
|
||||
}
|
||||
symt_new_public(module, compiland, symname,
|
||||
load_addr + symp->st_value, symp->st_size,
|
||||
TRUE /* FIXME */, ELF32_ST_TYPE(symp->st_info) == STT_FUNC);
|
||||
for (j = 0; j < num_areas; j++)
|
||||
{
|
||||
if (!strcmp(symname, thunks[j].symname))
|
||||
{
|
||||
thunks[j].rva_start = symp->st_value;
|
||||
thunks[j].rva_end = symp->st_value + symp->st_size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < num_areas) continue;
|
||||
ste = pool_alloc(pool, sizeof(*ste));
|
||||
ste->ht_elt.name = symname;
|
||||
ste->symp = symp;
|
||||
ste->filename = filename;
|
||||
ste->used = 0;
|
||||
hash_table_add(ht_symtab, &ste->ht_elt);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* elf_lookup_symtab
|
||||
*
|
||||
* lookup a symbol by name in our internal hash table for the symtab
|
||||
*/
|
||||
static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
|
||||
const struct hash_table* ht_symtab,
|
||||
const char* name, struct symt* compiland)
|
||||
{
|
||||
struct symtab_elt* weak_result = NULL; /* without compiland name */
|
||||
struct symtab_elt* result = NULL;
|
||||
struct hash_table_iter hti;
|
||||
struct symtab_elt* ste;
|
||||
const char* compiland_name;
|
||||
const char* compiland_basename;
|
||||
const char* base;
|
||||
|
||||
/* we need weak match up (at least) when symbols of same name,
|
||||
* defined several times in different compilation units,
|
||||
* are merged in a single one (hence a different filename for c.u.)
|
||||
*/
|
||||
if (compiland)
|
||||
{
|
||||
compiland_name = source_get(module,
|
||||
((struct symt_compiland*)compiland)->source);
|
||||
compiland_basename = strrchr(compiland_name, '/');
|
||||
if (!compiland_basename++) compiland_basename = compiland_name;
|
||||
}
|
||||
else compiland_name = compiland_basename = NULL;
|
||||
|
||||
hash_table_iter_init(ht_symtab, &hti, name);
|
||||
while ((ste = hash_table_iter_up(&hti)))
|
||||
{
|
||||
if (ste->used || strcmp(ste->ht_elt.name, name)) continue;
|
||||
|
||||
weak_result = ste;
|
||||
if ((ste->filename && !compiland_name) || (!ste->filename && compiland_name))
|
||||
continue;
|
||||
if (ste->filename && compiland_name)
|
||||
{
|
||||
if (strcmp(ste->filename, compiland_name))
|
||||
{
|
||||
base = strrchr(ste->filename, '/');
|
||||
if (!base++) base = ste->filename;
|
||||
if (strcmp(base, compiland_basename)) continue;
|
||||
}
|
||||
}
|
||||
if (result)
|
||||
{
|
||||
FIXME("Already found symbol %s (%s) in symtab %s @%08x and %s @%08x\n",
|
||||
name, compiland_name, result->filename, result->symp->st_value,
|
||||
ste->filename, ste->symp->st_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ste;
|
||||
ste->used = 1;
|
||||
}
|
||||
}
|
||||
if (!result && !(result = weak_result))
|
||||
{
|
||||
FIXME("Couldn't find symbol %s.%s in symtab\n",
|
||||
module->module.ModuleName, name);
|
||||
return NULL;
|
||||
}
|
||||
return result->symp;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* elf_finish_stabs_info
|
||||
*
|
||||
* - get any relevant information (address & size) from the bits we got from the
|
||||
* stabs debugging information
|
||||
*/
|
||||
static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
|
||||
{
|
||||
struct hash_table_iter hti;
|
||||
void* ptr;
|
||||
struct symt_ht* sym;
|
||||
const Elf32_Sym* symp;
|
||||
|
||||
hash_table_iter_init(&module->ht_symbols, &hti, NULL);
|
||||
while ((ptr = hash_table_iter_up(&hti)))
|
||||
{
|
||||
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
|
||||
switch (sym->symt.tag)
|
||||
{
|
||||
case SymTagFunction:
|
||||
if (((struct symt_function*)sym)->address != module->elf_info->elf_addr)
|
||||
break;
|
||||
symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
|
||||
((struct symt_function*)sym)->container);
|
||||
if (symp)
|
||||
{
|
||||
((struct symt_function*)sym)->address = module->elf_info->elf_addr +
|
||||
symp->st_value;
|
||||
((struct symt_function*)sym)->size = symp->st_size;
|
||||
}
|
||||
break;
|
||||
case SymTagData:
|
||||
switch (((struct symt_data*)sym)->kind)
|
||||
{
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
if (((struct symt_data*)sym)->u.address != module->elf_info->elf_addr)
|
||||
break;
|
||||
symp = elf_lookup_symtab(module, symtab, sym->hash_elt.name,
|
||||
((struct symt_data*)sym)->container);
|
||||
if (symp)
|
||||
((struct symt_data*)sym)->u.address = module->elf_info->elf_addr +
|
||||
symp->st_value;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported tag %u\n", sym->symt.tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* elf_load_wine_thunks
|
||||
*
|
||||
* creating the thunk objects for a wine native DLL
|
||||
*/
|
||||
static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
|
||||
unsigned num_areas, struct thunk_area* thunks)
|
||||
{
|
||||
int j;
|
||||
struct symt_compiland* compiland = NULL;
|
||||
const char* compiland_name = NULL;
|
||||
struct hash_table_iter hti;
|
||||
struct symtab_elt* ste;
|
||||
DWORD addr;
|
||||
|
||||
hash_table_iter_init(ht_symtab, &hti, NULL);
|
||||
while ((ste = hash_table_iter_up(&hti)))
|
||||
{
|
||||
if (ste->used) continue;
|
||||
|
||||
/* FIXME: this is not a good idea anyway... we are creating several
|
||||
* compiland objects for a same compilation unit
|
||||
* We try to cache the last compiland used, but it's not enough
|
||||
* (we should here only create compilands if they are not yet
|
||||
* defined)
|
||||
*/
|
||||
if (!compiland_name || compiland_name != ste->filename)
|
||||
compiland = symt_new_compiland(module,
|
||||
compiland_name = ste->filename);
|
||||
|
||||
addr = module->elf_info->elf_addr + ste->symp->st_value;
|
||||
|
||||
for (j = 0; j < num_areas; j++)
|
||||
{
|
||||
if (ste->symp->st_value >= thunks[j].rva_start &&
|
||||
ste->symp->st_value < thunks[j].rva_end)
|
||||
break;
|
||||
}
|
||||
if (j < num_areas) /* thunk found */
|
||||
{
|
||||
symt_new_thunk(module, compiland, ste->ht_elt.name, thunks[j].ordinal,
|
||||
addr, ste->symp->st_size);
|
||||
}
|
||||
else if (symt_find_nearest(module, addr) == -1)
|
||||
{
|
||||
/* creating public symbols for all the ELF symbols which haven't been
|
||||
* used yet (ie we have no debug information on them)
|
||||
* That's the case, for example, of the .spec.c files
|
||||
*/
|
||||
if (ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC)
|
||||
{
|
||||
symt_new_function(module, compiland, ste->ht_elt.name,
|
||||
addr, ste->symp->st_size, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
symt_new_global_variable(module, compiland, ste->ht_elt.name,
|
||||
FALSE /* FIXME */,
|
||||
addr, ste->symp->st_size, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* elf_new_public_symbols
|
||||
*
|
||||
* Creates a set of public symbols from an ELF symtab
|
||||
*/
|
||||
static int elf_new_public_symbols(struct module* module, struct hash_table* symtab,
|
||||
BOOL dont_check)
|
||||
{
|
||||
struct symt_compiland* compiland = NULL;
|
||||
const char* compiland_name = NULL;
|
||||
struct hash_table_iter hti;
|
||||
struct symtab_elt* ste;
|
||||
|
||||
if (!(dbghelp_options & SYMOPT_NO_PUBLICS)) return TRUE;
|
||||
|
||||
hash_table_iter_init(symtab, &hti, NULL);
|
||||
while ((ste = hash_table_iter_up(&hti)))
|
||||
{
|
||||
/* FIXME: this is not a good idea anyway... we are creating several
|
||||
* compiland objects for a same compilation unit
|
||||
* We try to cache the last compiland used, but it's not enough
|
||||
* (we should here only create compilands if they are not yet
|
||||
* defined)
|
||||
*/
|
||||
if (!compiland_name || compiland_name != ste->filename)
|
||||
compiland = symt_new_compiland(module,
|
||||
compiland_name = ste->filename);
|
||||
|
||||
if (dont_check || !(dbghelp_options & SYMOPT_AUTO_PUBLICS) ||
|
||||
symt_find_nearest(module, module->elf_info->elf_addr + ste->symp->st_value) == -1)
|
||||
{
|
||||
symt_new_public(module, compiland, ste->ht_elt.name,
|
||||
module->elf_info->elf_addr + ste->symp->st_value,
|
||||
ste->symp->st_size, TRUE /* FIXME */,
|
||||
ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -160,10 +414,22 @@ SYM_TYPE elf_load_debug_info(struct module* module)
|
|||
const Elf32_Shdr* spnt;
|
||||
const char* shstrtab;
|
||||
int i;
|
||||
int stabsect, stabstrsect, debugsect;
|
||||
int symsect, dynsect;
|
||||
int symtab_sect, dynsym_sect, stab_sect, stabstr_sect, debug_sect;
|
||||
struct pool pool;
|
||||
struct hash_table ht_symtab;
|
||||
struct thunk_area thunks[] =
|
||||
{
|
||||
{"__wine_spec_import_thunks", THUNK_ORDINAL_NOTYPE, 0, 0}, /* inter DLL calls */
|
||||
{"__wine_spec_delayed_import_loaders", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
|
||||
{"__wine_spec_delayed_import_thunks", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
|
||||
{"__wine_delay_load", THUNK_ORDINAL_LOAD, 0, 0}, /* delayed inter DLL calls */
|
||||
{"__wine_spec_thunk_text_16", -16, 0, 0}, /* 16 => 32 thunks */
|
||||
{"__wine_spec_thunk_data_16", -16, 0, 0}, /* 16 => 32 thunks */
|
||||
{"__wine_spec_thunk_text_32", -32, 0, 0}, /* 32 => 16 thunks */
|
||||
{"__wine_spec_thunk_data_32", -32, 0, 0}, /* 32 => 16 thunks */
|
||||
};
|
||||
|
||||
if (module->type != DMT_ELF || !module->elf_dbg_info)
|
||||
if (module->type != DMT_ELF || !module->elf_info)
|
||||
{
|
||||
ERR("Bad elf module '%s'\n", module->module.LoadedImageName);
|
||||
return sym_type;
|
||||
|
@ -195,55 +461,86 @@ SYM_TYPE elf_load_debug_info(struct module* module)
|
|||
spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
|
||||
shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
|
||||
|
||||
symsect = dynsect = stabsect = stabstrsect = debugsect = -1;
|
||||
symtab_sect = dynsym_sect = stab_sect = stabstr_sect = debug_sect = -1;
|
||||
|
||||
for (i = 0; i < ehptr->e_shnum; i++)
|
||||
{
|
||||
if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
|
||||
stabsect = i;
|
||||
stab_sect = i;
|
||||
if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
|
||||
stabstrsect = i;
|
||||
stabstr_sect = i;
|
||||
if (strcmp(shstrtab + spnt[i].sh_name, ".debug_info") == 0)
|
||||
debugsect = i;
|
||||
debug_sect = i;
|
||||
if ((strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0) &&
|
||||
(spnt[i].sh_type == SHT_SYMTAB))
|
||||
symsect = i;
|
||||
if ((strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0) &&
|
||||
(spnt[i].sh_type == SHT_DYNSYM))
|
||||
dynsect = i;
|
||||
symtab_sect = i;
|
||||
if ((strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0) &&
|
||||
(spnt[i].sh_type == SHT_DYNSYM))
|
||||
dynsym_sect = i;
|
||||
}
|
||||
/* start loading dynamic symbol info (so that we can get the correct address) */
|
||||
if (symsect != -1)
|
||||
elf_load_symtab(module, addr, module->elf_dbg_info->elf_addr,
|
||||
spnt + symsect, spnt + spnt[symsect].sh_link);
|
||||
else if (dynsect != -1)
|
||||
elf_load_symtab(module, addr, module->elf_dbg_info->elf_addr,
|
||||
spnt + dynsect, spnt + spnt[dynsect].sh_link);
|
||||
|
||||
sym_type = SymExport;
|
||||
|
||||
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
||||
if (symtab_sect == -1)
|
||||
{
|
||||
if (stabsect != -1 && stabstrsect != -1)
|
||||
{
|
||||
/* OK, now just parse all of the stabs. */
|
||||
sym_type = stabs_parse(module, addr, module->elf_dbg_info->elf_addr,
|
||||
spnt[stabsect].sh_offset, spnt[stabsect].sh_size,
|
||||
spnt[stabstrsect].sh_offset,
|
||||
spnt[stabstrsect].sh_size);
|
||||
if (sym_type == -1)
|
||||
{
|
||||
WARN("Couldn't read correctly read stabs\n");
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
else if (debugsect != -1)
|
||||
{
|
||||
/* Dwarf 2 debug information */
|
||||
FIXME("Unsupported Dwarf2 information\n");
|
||||
sym_type = SymNone;
|
||||
}
|
||||
/* if we don't have a symtab but a dynsym, process the dynsym
|
||||
* section instead. It'll contain less (relevant) information,
|
||||
* but it'll be better than nothing
|
||||
*/
|
||||
if (dynsym_sect == -1) goto leave;
|
||||
symtab_sect = dynsym_sect;
|
||||
}
|
||||
|
||||
/* FIXME: guess a better size from ELF info */
|
||||
pool_init(&pool, 65536);
|
||||
hash_table_init(&pool, &ht_symtab, 256);
|
||||
|
||||
/* create a hash table for the symtab */
|
||||
elf_hash_symtab(module, &pool, &ht_symtab, addr,
|
||||
spnt + symtab_sect, spnt + spnt[symtab_sect].sh_link,
|
||||
sizeof(thunks) / sizeof(thunks[0]), thunks);
|
||||
|
||||
if (stab_sect != -1 && stabstr_sect != -1 &&
|
||||
!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
||||
{
|
||||
/* OK, now just parse all of the stabs. */
|
||||
sym_type = stabs_parse(module, addr, module->elf_info->elf_addr,
|
||||
spnt[stab_sect].sh_offset, spnt[stab_sect].sh_size,
|
||||
spnt[stabstr_sect].sh_offset,
|
||||
spnt[stabstr_sect].sh_size);
|
||||
if (sym_type == -1)
|
||||
{
|
||||
WARN("Couldn't read correctly read stabs\n");
|
||||
goto leave;
|
||||
}
|
||||
/* and fill in the missing information for stabs */
|
||||
elf_finish_stabs_info(module, &ht_symtab);
|
||||
}
|
||||
else if (debug_sect != -1)
|
||||
{
|
||||
/* Dwarf 2 debug information */
|
||||
FIXME("Unsupported Dwarf2 information\n");
|
||||
sym_type = SymNone;
|
||||
}
|
||||
if (strstr(module->module.ModuleName, "<elf>"))
|
||||
{
|
||||
/* add the thunks for native libraries */
|
||||
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
|
||||
elf_new_wine_thunks(module, &ht_symtab,
|
||||
sizeof(thunks) / sizeof(thunks[0]), thunks);
|
||||
/* add the public symbols from symtab
|
||||
* (only if they haven't been defined yet)
|
||||
*/
|
||||
elf_new_public_symbols(module, &ht_symtab, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add all the public symbols from symtab */
|
||||
elf_new_public_symbols(module, &ht_symtab, TRUE);
|
||||
}
|
||||
|
||||
pool_destroy(&pool);
|
||||
|
||||
leave:
|
||||
if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
|
||||
if (fd != -1) close(fd);
|
||||
|
@ -298,6 +595,7 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename,
|
|||
const char* shstrtab;
|
||||
int i;
|
||||
DWORD delta, size;
|
||||
unsigned tmp, page_mask = getpagesize() - 1;
|
||||
|
||||
TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
|
||||
|
||||
|
@ -317,10 +615,10 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename,
|
|||
* this thing. We need the main executable header, and the section
|
||||
* table.
|
||||
*/
|
||||
ehptr = (Elf32_Ehdr*)addr;
|
||||
ehptr = (const Elf32_Ehdr*)addr;
|
||||
if (memcmp(ehptr->e_ident, elf_signature, sizeof(elf_signature))) goto leave;
|
||||
|
||||
spnt = (Elf32_Shdr*)(addr + ehptr->e_shoff);
|
||||
spnt = (const Elf32_Shdr*)(addr + ehptr->e_shoff);
|
||||
shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
|
||||
|
||||
/* if non relocatable ELF, then remove fixed address from computation
|
||||
|
@ -329,14 +627,14 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename,
|
|||
delta = (load_offset == 0) ? ehptr->e_entry : 0;
|
||||
|
||||
/* grab size of module once loaded in memory */
|
||||
ppnt = (Elf32_Phdr*)(addr + ehptr->e_phoff);
|
||||
ppnt = (const Elf32_Phdr*)(addr + ehptr->e_phoff);
|
||||
size = 0;
|
||||
for (i = 0; i < ehptr->e_phnum; i++)
|
||||
{
|
||||
if (ppnt[i].p_type == PT_LOAD)
|
||||
if (ppnt[i].p_type == PT_LOAD)
|
||||
{
|
||||
size += (ppnt[i].p_align <= 1) ? ppnt[i].p_memsz :
|
||||
(ppnt[i].p_memsz + ppnt[i].p_align - 1) & ~(ppnt[i].p_align - 1);
|
||||
tmp = (ppnt[i].p_vaddr + ppnt[i].p_memsz + page_mask) & ~page_mask;
|
||||
if (size < tmp) size = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,16 +673,19 @@ static SYM_TYPE elf_load_file(struct process* pcs, const char* filename,
|
|||
size, 0, 0);
|
||||
if (elf_info->module)
|
||||
{
|
||||
if ((elf_info->module->elf_dbg_info = HeapAlloc(GetProcessHeap(), 0, sizeof(ELF_DBG_INFO))) == NULL)
|
||||
elf_info->module->elf_info = HeapAlloc(GetProcessHeap(),
|
||||
0, sizeof(struct elf_module_info));
|
||||
if (elf_info->module->elf_info == NULL)
|
||||
{
|
||||
ERR("OOM\n");
|
||||
exit(0); /* FIXME */
|
||||
}
|
||||
elf_info->module->elf_dbg_info->elf_addr = load_offset;
|
||||
elf_info->module->elf_info->elf_addr = load_offset;
|
||||
elf_info->module->module.SymType = sym_type =
|
||||
(dbghelp_options & SYMOPT_DEFERRED_LOADS) ? SymDeferred :
|
||||
elf_load_debug_info(elf_info->module);
|
||||
elf_info->module->elf_mark = 1;
|
||||
elf_info->module->elf_info->elf_mark = 1;
|
||||
elf_info->module->elf_info->elf_loader = 0;
|
||||
}
|
||||
else sym_type = -1;
|
||||
}
|
||||
|
@ -447,7 +748,7 @@ static SYM_TYPE elf_search_and_load_file(struct process* pcs, const char* filena
|
|||
if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
|
||||
{
|
||||
elf_info->module = module;
|
||||
module->elf_mark = 1;
|
||||
module->elf_info->elf_mark = 1;
|
||||
return module->module.SymType;
|
||||
}
|
||||
|
||||
|
@ -493,7 +794,7 @@ BOOL elf_synchronize_module_list(struct process* pcs)
|
|||
|
||||
for (module = pcs->lmodules; module; module = module->next)
|
||||
{
|
||||
if (module->type == DMT_ELF) module->elf_mark = 0;
|
||||
if (module->type == DMT_ELF) module->elf_info->elf_mark = 0;
|
||||
}
|
||||
|
||||
elf_info.flags = ELF_INFO_MODULE;
|
||||
|
@ -519,7 +820,8 @@ BOOL elf_synchronize_module_list(struct process* pcs)
|
|||
|
||||
for (module = pcs->lmodules; module; module = module->next)
|
||||
{
|
||||
if (module->type == DMT_ELF && !module->elf_mark)
|
||||
if (module->type == DMT_ELF && !module->elf_info->elf_mark &&
|
||||
!module->elf_info->elf_loader)
|
||||
{
|
||||
module_remove(pcs, module);
|
||||
/* restart all over */
|
||||
|
@ -532,15 +834,15 @@ BOOL elf_synchronize_module_list(struct process* pcs)
|
|||
/******************************************************************
|
||||
* elf_read_wine_loader_dbg_info
|
||||
*
|
||||
* Try to find a decent wine executable which could have loader the debuggee
|
||||
* Try to find a decent wine executable which could have loaded the debuggee
|
||||
*/
|
||||
unsigned long elf_read_wine_loader_dbg_info(struct process* pcs)
|
||||
BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
|
||||
{
|
||||
const char* ptr;
|
||||
SYM_TYPE sym_type;
|
||||
struct elf_info elf_info;
|
||||
|
||||
elf_info.flags = ELF_INFO_DEBUG_HEADER;
|
||||
elf_info.flags = ELF_INFO_DEBUG_HEADER | ELF_INFO_MODULE;
|
||||
/* All binaries are loaded with WINELOADER (if run from tree) or by the
|
||||
* main executable (either wine-kthread or wine-pthread)
|
||||
* Note: the heuristic use to know whether we need to load wine-pthread or
|
||||
|
@ -553,7 +855,10 @@ unsigned long elf_read_wine_loader_dbg_info(struct process* pcs)
|
|||
if ((sym_type = elf_search_and_load_file(pcs, "wine-kthread", 0, &elf_info)) == -1)
|
||||
sym_type = elf_search_and_load_file(pcs, "wine-pthread", 0, &elf_info);
|
||||
}
|
||||
return (sym_type < 0) ? 0 : elf_info.dbg_hdr_addr;
|
||||
if (sym_type < 0) return FALSE;
|
||||
elf_info.module->elf_info->elf_loader = 1;
|
||||
strcpy(elf_info.module->module.ModuleName, "<wine-loader>");
|
||||
return (pcs->dbg_hdr_addr = elf_info.dbg_hdr_addr) != 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -33,16 +33,37 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
|
||||
|
||||
static void module_fill_module(const char* in, char* out, unsigned size)
|
||||
{
|
||||
const char* ptr;
|
||||
unsigned len;
|
||||
|
||||
for (ptr = in + strlen(in) - 1;
|
||||
*ptr != '/' && *ptr != '\\' && ptr >= in;
|
||||
ptr--);
|
||||
if (ptr < in || *ptr == '/' || *ptr == '\\') ptr++;
|
||||
strncpy(out, ptr, size);
|
||||
out[size - 1] = '\0';
|
||||
len = strlen(out);
|
||||
if (len > 4 &&
|
||||
(!strcasecmp(&out[len - 4], ".dll") || !strcasecmp(&out[len - 4], ".exe")))
|
||||
out[len - 4] = '\0';
|
||||
else
|
||||
if (len > 7 &&
|
||||
(!strcasecmp(&out[len - 7], ".dll.so") || !strcasecmp(&out[len - 7], ".exe.so")))
|
||||
strcpy(&out[len - 7], "<elf>");
|
||||
while ((*out = tolower(*out))) out++;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Creates and links a new module to a process
|
||||
*/
|
||||
struct module* module_new(struct process* pcs, const char* name,
|
||||
enum DbgModuleType type,
|
||||
enum module_type type,
|
||||
unsigned long mod_addr, unsigned long size,
|
||||
unsigned long stamp, unsigned long checksum)
|
||||
{
|
||||
struct module* module;
|
||||
const char* ptr;
|
||||
|
||||
if (!(module = HeapAlloc(GetProcessHeap(), 0, sizeof(*module))))
|
||||
return NULL;
|
||||
|
@ -61,12 +82,7 @@ struct module* module_new(struct process* pcs, const char* name,
|
|||
module->module.SizeOfStruct = sizeof(module->module);
|
||||
module->module.BaseOfImage = mod_addr;
|
||||
module->module.ImageSize = size;
|
||||
for (ptr = name + strlen(name) - 1;
|
||||
*ptr != '/' && *ptr != '\\' && ptr >= name;
|
||||
ptr--);
|
||||
if (ptr < name || *ptr == '/' || *ptr == '\\') ptr++;
|
||||
strncpy(module->module.ModuleName, ptr, sizeof(module->module.ModuleName));
|
||||
module->module.ModuleName[sizeof(module->module.ModuleName) - 1] = '\0';
|
||||
module_fill_module(name, module->module.ModuleName, sizeof(module->module.ModuleName));
|
||||
module->module.ImageName[0] = '\0';
|
||||
strncpy(module->module.LoadedImageName, name,
|
||||
sizeof(module->module.LoadedImageName));
|
||||
|
@ -97,7 +113,7 @@ struct module* module_new(struct process* pcs, const char* name,
|
|||
*
|
||||
*/
|
||||
struct module* module_find_by_name(const struct process* pcs,
|
||||
const char* name, enum DbgModuleType type)
|
||||
const char* name, enum module_type type)
|
||||
{
|
||||
struct module* module;
|
||||
|
||||
|
@ -188,7 +204,7 @@ struct module* module_get_debug(const struct process* pcs, struct module* module
|
|||
* module
|
||||
*/
|
||||
struct module* module_find_by_addr(const struct process* pcs, unsigned long addr,
|
||||
enum DbgModuleType type)
|
||||
enum module_type type)
|
||||
{
|
||||
struct module* module;
|
||||
|
||||
|
@ -227,6 +243,13 @@ DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, char* ImageName,
|
|||
pcs = process_find_by_handle(hProcess);
|
||||
if (!pcs) return FALSE;
|
||||
|
||||
/* this is a Wine extension to the API */
|
||||
if (!ImageName && !hFile)
|
||||
{
|
||||
elf_synchronize_module_list(pcs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(module = pe_load_module(pcs, ImageName, hFile, BaseOfDll, SizeOfDll)))
|
||||
{
|
||||
unsigned len = strlen(ImageName);
|
||||
|
@ -316,7 +339,8 @@ BOOL WINAPI SymEnumerateModules(HANDLE hProcess,
|
|||
|
||||
for (module = pcs->lmodules; module; module = module->next)
|
||||
{
|
||||
if (module->type != DMT_PE) continue;
|
||||
if (!(dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES) && module->type != DMT_PE)
|
||||
continue;
|
||||
if (!EnumModulesCallback(module->module.ModuleName,
|
||||
module->module.BaseOfImage, UserContext))
|
||||
break;
|
||||
|
@ -333,7 +357,7 @@ BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess,
|
|||
PVOID UserContext)
|
||||
{
|
||||
HMODULE* hMods;
|
||||
char img[256], mod[256];
|
||||
char base[256], mod[256];
|
||||
DWORD i, sz;
|
||||
MODULEINFO mi;
|
||||
|
||||
|
@ -351,9 +375,10 @@ BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess,
|
|||
for (i = 0; i < sz; i++)
|
||||
{
|
||||
if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
|
||||
!GetModuleFileNameExA(hProcess, hMods[i], img, sizeof(img)) ||
|
||||
!GetModuleBaseNameA(hProcess, hMods[i], mod, sizeof(mod)))
|
||||
break;
|
||||
!GetModuleBaseNameA(hProcess, hMods[i], base, sizeof(base)))
|
||||
continue;
|
||||
module_fill_module(base, mod, sizeof(mod));
|
||||
|
||||
EnumLoadedModulesCallback(mod, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage,
|
||||
UserContext);
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ struct msc_debug_info
|
|||
{
|
||||
struct module* module;
|
||||
int nsect;
|
||||
PIMAGE_SECTION_HEADER sectp;
|
||||
const IMAGE_SECTION_HEADER* sectp;
|
||||
int nomap;
|
||||
OMAP_DATA* omapp;
|
||||
const OMAP_DATA* omapp;
|
||||
const BYTE* root;
|
||||
};
|
||||
|
||||
|
@ -218,8 +218,8 @@ static SYM_TYPE coff_process_info(const struct msc_debug_info* msc_dbg)
|
|||
if (coff_sym->StorageClass == IMAGE_SYM_CLASS_FILE)
|
||||
{
|
||||
curr_file_idx = coff_add_file(&coff_files, msc_dbg->module,
|
||||
(char*)(coff_sym + 1));
|
||||
TRACE("New file %s\n", (char*)(coff_sym + 1));
|
||||
(const char*)(coff_sym + 1));
|
||||
TRACE("New file %s\n", (const char*)(coff_sym + 1));
|
||||
i += naux;
|
||||
continue;
|
||||
}
|
||||
|
@ -1111,27 +1111,27 @@ static int numeric_leaf(int* value, const unsigned short int* leaf)
|
|||
{
|
||||
case LF_CHAR:
|
||||
length += 1;
|
||||
*value = *(char*)leaf;
|
||||
*value = *(const char*)leaf;
|
||||
break;
|
||||
|
||||
case LF_SHORT:
|
||||
length += 2;
|
||||
*value = *(short*)leaf;
|
||||
*value = *(const short*)leaf;
|
||||
break;
|
||||
|
||||
case LF_USHORT:
|
||||
length += 2;
|
||||
*value = *(unsigned short*)leaf;
|
||||
*value = *(const unsigned short*)leaf;
|
||||
break;
|
||||
|
||||
case LF_LONG:
|
||||
length += 4;
|
||||
*value = *(int*)leaf;
|
||||
*value = *(const int*)leaf;
|
||||
break;
|
||||
|
||||
case LF_ULONG:
|
||||
length += 4;
|
||||
*value = *(unsigned int*)leaf;
|
||||
*value = *(const unsigned int*)leaf;
|
||||
break;
|
||||
|
||||
case LF_QUADWORD:
|
||||
|
@ -1327,7 +1327,7 @@ static int codeview_add_type_enum_field_list(struct module* module,
|
|||
symt = symt_new_enum(module, NULL);
|
||||
while (ptr - list < len)
|
||||
{
|
||||
union codeview_fieldtype* type = (union codeview_fieldtype*)ptr;
|
||||
const union codeview_fieldtype* type = (const union codeview_fieldtype*)ptr;
|
||||
|
||||
if (*ptr >= 0xf0) /* LF_PAD... */
|
||||
{
|
||||
|
@ -1340,7 +1340,7 @@ static int codeview_add_type_enum_field_list(struct module* module,
|
|||
case LF_ENUMERATE:
|
||||
{
|
||||
int value, vlen = numeric_leaf(&value, &type->enumerate.value);
|
||||
unsigned char* name = (unsigned char*)&type->enumerate.value + vlen;
|
||||
const unsigned char* name = (const unsigned char*)&type->enumerate.value + vlen;
|
||||
|
||||
symt_add_enum_element(module, symt, terminate_string(name), value);
|
||||
ptr += 2 + 2 + vlen + (1 + name[0]);
|
||||
|
@ -1400,7 +1400,7 @@ static int codeview_add_type_struct_field_list(struct module* module,
|
|||
case LF_IVBCLASS:
|
||||
{
|
||||
int vbpoff, vbplen = numeric_leaf(&vbpoff, &type->vbclass.vbpoff);
|
||||
const unsigned short int* p_vboff = (const unsigned short int*)((char*)&type->vbclass.vbpoff + vbpoff);
|
||||
const unsigned short int* p_vboff = (const unsigned short int*)((const char*)&type->vbclass.vbpoff + vbpoff);
|
||||
int vpoff, vplen = numeric_leaf(&vpoff, p_vboff);
|
||||
|
||||
/* FIXME: ignored for now */
|
||||
|
@ -1413,7 +1413,7 @@ static int codeview_add_type_struct_field_list(struct module* module,
|
|||
case LF_IVBCLASS_32:
|
||||
{
|
||||
int vbpoff, vbplen = numeric_leaf(&vbpoff, &type->vbclass32.vbpoff);
|
||||
const unsigned short int* p_vboff = (const unsigned short int*)((char*)&type->vbclass32.vbpoff + vbpoff);
|
||||
const unsigned short int* p_vboff = (const unsigned short int*)((const char*)&type->vbclass32.vbpoff + vbpoff);
|
||||
int vpoff, vplen = numeric_leaf(&vpoff, p_vboff);
|
||||
|
||||
/* FIXME: ignored for now */
|
||||
|
@ -1759,16 +1759,16 @@ static struct codeview_linetab* codeview_snarf_linetab(struct module* module,
|
|||
int file_segcount;
|
||||
char filename[PATH_MAX];
|
||||
const unsigned int* filetab;
|
||||
char* fn;
|
||||
const char* fn;
|
||||
int i;
|
||||
int k;
|
||||
struct codeview_linetab* lt_hdr;
|
||||
unsigned int* lt_ptr;
|
||||
const unsigned int* lt_ptr;
|
||||
int nfile;
|
||||
int nseg;
|
||||
union any_size pnt;
|
||||
union any_size pnt2;
|
||||
struct startend* start;
|
||||
const struct startend* start;
|
||||
int this_seg;
|
||||
struct symt_compiland* compiland;
|
||||
|
||||
|
@ -1820,13 +1820,13 @@ static struct codeview_linetab* codeview_snarf_linetab(struct module* module,
|
|||
file_segcount = *pnt2.s;
|
||||
|
||||
pnt2.ui++;
|
||||
lt_ptr = (unsigned int*) pnt2.c;
|
||||
start = (struct startend*)(lt_ptr + file_segcount);
|
||||
lt_ptr = (const unsigned int*) pnt2.c;
|
||||
start = (const struct startend*)(lt_ptr + file_segcount);
|
||||
|
||||
/*
|
||||
* Now snarf the filename for all of the segments for this file.
|
||||
*/
|
||||
fn = (unsigned char*)(start + file_segcount);
|
||||
fn = (const unsigned char*)(start + file_segcount);
|
||||
memset(filename, 0, sizeof(filename));
|
||||
memcpy(filename, fn + 1, *fn);
|
||||
compiland = symt_new_compiland(module, filename);
|
||||
|
@ -1840,7 +1840,7 @@ static struct codeview_linetab* codeview_snarf_linetab(struct module* module,
|
|||
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 = (unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
|
||||
lt_hdr[this_seg].linetab = (const unsigned short*)(pnt2.ui + lt_hdr[this_seg].nline);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2334,11 +2334,11 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
break;
|
||||
|
||||
case S_COMPILE:
|
||||
TRACE("S-Compile %x %.*s\n", ((LPBYTE)sym)[4], ((LPBYTE)sym)[8], (LPBYTE)sym + 9);
|
||||
TRACE("S-Compile %x %.*s\n", ((const BYTE*)sym)[4], ((const BYTE*)sym)[8], (const BYTE*)sym + 9);
|
||||
break;
|
||||
|
||||
case S_OBJNAME:
|
||||
TRACE("S-ObjName %.*s\n", ((LPBYTE)sym)[8], (LPBYTE)sym + 9);
|
||||
TRACE("S-ObjName %.*s\n", ((const BYTE*)sym)[8], (const BYTE*)sym + 9);
|
||||
break;
|
||||
|
||||
case S_LABEL:
|
||||
|
@ -2347,7 +2347,7 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
if (curr_func)
|
||||
{
|
||||
symt_add_function_point(msc_dbg->module, curr_func, SymTagLabel,
|
||||
codeview_get_address(msc_dbg, sym->label.segment, sym->label.offset) - curr_func->addr,
|
||||
codeview_get_address(msc_dbg, sym->label.segment, sym->label.offset) - curr_func->address,
|
||||
symname);
|
||||
}
|
||||
else FIXME("No current function for label %s\n", symname);
|
||||
|
@ -2407,7 +2407,7 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
|||
case S_DATAREF:
|
||||
case S_LPROCREF:
|
||||
{
|
||||
LPBYTE name = (LPBYTE)sym + length;
|
||||
const BYTE* name = (const BYTE*)sym + length;
|
||||
length += (*name + 1 + 3) & ~3;
|
||||
}
|
||||
break;
|
||||
|
@ -2629,7 +2629,7 @@ static void pdb_convert_types_header(PDB_TYPES* types, const BYTE* image)
|
|||
memset(types, 0, sizeof(PDB_TYPES));
|
||||
if (!image) return;
|
||||
|
||||
if (*(DWORD*)image < 19960000) /* FIXME: correct version? */
|
||||
if (*(const DWORD*)image < 19960000) /* FIXME: correct version? */
|
||||
{
|
||||
/* Old version of the types record header */
|
||||
const PDB_TYPES_OLD* old = (const PDB_TYPES_OLD*)image;
|
||||
|
@ -2653,7 +2653,7 @@ static void pdb_convert_symbols_header(PDB_SYMBOLS* symbols,
|
|||
memset(symbols, 0, sizeof(PDB_SYMBOLS));
|
||||
if (!image) return;
|
||||
|
||||
if (*(DWORD*)image != 0xffffffff)
|
||||
if (*(const DWORD*)image != 0xffffffff)
|
||||
{
|
||||
/* Old version of the symbols record header */
|
||||
const PDB_SYMBOLS_OLD* old = (const PDB_SYMBOLS_OLD*)image;
|
||||
|
@ -2686,7 +2686,7 @@ static const char* get_last_sep(const char* str)
|
|||
}
|
||||
|
||||
static HANDLE open_pdb_file(const struct process* pcs, struct module* module,
|
||||
char* filename)
|
||||
const char* filename)
|
||||
{
|
||||
HANDLE h;
|
||||
char dbg_file_path[MAX_PATH];
|
||||
|
@ -2695,7 +2695,7 @@ static HANDLE open_pdb_file(const struct process* pcs, struct module* module,
|
|||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
h = FindDebugInfoFile(filename, pcs->search_path, dbg_file_path);
|
||||
h = FindDebugInfoFile((char*)filename, pcs->search_path, dbg_file_path);
|
||||
if (h == NULL)
|
||||
{
|
||||
const char* p;
|
||||
|
@ -2716,7 +2716,7 @@ static HANDLE open_pdb_file(const struct process* pcs, struct module* module,
|
|||
|
||||
static SYM_TYPE pdb_process_file(const struct process* pcs,
|
||||
const struct msc_debug_info* msc_dbg,
|
||||
char* filename, DWORD timestamp)
|
||||
const char* filename, DWORD timestamp)
|
||||
{
|
||||
SYM_TYPE sym_type = -1;
|
||||
HANDLE hFile, hMap = NULL;
|
||||
|
@ -2982,7 +2982,7 @@ static SYM_TYPE codeview_process_info(const struct process* pcs,
|
|||
|
||||
case CODEVIEW_NB10_SIG:
|
||||
{
|
||||
PCODEVIEW_PDB_DATA pdb = (PCODEVIEW_PDB_DATA)(cv + 1);
|
||||
const CODEVIEW_PDB_DATA* pdb = (const CODEVIEW_PDB_DATA*)(cv + 1);
|
||||
|
||||
codeview_init_basic_types(msc_dbg->module);
|
||||
sym_type = pdb_process_file(pcs, msc_dbg, pdb->name, pdb->timestamp);
|
||||
|
@ -3001,17 +3001,17 @@ static SYM_TYPE codeview_process_info(const struct process* pcs,
|
|||
* Process debug directory.
|
||||
*/
|
||||
SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* module,
|
||||
const BYTE* mapping, PIMAGE_DEBUG_DIRECTORY dbg,
|
||||
const BYTE* mapping, const IMAGE_DEBUG_DIRECTORY* dbg,
|
||||
int nDbg)
|
||||
{
|
||||
SYM_TYPE sym_type;
|
||||
int i;
|
||||
struct msc_debug_info msc_dbg;
|
||||
IMAGE_NT_HEADERS* nth = RtlImageNtHeader((void*)mapping);
|
||||
const IMAGE_NT_HEADERS* nth = RtlImageNtHeader((void*)mapping);
|
||||
|
||||
msc_dbg.module = module;
|
||||
msc_dbg.nsect = nth->FileHeader.NumberOfSections;
|
||||
msc_dbg.sectp = (PIMAGE_SECTION_HEADER)((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
|
||||
msc_dbg.sectp = (const IMAGE_SECTION_HEADER*)((const char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
|
||||
msc_dbg.nomap = 0;
|
||||
msc_dbg.omapp = NULL;
|
||||
|
||||
|
@ -3025,7 +3025,7 @@ SYM_TYPE pe_load_debug_directory(const struct process* pcs, struct module* modul
|
|||
if (dbg[i].Type == IMAGE_DEBUG_TYPE_OMAP_FROM_SRC)
|
||||
{
|
||||
msc_dbg.nomap = dbg[i].SizeOfData / sizeof(OMAP_DATA);
|
||||
msc_dbg.omapp = (OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
|
||||
msc_dbg.omapp = (const OMAP_DATA*)(mapping + dbg[i].PointerToRawData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,22 +78,22 @@ static SYM_TYPE pe_load_stabs(const struct process* pcs, struct module* module,
|
|||
* loads a .dbg file
|
||||
*/
|
||||
static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* module,
|
||||
char* dbg_name, DWORD timestamp)
|
||||
const char* dbg_name, DWORD timestamp)
|
||||
{
|
||||
char tmp[MAX_PATH];
|
||||
HANDLE hFile, hMap = 0;
|
||||
const BYTE* dbg_mapping = NULL;
|
||||
PIMAGE_SEPARATE_DEBUG_HEADER hdr;
|
||||
PIMAGE_DEBUG_DIRECTORY dbg;
|
||||
SYM_TYPE sym_type = -1;
|
||||
char tmp[MAX_PATH];
|
||||
HANDLE hFile, hMap = 0;
|
||||
const BYTE* dbg_mapping = NULL;
|
||||
const IMAGE_SEPARATE_DEBUG_HEADER* hdr;
|
||||
const IMAGE_DEBUG_DIRECTORY* dbg;
|
||||
SYM_TYPE sym_type = -1;
|
||||
|
||||
WINE_TRACE("Processing DBG file %s\n", dbg_name);
|
||||
|
||||
if ((hFile = FindDebugInfoFile(dbg_name, pcs->search_path, tmp)) != NULL &&
|
||||
if ((hFile = FindDebugInfoFile((char*)dbg_name, pcs->search_path, tmp)) != NULL &&
|
||||
((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
|
||||
((dbg_mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
|
||||
{
|
||||
hdr = (PIMAGE_SEPARATE_DEBUG_HEADER)dbg_mapping;
|
||||
hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)dbg_mapping;
|
||||
if (hdr->TimeDateStamp != timestamp)
|
||||
{
|
||||
WINE_ERR("Warning - %s has incorrect internal timestamp\n",
|
||||
|
@ -105,7 +105,7 @@ static SYM_TYPE pe_load_dbg_file(const struct process* pcs, struct module* modul
|
|||
* which have incorrect timestamps.
|
||||
*/
|
||||
}
|
||||
dbg = (PIMAGE_DEBUG_DIRECTORY)
|
||||
dbg = (const IMAGE_DEBUG_DIRECTORY*)
|
||||
(dbg_mapping + sizeof(*hdr) +
|
||||
hdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) +
|
||||
hdr->ExportedNamesSize);
|
||||
|
@ -133,24 +133,24 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs,
|
|||
struct module* module,
|
||||
const void* mapping, IMAGE_NT_HEADERS* nth)
|
||||
{
|
||||
SYM_TYPE sym_type = -1;
|
||||
PIMAGE_DATA_DIRECTORY dir;
|
||||
PIMAGE_DEBUG_DIRECTORY dbg = NULL;
|
||||
int nDbg;
|
||||
SYM_TYPE sym_type = -1;
|
||||
const IMAGE_DATA_DIRECTORY* dir;
|
||||
const IMAGE_DEBUG_DIRECTORY*dbg = NULL;
|
||||
int nDbg;
|
||||
|
||||
/* Read in debug directory */
|
||||
dir = nth->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_DEBUG;
|
||||
nDbg = dir->Size / sizeof(IMAGE_DEBUG_DIRECTORY);
|
||||
if (!nDbg) return sym_type;
|
||||
|
||||
dbg = (PIMAGE_DEBUG_DIRECTORY)((char*)mapping + dir->VirtualAddress);
|
||||
dbg = (const IMAGE_DEBUG_DIRECTORY*)((const char*)mapping + dir->VirtualAddress);
|
||||
|
||||
/* Parse debug directory */
|
||||
if (nth->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)
|
||||
{
|
||||
/* Debug info is stripped to .DBG file */
|
||||
PIMAGE_DEBUG_MISC misc = (PIMAGE_DEBUG_MISC)
|
||||
((char*)mapping + dbg->PointerToRawData);
|
||||
const IMAGE_DEBUG_MISC* misc = (const IMAGE_DEBUG_MISC*)
|
||||
((const char*)mapping + dbg->PointerToRawData);
|
||||
|
||||
if (nDbg != 1 || dbg->Type != IMAGE_DEBUG_TYPE_MISC ||
|
||||
misc->DataType != IMAGE_DEBUG_MISC_EXENAME)
|
||||
|
@ -179,7 +179,6 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs,
|
|||
struct module* module,
|
||||
const void* mapping, IMAGE_NT_HEADERS* nth)
|
||||
{
|
||||
char buffer[512];
|
||||
unsigned int i;
|
||||
IMAGE_DATA_DIRECTORY* dir;
|
||||
DWORD base = module->module.BaseOfImage;
|
||||
|
@ -196,21 +195,20 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs,
|
|||
#endif
|
||||
|
||||
/* Add entry point */
|
||||
snprintf(buffer, sizeof(buffer), "%s.EntryPoint", module->module.ModuleName);
|
||||
symt_new_public(module, NULL, buffer,
|
||||
symt_new_public(module, NULL, "EntryPoint",
|
||||
base + nth->OptionalHeader.AddressOfEntryPoint, 0,
|
||||
TRUE /* FIXME */, TRUE /* FIXME */);
|
||||
|
||||
#if 0
|
||||
/* FIXME: we'd better store addresses linked to sections rather than
|
||||
absolute values */
|
||||
IMAGE_SECTION_HEADER* section;
|
||||
/* Add start of sections */
|
||||
section = (IMAGE_SECTION_HEADER*)
|
||||
((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
|
||||
for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "%s.%s",
|
||||
module->module.ModuleName, section->Name);
|
||||
symt_new_public(module, NULL, buffer, base + section->VirtualAddress, 0,
|
||||
symt_new_public(module, NULL, section->Name, base + section->VirtualAddress, 0,
|
||||
TRUE /* FIXME */, TRUE /* FIXME */);
|
||||
}
|
||||
#endif
|
||||
|
@ -219,23 +217,22 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs,
|
|||
if ((dir = RtlImageDirectoryEntryToData((void*)mapping, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT, NULL)))
|
||||
{
|
||||
IMAGE_EXPORT_DIRECTORY* exports;
|
||||
WORD* ordinals = NULL;
|
||||
void** functions = NULL;
|
||||
DWORD* names = NULL;
|
||||
unsigned int j;
|
||||
|
||||
exports = (void*)((char*)mapping + dir->VirtualAddress);
|
||||
functions = (void*)((char*)mapping + exports->AddressOfFunctions);
|
||||
ordinals = (void*)((char*)mapping + exports->AddressOfNameOrdinals);
|
||||
names = (void*)((char*)mapping + exports->AddressOfNames);
|
||||
const IMAGE_EXPORT_DIRECTORY* exports;
|
||||
const WORD* ordinals = NULL;
|
||||
const void* const* functions = NULL;
|
||||
const DWORD* names = NULL;
|
||||
unsigned int j;
|
||||
char buffer[16];
|
||||
|
||||
exports = (const void*)((const char*)mapping + dir->VirtualAddress);
|
||||
functions = (const void*)((const char*)mapping + exports->AddressOfFunctions);
|
||||
ordinals = (const void*)((const char*)mapping + exports->AddressOfNameOrdinals);
|
||||
names = (const void*)((const char*)mapping + exports->AddressOfNames);
|
||||
|
||||
for (i = 0; i < exports->NumberOfNames; i++)
|
||||
{
|
||||
if (!names[i]) continue;
|
||||
snprintf(buffer, sizeof(buffer), "%s.%s",
|
||||
module->module.ModuleName, (char*)base + names[i]);
|
||||
symt_new_public(module, NULL, buffer,
|
||||
symt_new_public(module, NULL, (const char*)base + names[i],
|
||||
base + (DWORD)functions[ordinals[i]], 0,
|
||||
TRUE /* FIXME */, TRUE /* FIXME */);
|
||||
}
|
||||
|
@ -247,9 +244,8 @@ static SYM_TYPE pe_load_export_debug_info(const struct process* pcs,
|
|||
for (j = 0; j < exports->NumberOfNames; j++)
|
||||
if ((ordinals[j] == i) && names[j]) break;
|
||||
if (j < exports->NumberOfNames) continue;
|
||||
snprintf(buffer, sizeof(buffer), "%s.%ld",
|
||||
module->module.ModuleName, i + exports->Base);
|
||||
symt_new_public(module, NULL, buffer, base + (DWORD)functions[i], 0,
|
||||
snprintf(buffer, sizeof(buffer), "%ld", i + exports->Base);
|
||||
symt_new_public(module, NULL, buffer, base + (DWORD)functions[i], 0,
|
||||
TRUE /* FIXME */, TRUE /* FIXME */);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,10 +57,6 @@
|
|||
|
||||
#include "dbghelp_private.h"
|
||||
|
||||
#if defined(__svr4__) || defined(__sun)
|
||||
#define __ELF__
|
||||
#endif
|
||||
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs);
|
||||
|
@ -842,6 +838,9 @@ static int stabs_pts_read_type_def(struct ParseTypedefData* ptd, const char* typ
|
|||
udt, symt_get_name(&udt->symt), udt->symt.tag);
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(udt->hash_elt.name, typename))
|
||||
ERR("Forward declaration name mismatch %s <> %s\n",
|
||||
udt->hash_elt.name, typename);
|
||||
/* should check typename is the same too */
|
||||
new_dt = &udt->symt;
|
||||
}
|
||||
|
@ -1042,76 +1041,6 @@ struct pending_loc_var
|
|||
unsigned regno;
|
||||
};
|
||||
|
||||
static
|
||||
struct symt_public* lookup_public(const struct module* module,
|
||||
const struct symt_compiland* compiland,
|
||||
const char* name)
|
||||
{
|
||||
unsigned nfind = 0;
|
||||
struct symt_public* found = NULL;
|
||||
struct symt_public* xfound = NULL;
|
||||
struct symt_public* sym;
|
||||
const char* xname;
|
||||
const char* tmp;
|
||||
void* ptr;
|
||||
struct hash_table_iter hti;
|
||||
const char* in_src;
|
||||
const char* out_src;
|
||||
|
||||
if (compiland && compiland->symt.tag == SymTagCompiland)
|
||||
in_src = source_get(module, compiland->source);
|
||||
else in_src = NULL;
|
||||
|
||||
hash_table_iter_init(&module->ht_symbols, &hti, name);
|
||||
while ((ptr = hash_table_iter_up(&hti)))
|
||||
{
|
||||
sym = GET_ENTRY(ptr, struct symt_public, hash_elt);
|
||||
if (sym->symt.tag == SymTagPublicSymbol)
|
||||
{
|
||||
xname = symt_get_name(&sym->symt);
|
||||
if (!xname || strcmp(xname, name)) continue;
|
||||
|
||||
if (sym->container &&
|
||||
sym->container->tag == SymTagCompiland)
|
||||
out_src = source_get(module, ((struct symt_compiland*)sym->container)->source);
|
||||
else out_src = NULL;
|
||||
|
||||
xfound = sym;
|
||||
if ((in_src && !out_src) || (!in_src && out_src)) continue;
|
||||
|
||||
if (in_src)
|
||||
{
|
||||
if (strcmp(in_src, out_src) || (tmp = strrchr(in_src, '/')) == NULL ||
|
||||
strcmp(tmp + 1, out_src))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* we continue once found to insure uniqueness of public symbol's name */
|
||||
if (nfind++)
|
||||
{
|
||||
FIXME("More than one public symbol (%s) in %s: [%u] %p {%lx,%lx} in %s\n",
|
||||
name, in_src, nfind, sym, sym->address, sym->size, out_src);
|
||||
}
|
||||
else found = sym;
|
||||
}
|
||||
}
|
||||
if (!nfind)
|
||||
{
|
||||
if (xfound) found = xfound;
|
||||
else FIXME("Couldn't locate %s in public symbols\n", name);
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
if (found->container &&
|
||||
found->container->tag == SymTagCompiland)
|
||||
out_src = source_get(module, ((struct symt_compiland*)found->container)->source);
|
||||
else out_src = NULL;
|
||||
TRACE("Found for %s in %s: %p {%lx,%lx} in %s\n",
|
||||
name, in_src, found, found->address, found->size, out_src);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* stabs_finalize_function
|
||||
*
|
||||
|
@ -1128,11 +1057,11 @@ static void stabs_finalize_function(struct module* module, struct symt_function*
|
|||
/* To define the debug-start of the function, we use the second line number.
|
||||
* Not 100% bullet proof, but better than nothing
|
||||
*/
|
||||
if (symt_fill_func_line_info(module, func, func->addr, &il) &&
|
||||
if (symt_fill_func_line_info(module, func, func->address, &il) &&
|
||||
symt_get_func_line_next(module, &il))
|
||||
{
|
||||
symt_add_function_point(module, func, SymTagFuncDebugStart,
|
||||
il.Address - func->addr, NULL);
|
||||
il.Address - func->address, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1142,7 +1071,6 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
{
|
||||
struct symt_function* curr_func = NULL;
|
||||
struct symt_block* block = NULL;
|
||||
struct symt_public* public;
|
||||
struct symt_compiland* compiland = NULL;
|
||||
char currpath[PATH_MAX];
|
||||
int i, j;
|
||||
|
@ -1162,8 +1090,8 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
unsigned num_allocated_pending_vars = 0;
|
||||
|
||||
nstab = stablen / sizeof(struct stab_nlist);
|
||||
stab_ptr = (struct stab_nlist*)(addr + staboff);
|
||||
strs = (char*)(addr + strtaboff);
|
||||
stab_ptr = (const struct stab_nlist*)(addr + staboff);
|
||||
strs = (const char*)(addr + strtaboff);
|
||||
|
||||
memset(currpath, 0, sizeof(currpath));
|
||||
memset(stabs_basic, 0, sizeof(stabs_basic));
|
||||
|
@ -1270,16 +1198,9 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
* With a.out or mingw, they actually do make some amount of sense.
|
||||
*/
|
||||
stab_strcpy(symname, sizeof(symname), ptr);
|
||||
#ifdef __ELF__
|
||||
if ((public = lookup_public(module, compiland, symname)))
|
||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||
public->address, public->size,
|
||||
stabs_parse_type(ptr));
|
||||
#else
|
||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||
load_offset + stab_ptr->n_value, 0,
|
||||
stabs_parse_type(ptr));
|
||||
#endif
|
||||
break;
|
||||
case N_LCSYM:
|
||||
case N_STSYM:
|
||||
|
@ -1396,19 +1317,8 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
if (curr_func != NULL)
|
||||
{
|
||||
assert(source_idx >= 0);
|
||||
#ifdef __ELF__
|
||||
symt_add_func_line(module, curr_func, source_idx,
|
||||
stab_ptr->n_desc, stab_ptr->n_value);
|
||||
#else
|
||||
/*
|
||||
* This isn't right. The order of the stabs is different under
|
||||
* a.out, and as a result we would end up attaching the line
|
||||
* number to the wrong function.
|
||||
*/
|
||||
symt_add_func_line(module, curr_func, source_idx,
|
||||
stab_ptr->n_desc,
|
||||
stab_ptr->n_value - curr_func->addr);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case N_FUN:
|
||||
|
@ -1433,16 +1343,9 @@ SYM_TYPE stabs_parse(struct module* module, const char* addr,
|
|||
struct symt_function_signature* func_type;
|
||||
func_type = symt_new_function_signature(module,
|
||||
stabs_parse_type(ptr));
|
||||
#ifdef __ELF__
|
||||
if ((public = lookup_public(module, compiland, symname)))
|
||||
curr_func = symt_new_function(module, compiland, symname,
|
||||
public->address, public->size,
|
||||
&func_type->symt);
|
||||
#else
|
||||
curr_func = symt_new_function(module, compiland, symname,
|
||||
load_offset + stab_ptr->n_value, 0,
|
||||
&func_type->symt);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -288,10 +288,15 @@ void hash_table_destroy(struct hash_table* ht)
|
|||
|
||||
void hash_table_add(struct hash_table* ht, struct hash_table_elt* elt)
|
||||
{
|
||||
unsigned hash = hash_table_hash(elt->name, ht->num_buckets);
|
||||
unsigned hash = hash_table_hash(elt->name, ht->num_buckets);
|
||||
struct hash_table_elt** p;
|
||||
|
||||
elt->next = ht->buckets[hash];
|
||||
ht->buckets[hash] = elt;
|
||||
/* in some cases, we need to get back the symbols of same name in the order
|
||||
* in which they've been inserted. So insert new elements at the end of the list.
|
||||
*/
|
||||
for (p = &ht->buckets[hash]; *p; p = &((*p)->next));
|
||||
*p = elt;
|
||||
elt->next = NULL;
|
||||
}
|
||||
|
||||
void* hash_table_find(const struct hash_table* ht, const char* name)
|
||||
|
|
|
@ -70,8 +70,8 @@ inline static int cmp_sorttab_addr(const struct module* module, int idx, DWORD a
|
|||
|
||||
int symt_cmp_addr(const void* p1, const void* p2)
|
||||
{
|
||||
struct symt* sym1 = *(struct symt**)p1;
|
||||
struct symt* sym2 = *(struct symt**)p2;
|
||||
const struct symt* sym1 = *(const struct symt* const *)p1;
|
||||
const struct symt* sym2 = *(const struct symt* const *)p2;
|
||||
DWORD a1, a2;
|
||||
|
||||
symt_get_info(sym1, TI_GET_ADDRESS, &a1);
|
||||
|
@ -188,6 +188,7 @@ struct symt_data* symt_new_global_variable(struct module* module,
|
|||
{
|
||||
struct symt_data* sym;
|
||||
struct symt** p;
|
||||
DWORD tsz;
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding global symbol %s:%s @%lx %p\n",
|
||||
module->module.ModuleName, name, addr, type);
|
||||
|
@ -201,6 +202,12 @@ struct symt_data* symt_new_global_variable(struct module* module,
|
|||
sym->container = compiland ? &compiland->symt : NULL;
|
||||
sym->type = type;
|
||||
sym->u.address = addr;
|
||||
if (type && size && symt_get_info(type, TI_GET_LENGTH, &tsz))
|
||||
{
|
||||
if (tsz != size)
|
||||
FIXME("Size mismatch for %s.%s between type (%lu) and src (%lu)\n",
|
||||
module->module.ModuleName, name, tsz, size);
|
||||
}
|
||||
if (compiland)
|
||||
{
|
||||
p = vector_add(&compiland->vchildren, &module->pool);
|
||||
|
@ -230,10 +237,9 @@ struct symt_function* symt_new_function(struct module* module,
|
|||
hash_table_add(&module->ht_symbols, &sym->hash_elt);
|
||||
module->sortlist_valid = FALSE;
|
||||
sym->container = &compiland->symt;
|
||||
sym->addr = addr;
|
||||
sym->address = addr;
|
||||
sym->type = sig_type;
|
||||
sym->size = size;
|
||||
sym->addr = addr;
|
||||
vector_init(&sym->vlines, sizeof(struct line_info), 64);
|
||||
vector_init(&sym->vchildren, sizeof(struct symt*), 8);
|
||||
if (compiland)
|
||||
|
@ -282,7 +288,7 @@ void symt_add_func_line(struct module* module, struct symt_function* func,
|
|||
dli->is_source_file = 0;
|
||||
dli->is_first = dli->is_last = 0;
|
||||
dli->line_number = line_num;
|
||||
dli->u.pc_offset = func->addr + offset;
|
||||
dli->u.pc_offset = func->address + offset;
|
||||
}
|
||||
|
||||
struct symt_data* symt_add_func_local(struct module* module,
|
||||
|
@ -341,7 +347,7 @@ struct symt_block* symt_open_func_block(struct module* module,
|
|||
assert(!parent_block || parent_block->symt.tag == SymTagBlock);
|
||||
block = pool_alloc(&module->pool, sizeof(*block));
|
||||
block->symt.tag = SymTagBlock;
|
||||
block->address = func->addr + pc;
|
||||
block->address = func->address + pc;
|
||||
block->size = len;
|
||||
block->container = parent_block ? &parent_block->symt : &func->symt;
|
||||
vector_init(&block->vchildren, sizeof(struct symt*), 4);
|
||||
|
@ -360,7 +366,7 @@ struct symt_block* symt_close_func_block(struct module* module,
|
|||
{
|
||||
assert(func->symt.tag == SymTagFunction);
|
||||
|
||||
if (pc) block->size = func->addr + pc - block->address;
|
||||
if (pc) block->size = func->address + pc - block->address;
|
||||
return (block->container->tag == SymTagBlock) ?
|
||||
GET_ENTRY(block->container, struct symt_block, symt) : NULL;
|
||||
}
|
||||
|
@ -408,6 +414,37 @@ BOOL symt_normalize_function(struct module* module, struct symt_function* func)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
struct symt_thunk* symt_new_thunk(struct module* module,
|
||||
struct symt_compiland* compiland,
|
||||
const char* name, THUNK_ORDINAL ord,
|
||||
unsigned long addr, unsigned long size)
|
||||
{
|
||||
struct symt_thunk* sym;
|
||||
|
||||
|
||||
TRACE_(dbghelp_symt)("Adding global thunk %s:%s @%lx-%lx\n",
|
||||
module->module.ModuleName, name, addr, addr + size - 1);
|
||||
|
||||
if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
|
||||
{
|
||||
sym->symt.tag = SymTagThunk;
|
||||
sym->hash_elt.name = pool_strdup(&module->pool, name);
|
||||
hash_table_add(&module->ht_symbols, &sym->hash_elt);
|
||||
module->sortlist_valid = FALSE;
|
||||
sym->container = &compiland->symt;
|
||||
sym->address = addr;
|
||||
sym->size = size;
|
||||
sym->ordinal = ord;
|
||||
if (compiland)
|
||||
{
|
||||
struct symt** p;
|
||||
p = vector_add(&compiland->vchildren, &module->pool);
|
||||
*p = &sym->symt;
|
||||
}
|
||||
}
|
||||
return sym;
|
||||
}
|
||||
|
||||
/* expect sym_info->MaxNameLen to be set before being called */
|
||||
static void symt_fill_sym_info(const struct module* module,
|
||||
const struct symt* sym, SYMBOL_INFO* sym_info)
|
||||
|
@ -423,7 +460,7 @@ static void symt_fill_sym_info(const struct module* module,
|
|||
{
|
||||
case SymTagData:
|
||||
{
|
||||
struct symt_data* data = (struct symt_data*)sym;
|
||||
const struct symt_data* data = (const struct symt_data*)sym;
|
||||
switch (data->kind)
|
||||
{
|
||||
case DataIsLocal:
|
||||
|
@ -476,6 +513,10 @@ static void symt_fill_sym_info(const struct module* module,
|
|||
sym_info->Flags |= SYMFLAG_FUNCTION;
|
||||
symt_get_info(sym, TI_GET_ADDRESS, &sym_info->Address);
|
||||
break;
|
||||
case SymTagThunk:
|
||||
sym_info->Flags |= SYMFLAG_THUNK;
|
||||
symt_get_info(sym, TI_GET_ADDRESS, &sym_info->Address);
|
||||
break;
|
||||
default:
|
||||
symt_get_info(sym, TI_GET_ADDRESS, &sym_info->Address);
|
||||
sym_info->Register = 0;
|
||||
|
@ -571,9 +612,10 @@ static BOOL resort_symbols(struct module* module)
|
|||
}
|
||||
|
||||
/* assume addr is in module */
|
||||
static int symt_find_nearest(struct module* module, DWORD addr)
|
||||
int symt_find_nearest(struct module* module, DWORD addr)
|
||||
{
|
||||
int mid, high, low;
|
||||
DWORD ref;
|
||||
|
||||
if (!module->sortlist_valid && !resort_symbols(module)) return -1;
|
||||
|
||||
|
@ -582,6 +624,15 @@ static int symt_find_nearest(struct module* module, DWORD addr)
|
|||
*/
|
||||
low = 0;
|
||||
high = module->module.NumSyms;
|
||||
|
||||
symt_get_info(&module->addr_sorttab[0]->symt, TI_GET_ADDRESS, &ref);
|
||||
if (addr < ref) return -1;
|
||||
if (high)
|
||||
{
|
||||
symt_get_info(&module->addr_sorttab[high - 1]->symt, TI_GET_ADDRESS, &ref);
|
||||
/* FIXME: use the size of symbol here if known */
|
||||
if (addr > ref + 0x1000) return -1;
|
||||
}
|
||||
|
||||
while (high > low + 1)
|
||||
{
|
||||
|
@ -600,8 +651,6 @@ static int symt_find_nearest(struct module* module, DWORD addr)
|
|||
*/
|
||||
if (module->addr_sorttab[low]->symt.tag == SymTagPublicSymbol)
|
||||
{
|
||||
DWORD ref;
|
||||
|
||||
symt_get_info(&module->addr_sorttab[low]->symt, TI_GET_ADDRESS, &ref);
|
||||
if (low > 0 &&
|
||||
module->addr_sorttab[low - 1]->symt.tag != SymTagPublicSymbol &&
|
||||
|
|
|
@ -80,15 +80,16 @@ const char* symt_get_name(const struct symt* sym)
|
|||
switch (sym->tag)
|
||||
{
|
||||
/* lexical tree */
|
||||
case SymTagData: return ((struct symt_data*)sym)->hash_elt.name;
|
||||
case SymTagFunction: return ((struct symt_function*)sym)->hash_elt.name;
|
||||
case SymTagPublicSymbol: return ((struct symt_public*)sym)->hash_elt.name;
|
||||
case SymTagBaseType: return ((struct symt_basic*)sym)->hash_elt.name;
|
||||
case SymTagLabel: return ((struct symt_function_point*)sym)->name;
|
||||
case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
|
||||
case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
|
||||
case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
|
||||
case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
|
||||
case SymTagLabel: return ((const struct symt_function_point*)sym)->name;
|
||||
case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
|
||||
/* hierarchy tree */
|
||||
case SymTagEnum: return ((struct symt_enum*)sym)->name;
|
||||
case SymTagTypedef: return ((struct symt_typedef*)sym)->hash_elt.name;
|
||||
case SymTagUDT: return ((struct symt_udt*)sym)->hash_elt.name;
|
||||
case SymTagEnum: return ((const struct symt_enum*)sym)->name;
|
||||
case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name;
|
||||
case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
|
||||
/* fall through */
|
||||
|
@ -417,10 +418,10 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
|
||||
switch (type->tag)
|
||||
{
|
||||
case SymTagUDT: v = &((struct symt_udt*)type)->vchildren; break;
|
||||
case SymTagEnum: v = &((struct symt_enum*)type)->vchildren; break;
|
||||
case SymTagFunctionType: v = &((struct symt_function_signature*)type)->vchildren; break;
|
||||
case SymTagFunction: v = &((struct symt_function*)type)->vchildren; break;
|
||||
case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break;
|
||||
case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
|
||||
case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
|
||||
case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for find-children\n",
|
||||
symt_get_tag_str(type->tag));
|
||||
|
@ -438,26 +439,29 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
switch (type->tag)
|
||||
{
|
||||
case SymTagData:
|
||||
switch (((struct symt_data*)type)->kind)
|
||||
switch (((const struct symt_data*)type)->kind)
|
||||
{
|
||||
case DataIsGlobal:
|
||||
case DataIsFileStatic:
|
||||
X(DWORD) = ((struct symt_data*)type)->u.address;
|
||||
X(DWORD) = ((const struct symt_data*)type)->u.address;
|
||||
break;
|
||||
default: return FALSE;
|
||||
}
|
||||
break;
|
||||
case SymTagFunction:
|
||||
X(DWORD) = ((struct symt_function*)type)->addr;
|
||||
X(DWORD) = ((const struct symt_function*)type)->address;
|
||||
break;
|
||||
case SymTagPublicSymbol:
|
||||
X(DWORD) = ((struct symt_public*)type)->address;
|
||||
X(DWORD) = ((const struct symt_public*)type)->address;
|
||||
break;
|
||||
case SymTagFuncDebugStart:
|
||||
case SymTagFuncDebugEnd:
|
||||
case SymTagLabel:
|
||||
X(DWORD) = ((struct symt_function_point*)type)->parent->addr +
|
||||
((struct symt_function_point*)type)->offset;
|
||||
X(DWORD) = ((const struct symt_function_point*)type)->parent->address +
|
||||
((const struct symt_function_point*)type)->offset;
|
||||
break;
|
||||
case SymTagThunk:
|
||||
X(DWORD) = ((const struct symt_thunk*)type)->address;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for get-address\n",
|
||||
|
@ -470,7 +474,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
switch (type->tag)
|
||||
{
|
||||
case SymTagBaseType:
|
||||
X(DWORD) = ((struct symt_basic*)type)->bt;
|
||||
X(DWORD) = ((const struct symt_basic*)type)->bt;
|
||||
break;
|
||||
case SymTagEnum:
|
||||
X(DWORD) = btInt;
|
||||
|
@ -482,29 +486,30 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
|
||||
case TI_GET_BITPOSITION:
|
||||
if (type->tag != SymTagData ||
|
||||
((struct symt_data*)type)->kind != DataIsMember ||
|
||||
((struct symt_data*)type)->u.s.length == 0)
|
||||
((const struct symt_data*)type)->kind != DataIsMember ||
|
||||
((const struct symt_data*)type)->u.s.length == 0)
|
||||
return FALSE;
|
||||
X(DWORD) = ((struct symt_data*)type)->u.s.offset & 7;
|
||||
X(DWORD) = ((const struct symt_data*)type)->u.s.offset & 7;
|
||||
break;
|
||||
|
||||
case TI_GET_CHILDRENCOUNT:
|
||||
switch (type->tag)
|
||||
{
|
||||
case SymTagUDT:
|
||||
X(DWORD) = vector_length(&((struct symt_udt*)type)->vchildren);
|
||||
X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren);
|
||||
break;
|
||||
case SymTagEnum:
|
||||
X(DWORD) = vector_length(&((struct symt_enum*)type)->vchildren);
|
||||
X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren);
|
||||
break;
|
||||
case SymTagFunctionType:
|
||||
X(DWORD) = vector_length(&((struct symt_function_signature*)type)->vchildren);
|
||||
X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
|
||||
break;
|
||||
case SymTagFunction:
|
||||
X(DWORD) = vector_length(&((struct symt_function*)type)->vchildren);
|
||||
X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
|
||||
break;
|
||||
case SymTagPointerType: /* MS does it that way */
|
||||
case SymTagArrayType: /* MS does it that way */
|
||||
case SymTagThunk: /* MS does it that way */
|
||||
X(DWORD) = 0;
|
||||
break;
|
||||
default:
|
||||
|
@ -524,51 +529,54 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
* also include 'this' (GET_CHILDREN_COUNT+1)
|
||||
*/
|
||||
if (type->tag != SymTagArrayType) return FALSE;
|
||||
X(DWORD) = ((struct symt_array*)type)->end -
|
||||
((struct symt_array*)type)->start;
|
||||
X(DWORD) = ((const struct symt_array*)type)->end -
|
||||
((const struct symt_array*)type)->start + 1;
|
||||
break;
|
||||
|
||||
case TI_GET_DATAKIND:
|
||||
if (type->tag != SymTagData) return FALSE;
|
||||
X(DWORD) = ((struct symt_data*)type)->kind;
|
||||
X(DWORD) = ((const struct symt_data*)type)->kind;
|
||||
break;
|
||||
|
||||
case TI_GET_LENGTH:
|
||||
switch (type->tag)
|
||||
{
|
||||
case SymTagBaseType:
|
||||
X(DWORD) = ((struct symt_basic*)type)->size;
|
||||
X(DWORD) = ((const struct symt_basic*)type)->size;
|
||||
break;
|
||||
case SymTagFunction:
|
||||
X(DWORD) = ((struct symt_function*)type)->size;
|
||||
X(DWORD) = ((const struct symt_function*)type)->size;
|
||||
break;
|
||||
case SymTagPointerType:
|
||||
X(DWORD) = sizeof(void*);
|
||||
break;
|
||||
case SymTagUDT:
|
||||
X(DWORD) = ((struct symt_udt*)type)->size;
|
||||
X(DWORD) = ((const struct symt_udt*)type)->size;
|
||||
break;
|
||||
case SymTagEnum:
|
||||
X(DWORD) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
|
||||
break;
|
||||
case SymTagData:
|
||||
if (((struct symt_data*)type)->kind != DataIsMember ||
|
||||
!((struct symt_data*)type)->u.s.length)
|
||||
if (((const struct symt_data*)type)->kind != DataIsMember ||
|
||||
!((const struct symt_data*)type)->u.s.length)
|
||||
return FALSE;
|
||||
X(DWORD) = ((struct symt_data*)type)->u.s.length;
|
||||
X(DWORD) = ((const struct symt_data*)type)->u.s.length;
|
||||
break;
|
||||
case SymTagArrayType:
|
||||
if (!symt_get_info(((struct symt_array*)type)->basetype,
|
||||
if (!symt_get_info(((const struct symt_array*)type)->basetype,
|
||||
TI_GET_LENGTH, pInfo))
|
||||
return FALSE;
|
||||
X(DWORD) *= ((struct symt_array*)type)->end -
|
||||
((struct symt_array*)type)->start;
|
||||
X(DWORD) *= ((const struct symt_array*)type)->end -
|
||||
((const struct symt_array*)type)->start + 1;
|
||||
break;
|
||||
case SymTagPublicSymbol:
|
||||
X(DWORD) = ((struct symt_public*)type)->size;
|
||||
X(DWORD) = ((const struct symt_public*)type)->size;
|
||||
break;
|
||||
case SymTagTypedef:
|
||||
return symt_get_info(((struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
|
||||
return symt_get_info(((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
|
||||
break;
|
||||
case SymTagThunk:
|
||||
X(DWORD) = ((const struct symt_thunk*)type)->size;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for get-length\n",
|
||||
|
@ -581,10 +589,16 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
switch (type->tag)
|
||||
{
|
||||
case SymTagBlock:
|
||||
X(DWORD) = (DWORD)((struct symt_block*)type)->container;
|
||||
X(DWORD) = (DWORD)((const struct symt_block*)type)->container;
|
||||
break;
|
||||
case SymTagData:
|
||||
X(DWORD) = (DWORD)((struct symt_data*)type)->container;
|
||||
X(DWORD) = (DWORD)((const struct symt_data*)type)->container;
|
||||
break;
|
||||
case SymTagFunction:
|
||||
X(DWORD) = (DWORD)((const struct symt_function*)type)->container;
|
||||
break;
|
||||
case SymTagThunk:
|
||||
X(DWORD) = (DWORD)((const struct symt_thunk*)type)->container;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
|
||||
|
@ -609,16 +623,16 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
switch (type->tag)
|
||||
{
|
||||
case SymTagData:
|
||||
switch (((struct symt_data*)type)->kind)
|
||||
switch (((const struct symt_data*)type)->kind)
|
||||
{
|
||||
case DataIsParam:
|
||||
case DataIsLocal:
|
||||
case DataIsMember:
|
||||
X(ULONG) = ((struct symt_data*)type)->u.s.offset >> 3;
|
||||
X(ULONG) = ((const struct symt_data*)type)->u.s.offset >> 3;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown kind (%u) for get-offset\n",
|
||||
((struct symt_data*)type)->kind);
|
||||
((const struct symt_data*)type)->kind);
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
@ -650,41 +664,42 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
|
|||
{
|
||||
/* hierarchical => hierarchical */
|
||||
case SymTagArrayType:
|
||||
X(DWORD) = (DWORD)((struct symt_array*)type)->basetype;
|
||||
X(DWORD) = (DWORD)((const struct symt_array*)type)->basetype;
|
||||
break;
|
||||
case SymTagPointerType:
|
||||
X(DWORD) = (DWORD)((struct symt_pointer*)type)->pointsto;
|
||||
X(DWORD) = (DWORD)((const struct symt_pointer*)type)->pointsto;
|
||||
break;
|
||||
case SymTagFunctionType:
|
||||
X(DWORD) = (DWORD)((struct symt_function_signature*)type)->rettype;
|
||||
X(DWORD) = (DWORD)((const struct symt_function_signature*)type)->rettype;
|
||||
break;
|
||||
case SymTagTypedef:
|
||||
X(DWORD) = (DWORD)((struct symt_typedef*)type)->type;
|
||||
X(DWORD) = (DWORD)((const struct symt_typedef*)type)->type;
|
||||
break;
|
||||
/* lexical => hierarchical */
|
||||
case SymTagData:
|
||||
X(DWORD) = (DWORD)((struct symt_data*)type)->type;
|
||||
X(DWORD) = (DWORD)((const struct symt_data*)type)->type;
|
||||
break;
|
||||
case SymTagFunction:
|
||||
X(DWORD) = (DWORD)((struct symt_function*)type)->type;
|
||||
X(DWORD) = (DWORD)((const struct symt_function*)type)->type;
|
||||
break;
|
||||
/* FIXME: should also work for enums and FunctionArgType */
|
||||
default:
|
||||
FIXME("Unsupported sym-tag %s for get-type\n",
|
||||
symt_get_tag_str(type->tag));
|
||||
case SymTagThunk:
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TI_GET_UDTKIND:
|
||||
if (type->tag != SymTagUDT) return FALSE;
|
||||
X(DWORD) = ((struct symt_udt*)type)->kind;
|
||||
X(DWORD) = ((const struct symt_udt*)type)->kind;
|
||||
break;
|
||||
|
||||
case TI_GET_VALUE:
|
||||
if (type->tag != SymTagData || ((struct symt_data*)type)->kind != DataIsConstant)
|
||||
if (type->tag != SymTagData || ((const struct symt_data*)type)->kind != DataIsConstant)
|
||||
return FALSE;
|
||||
X(VARIANT) = ((struct symt_data*)type)->u.value;
|
||||
X(VARIANT) = ((const struct symt_data*)type)->u.value;
|
||||
break;
|
||||
|
||||
#undef X
|
||||
|
|
|
@ -421,3 +421,12 @@ enum CV_HREG_e
|
|||
CV_M32R_ACLO = 33,
|
||||
CV_M32R_PC = 34,
|
||||
} CV_HREG_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
THUNK_ORDINAL_NOTYPE,
|
||||
THUNK_ORDINAL_ADJUSTOR,
|
||||
THUNK_ORDINAL_VCALL,
|
||||
THUNK_ORDINAL_PCODE,
|
||||
THUNK_ORDINAL_LOAD
|
||||
} THUNK_ORDINAL;
|
||||
|
|
|
@ -72,6 +72,9 @@ typedef struct _tagADDRESS
|
|||
#define SYMF_EXPORT 0x00000200
|
||||
#define SYMF_FORWARDER 0x00000400
|
||||
#define SYMF_FUNCTION 0x00000800
|
||||
#define SYMF_VIRTUAL 0x00001000
|
||||
#define SYMF_THUNK 0x00002000
|
||||
#define SYMF_TLSREL 0x00004000
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -529,6 +532,11 @@ typedef struct _MINIDUMP_THREAD_LIST
|
|||
MINIDUMP_THREAD Threads[1]; /* FIXME: no support of 0 sized array */
|
||||
} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST;
|
||||
|
||||
BOOL WINAPI MiniDumpWriteDump(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,const PMINIDUMP_EXCEPTION_INFORMATION,
|
||||
const PMINIDUMP_USER_STREAM_INFORMATION,const PMINIDUMP_CALLBACK_INFORMATION);
|
||||
BOOL WINAPI MiniDumpReadDumpStream(PVOID,ULONG,PMINIDUMP_DIRECTORY*,PVOID*,ULONG*);
|
||||
|
||||
|
||||
/*************************
|
||||
* MODULE handling *
|
||||
*************************/
|
||||
|
@ -586,7 +594,7 @@ typedef struct _SYMBOL_INFO
|
|||
ULONG SizeOfStruct;
|
||||
ULONG TypeIndex;
|
||||
ULONG Reserved[2];
|
||||
ULONG info;
|
||||
ULONG info; /* sdk states info, while MSDN says it's Index... */
|
||||
ULONG Size;
|
||||
ULONG ModBase;
|
||||
ULONG Flags;
|
||||
|
@ -666,8 +674,12 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, DWORD BaseOfDll,
|
|||
BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD addr, DWORD* displacement,
|
||||
SYMBOL_INFO* sym_info);
|
||||
BOOL WINAPI SymFromName(HANDLE hProcess, LPSTR Name, PSYMBOL_INFO Symbol);
|
||||
BOOL WINAPI SymGetSymFromAddr(HANDLE,DWORD,PDWORD,PIMAGEHLP_SYMBOL);
|
||||
BOOL WINAPI SymGetSymFromName(HANDLE,PSTR,PIMAGEHLP_SYMBOL);
|
||||
BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, DWORD BaseOfDll, LPSTR Name,
|
||||
PSYMBOL_INFO Symbol);
|
||||
BOOL WINAPI SymGetSymNext(HANDLE,PIMAGEHLP_SYMBOL);
|
||||
BOOL WINAPI SymGetSymPrev(HANDLE,PIMAGEHLP_SYMBOL);
|
||||
BOOL WINAPI SymEnumSymbols(HANDLE hProcess, ULONG BaseOfDll, PCSTR Mask,
|
||||
PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
|
||||
PVOID UserContext);
|
||||
|
@ -681,6 +693,7 @@ typedef BOOL (CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(HANDLE hProcess, ULONG Acti
|
|||
BOOL WINAPI SymRegisterCallback(HANDLE hProcess,
|
||||
PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
|
||||
PVOID UserContext);
|
||||
BOOL WINAPI SymUnDName(PIMAGEHLP_SYMBOL,PSTR,DWORD);
|
||||
DWORD WINAPI UnDecorateSymbolName(LPCSTR DecoratedName, LPSTR UnDecoratedName,
|
||||
DWORD UndecoratedLength, DWORD Flags);
|
||||
|
||||
|
@ -731,6 +744,11 @@ PIMAGE_SECTION_HEADER WINAPI ImageRvaToSection(PIMAGE_NT_HEADERS NtHeaders,
|
|||
PVOID Base, ULONG Rva);
|
||||
PVOID WINAPI ImageRvaToVa(PIMAGE_NT_HEADERS NtHeaders, PVOID Base,
|
||||
ULONG Rva, OUT PIMAGE_SECTION_HEADER *LastRvaSection);
|
||||
BOOL WINAPI SymGetSearchPath(HANDLE,PSTR,DWORD);
|
||||
BOOL WINAPI SymSetSearchPath(HANDLE,PSTR);
|
||||
DWORD WINAPI GetTimestampForLoadedLibrary(HMODULE);
|
||||
BOOL WINAPI MakeSureDirectoryPathExists(PCSTR);
|
||||
BOOL WINAPI SearchTreeForFile(PSTR,PSTR,PSTR);
|
||||
|
||||
/*************************
|
||||
* Context management *
|
||||
|
|
Loading…
Reference in New Issue