Commit 48a86598 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- 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
parent d3f8f78c
......@@ -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);
......@@ -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
......@@ -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);
}
......
......@@ -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;
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);
......@@ -134,8 +134,8 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs,
const void* mapping, IMAGE_NT_HEADERS* nth)
{
SYM_TYPE sym_type = -1;
PIMAGE_DATA_DIRECTORY dir;
PIMAGE_DEBUG_DIRECTORY dbg = NULL;
const IMAGE_DATA_DIRECTORY* dir;
const IMAGE_DEBUG_DIRECTORY*dbg = NULL;
int nDbg;
/* Read in debug directory */
......@@ -143,14 +143,14 @@ static SYM_TYPE pe_load_msc_debug_info(const struct process* pcs,
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;
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 = (void*)((char*)mapping + dir->VirtualAddress);
functions = (void*)((char*)mapping + exports->AddressOfFunctions);
ordinals = (void*)((char*)mapping + exports->AddressOfNameOrdinals);
names = (void*)((char*)mapping + exports->AddressOfNames);
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,8 +244,7 @@ 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);
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
{
......
......@@ -289,9 +289,14 @@ 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);
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;
......@@ -583,6 +625,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)
{
mid = (high + low) / 2;
......@@ -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 &&
......
......@@ -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 *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment