dbghelp: Read the stabs nlist entry corresponding to the target's architecture.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1dc9bb70cd
commit
7d441808ac
|
@ -676,7 +676,7 @@ typedef void (*stabs_def_cb)(struct module* module, unsigned long load_offset,
|
||||||
BOOL is_public, BOOL is_global, unsigned char other,
|
BOOL is_public, BOOL is_global, unsigned char other,
|
||||||
struct symt_compiland* compiland, void* user);
|
struct symt_compiland* compiland, void* user);
|
||||||
extern BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
extern BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
const void* stabs, int stablen,
|
const char* stabs, int stablen,
|
||||||
const char* strs, int strtablen,
|
const char* strs, int strtablen,
|
||||||
stabs_def_cb callback, void* user) DECLSPEC_HIDDEN;
|
stabs_def_cb callback, void* user) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -88,13 +88,6 @@ struct dyld_all_image_infos {
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);
|
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_macho);
|
||||||
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
typedef struct nlist_64 macho_nlist;
|
|
||||||
#else
|
|
||||||
typedef struct nlist macho_nlist;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Bitmask for Mach-O image header flags indicating that the image is in dyld's
|
/* Bitmask for Mach-O image header flags indicating that the image is in dyld's
|
||||||
shared cached. That implies that its segments are mapped non-contiguously.
|
shared cached. That implies that its segments are mapped non-contiguously.
|
||||||
This value isn't defined anywhere in headers. It's used in dyld and in
|
This value isn't defined anywhere in headers. It's used in dyld and in
|
||||||
|
@ -913,24 +906,25 @@ static int macho_parse_symtab(struct image_file_map* ifm,
|
||||||
struct macho_file_map* fmap = &ifm->u.macho;
|
struct macho_file_map* fmap = &ifm->u.macho;
|
||||||
const struct symtab_command* sc = (const struct symtab_command*)lc;
|
const struct symtab_command* sc = (const struct symtab_command*)lc;
|
||||||
struct macho_debug_info* mdi = user;
|
struct macho_debug_info* mdi = user;
|
||||||
const macho_nlist* stab;
|
|
||||||
const char* stabstr;
|
const char* stabstr;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
size_t stabsize = (ifm->addr_size == 32) ? sizeof(struct nlist) : sizeof(struct nlist_64);
|
||||||
|
const char *stab;
|
||||||
|
|
||||||
TRACE("(%p/%d, %p, %p) %u syms at 0x%08x, strings 0x%08x - 0x%08x\n", fmap, fmap->fd, lc,
|
TRACE("(%p/%d, %p, %p) %u syms at 0x%08x, strings 0x%08x - 0x%08x\n", fmap, fmap->fd, lc,
|
||||||
user, sc->nsyms, sc->symoff, sc->stroff, sc->stroff + sc->strsize);
|
user, sc->nsyms, sc->symoff, sc->stroff, sc->stroff + sc->strsize);
|
||||||
|
|
||||||
if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist),
|
if (!macho_map_ranges(fmap, sc->symoff, sc->nsyms * stabsize,
|
||||||
sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr))
|
sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!stabs_parse(mdi->module,
|
if (!stabs_parse(mdi->module,
|
||||||
mdi->module->format_info[DFI_MACHO]->u.macho_info->load_addr - fmap->segs_start,
|
mdi->module->format_info[DFI_MACHO]->u.macho_info->load_addr - fmap->segs_start,
|
||||||
stab, sc->nsyms * sizeof(macho_nlist),
|
stab, sc->nsyms * stabsize,
|
||||||
stabstr, sc->strsize, macho_stabs_def_cb, mdi))
|
stabstr, sc->strsize, macho_stabs_def_cb, mdi))
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * sizeof(macho_nlist),
|
macho_unmap_ranges(fmap, sc->symoff, sc->nsyms * stabsize,
|
||||||
sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr);
|
sc->stroff, sc->strsize, (const void**)&stab, (const void**)&stabstr);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
|
@ -111,11 +112,7 @@ struct stab_nlist
|
||||||
unsigned char n_type;
|
unsigned char n_type;
|
||||||
char n_other;
|
char n_other;
|
||||||
short n_desc;
|
short n_desc;
|
||||||
#if defined(__APPLE__) && defined(_WIN64)
|
|
||||||
unsigned long n_value;
|
|
||||||
#else
|
|
||||||
unsigned n_value;
|
unsigned n_value;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void stab_strcpy(char* dest, int sz, const char* source)
|
static void stab_strcpy(char* dest, int sz, const char* source)
|
||||||
|
@ -1265,7 +1262,7 @@ static inline void stabbuf_append(char **buf, unsigned *buf_size, const char *st
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
const void* pv_stab_ptr, int stablen,
|
const char* pv_stab_ptr, int stablen,
|
||||||
const char* strs, int strtablen,
|
const char* strs, int strtablen,
|
||||||
stabs_def_cb callback, void* user)
|
stabs_def_cb callback, void* user)
|
||||||
{
|
{
|
||||||
|
@ -1278,7 +1275,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
const char* ptr;
|
const char* ptr;
|
||||||
char* stabbuff;
|
char* stabbuff;
|
||||||
unsigned int stabbufflen;
|
unsigned int stabbufflen;
|
||||||
const struct stab_nlist* stab_ptr = pv_stab_ptr;
|
const struct stab_nlist* stab_ptr;
|
||||||
const char* strs_end;
|
const char* strs_end;
|
||||||
int strtabinc;
|
int strtabinc;
|
||||||
char symname[4096];
|
char symname[4096];
|
||||||
|
@ -1290,8 +1287,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
struct location loc;
|
struct location loc;
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
|
size_t stabsize = sizeof(struct stab_nlist);
|
||||||
|
uint64_t n_value;
|
||||||
|
|
||||||
nstab = stablen / sizeof(struct stab_nlist);
|
#ifdef __APPLE__
|
||||||
|
if (module->process->is_64bit)
|
||||||
|
stabsize = sizeof(struct nlist_64);
|
||||||
|
#endif
|
||||||
|
nstab = stablen / stabsize;
|
||||||
strs_end = strs + strtablen;
|
strs_end = strs + strtablen;
|
||||||
|
|
||||||
memset(stabs_basic, 0, sizeof(stabs_basic));
|
memset(stabs_basic, 0, sizeof(stabs_basic));
|
||||||
|
@ -1307,8 +1310,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
|
|
||||||
strtabinc = 0;
|
strtabinc = 0;
|
||||||
stabbuff[0] = '\0';
|
stabbuff[0] = '\0';
|
||||||
for (i = 0; i < nstab; i++, stab_ptr++)
|
for (i = 0; i < nstab; i++)
|
||||||
{
|
{
|
||||||
|
stab_ptr = (struct stab_nlist *)(pv_stab_ptr + i * stabsize);
|
||||||
|
n_value = stab_ptr->n_value;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (module->process->is_64bit)
|
||||||
|
n_value = ((struct nlist_64 *)stab_ptr)->n_value;
|
||||||
|
#endif
|
||||||
ptr = strs + stab_ptr->n_strx;
|
ptr = strs + stab_ptr->n_strx;
|
||||||
if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
|
if ((ptr > strs_end) || (ptr + strlen(ptr) > strs_end))
|
||||||
{
|
{
|
||||||
|
@ -1382,7 +1391,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
stab_strcpy(symname, sizeof(symname), ptr);
|
stab_strcpy(symname, sizeof(symname), ptr);
|
||||||
loc.kind = loc_absolute;
|
loc.kind = loc_absolute;
|
||||||
loc.reg = 0;
|
loc.reg = 0;
|
||||||
loc.offset = load_offset + stab_ptr->n_value;
|
loc.offset = load_offset + n_value;
|
||||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||||
loc, 0, stabs_parse_type(ptr));
|
loc, 0, stabs_parse_type(ptr));
|
||||||
break;
|
break;
|
||||||
|
@ -1392,7 +1401,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
stab_strcpy(symname, sizeof(symname), ptr);
|
stab_strcpy(symname, sizeof(symname), ptr);
|
||||||
loc.kind = loc_absolute;
|
loc.kind = loc_absolute;
|
||||||
loc.reg = 0;
|
loc.reg = 0;
|
||||||
loc.offset = load_offset + stab_ptr->n_value;
|
loc.offset = load_offset + n_value;
|
||||||
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
symt_new_global_variable(module, compiland, symname, TRUE /* FIXME */,
|
||||||
loc, 0, stabs_parse_type(ptr));
|
loc, 0, stabs_parse_type(ptr));
|
||||||
break;
|
break;
|
||||||
|
@ -1400,14 +1409,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
if (curr_func)
|
if (curr_func)
|
||||||
{
|
{
|
||||||
block = symt_open_func_block(module, curr_func, block,
|
block = symt_open_func_block(module, curr_func, block,
|
||||||
stab_ptr->n_value, 0);
|
n_value, 0);
|
||||||
pending_flush(&pending_block, module, curr_func, block);
|
pending_flush(&pending_block, module, curr_func, block);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case N_RBRAC:
|
case N_RBRAC:
|
||||||
if (curr_func)
|
if (curr_func)
|
||||||
block = symt_close_func_block(module, curr_func, block,
|
block = symt_close_func_block(module, curr_func, block,
|
||||||
stab_ptr->n_value);
|
n_value);
|
||||||
break;
|
break;
|
||||||
case N_PSYM:
|
case N_PSYM:
|
||||||
/* These are function parameters. */
|
/* These are function parameters. */
|
||||||
|
@ -1417,9 +1426,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
stab_strcpy(symname, sizeof(symname), ptr);
|
stab_strcpy(symname, sizeof(symname), ptr);
|
||||||
loc.kind = loc_regrel;
|
loc.kind = loc_regrel;
|
||||||
loc.reg = dbghelp_current_cpu->frame_regno;
|
loc.reg = dbghelp_current_cpu->frame_regno;
|
||||||
loc.offset = stab_ptr->n_value;
|
loc.offset = n_value;
|
||||||
symt_add_func_local(module, curr_func,
|
symt_add_func_local(module, curr_func,
|
||||||
(int)stab_ptr->n_value >= 0 ? DataIsParam : DataIsLocal,
|
(int)n_value >= 0 ? DataIsParam : DataIsLocal,
|
||||||
&loc, NULL, param_type, symname);
|
&loc, NULL, param_type, symname);
|
||||||
symt_add_function_signature_parameter(module,
|
symt_add_function_signature_parameter(module,
|
||||||
(struct symt_function_signature*)curr_func->type,
|
(struct symt_function_signature*)curr_func->type,
|
||||||
|
@ -1433,7 +1442,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
loc.kind = loc_register;
|
loc.kind = loc_register;
|
||||||
loc.offset = 0;
|
loc.offset = 0;
|
||||||
|
|
||||||
switch (stab_ptr->n_value)
|
switch (n_value)
|
||||||
{
|
{
|
||||||
case 0: loc.reg = CV_REG_EAX; break;
|
case 0: loc.reg = CV_REG_EAX; break;
|
||||||
case 1: loc.reg = CV_REG_ECX; break;
|
case 1: loc.reg = CV_REG_ECX; break;
|
||||||
|
@ -1451,7 +1460,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
case 16:
|
case 16:
|
||||||
case 17:
|
case 17:
|
||||||
case 18:
|
case 18:
|
||||||
case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
|
case 19: loc.reg = CV_REG_ST0 + n_value - 12; break;
|
||||||
case 21:
|
case 21:
|
||||||
case 22:
|
case 22:
|
||||||
case 23:
|
case 23:
|
||||||
|
@ -1459,7 +1468,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
case 25:
|
case 25:
|
||||||
case 26:
|
case 26:
|
||||||
case 27:
|
case 27:
|
||||||
case 28: loc.reg = CV_REG_XMM0 + stab_ptr->n_value - 21; break;
|
case 28: loc.reg = CV_REG_XMM0 + n_value - 21; break;
|
||||||
case 29:
|
case 29:
|
||||||
case 30:
|
case 30:
|
||||||
case 31:
|
case 31:
|
||||||
|
@ -1467,9 +1476,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
case 33:
|
case 33:
|
||||||
case 34:
|
case 34:
|
||||||
case 35:
|
case 35:
|
||||||
case 36: loc.reg = CV_REG_MM0 + stab_ptr->n_value - 29; break;
|
case 36: loc.reg = CV_REG_MM0 + n_value - 29; break;
|
||||||
default:
|
default:
|
||||||
FIXME("Unknown register value (%lu)\n", (unsigned long)stab_ptr->n_value);
|
FIXME("Unknown register value (%lu)\n", (unsigned long)n_value);
|
||||||
loc.reg = CV_REG_NONE;
|
loc.reg = CV_REG_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1492,7 +1501,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
/* These are local variables */
|
/* These are local variables */
|
||||||
loc.kind = loc_regrel;
|
loc.kind = loc_regrel;
|
||||||
loc.reg = dbghelp_current_cpu->frame_regno;
|
loc.reg = dbghelp_current_cpu->frame_regno;
|
||||||
loc.offset = stab_ptr->n_value;
|
loc.offset = n_value;
|
||||||
if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
|
if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
|
||||||
break;
|
break;
|
||||||
case N_SLINE:
|
case N_SLINE:
|
||||||
|
@ -1503,14 +1512,14 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
assert(source_idx >= 0);
|
assert(source_idx >= 0);
|
||||||
if (curr_func != NULL)
|
if (curr_func != NULL)
|
||||||
{
|
{
|
||||||
unsigned long offset = stab_ptr->n_value;
|
unsigned long offset = n_value;
|
||||||
if (module->type == DMT_MACHO)
|
if (module->type == DMT_MACHO)
|
||||||
offset -= curr_func->address - load_offset;
|
offset -= curr_func->address - load_offset;
|
||||||
symt_add_func_line(module, curr_func, source_idx,
|
symt_add_func_line(module, curr_func, source_idx,
|
||||||
stab_ptr->n_desc, offset);
|
stab_ptr->n_desc, offset);
|
||||||
}
|
}
|
||||||
else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc,
|
else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc,
|
||||||
stab_ptr->n_value, load_offset);
|
n_value, load_offset);
|
||||||
break;
|
break;
|
||||||
case N_FUN:
|
case N_FUN:
|
||||||
/*
|
/*
|
||||||
|
@ -1537,13 +1546,13 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
* and offset of last function
|
* and offset of last function
|
||||||
*/
|
*/
|
||||||
stabs_finalize_function(module, curr_func,
|
stabs_finalize_function(module, curr_func,
|
||||||
stab_ptr->n_value ?
|
n_value ?
|
||||||
(load_offset + stab_ptr->n_value - curr_func->address) : 0);
|
(load_offset + n_value - curr_func->address) : 0);
|
||||||
}
|
}
|
||||||
func_type = symt_new_function_signature(module,
|
func_type = symt_new_function_signature(module,
|
||||||
stabs_parse_type(ptr), -1);
|
stabs_parse_type(ptr), -1);
|
||||||
curr_func = symt_new_function(module, compiland, symname,
|
curr_func = symt_new_function(module, compiland, symname,
|
||||||
load_offset + stab_ptr->n_value, 0,
|
load_offset + n_value, 0,
|
||||||
&func_type->symt);
|
&func_type->symt);
|
||||||
pending_flush(&pending_func, module, curr_func, NULL);
|
pending_flush(&pending_func, module, curr_func, NULL);
|
||||||
}
|
}
|
||||||
|
@ -1552,7 +1561,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
/* some versions of GCC to use a N_FUN "" to mark the end of a function
|
/* some versions of GCC to use a N_FUN "" to mark the end of a function
|
||||||
* and n_value contains the size of the func
|
* and n_value contains the size of the func
|
||||||
*/
|
*/
|
||||||
stabs_finalize_function(module, curr_func, stab_ptr->n_value);
|
stabs_finalize_function(module, curr_func, n_value);
|
||||||
curr_func = NULL;
|
curr_func = NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1594,7 +1603,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
break;
|
break;
|
||||||
case N_UNDF:
|
case N_UNDF:
|
||||||
strs += strtabinc;
|
strs += strtabinc;
|
||||||
strtabinc = stab_ptr->n_value;
|
strtabinc = n_value;
|
||||||
/* I'm not sure this is needed, so trace it before we obsolete it */
|
/* I'm not sure this is needed, so trace it before we obsolete it */
|
||||||
if (curr_func)
|
if (curr_func)
|
||||||
{
|
{
|
||||||
|
@ -1607,7 +1616,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
/* Ignore this. We don't care what it points to. */
|
/* Ignore this. We don't care what it points to. */
|
||||||
break;
|
break;
|
||||||
case N_BINCL:
|
case N_BINCL:
|
||||||
stabs_add_include(stabs_new_include(ptr, stab_ptr->n_value));
|
stabs_add_include(stabs_new_include(ptr, n_value));
|
||||||
assert(incl_stk < (int)(sizeof(incl) / sizeof(incl[0])) - 1);
|
assert(incl_stk < (int)(sizeof(incl) / sizeof(incl[0])) - 1);
|
||||||
incl[++incl_stk] = source_idx;
|
incl[++incl_stk] = source_idx;
|
||||||
source_idx = source_new(module, NULL, ptr);
|
source_idx = source_new(module, NULL, ptr);
|
||||||
|
@ -1617,9 +1626,9 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
source_idx = incl[incl_stk--];
|
source_idx = incl[incl_stk--];
|
||||||
break;
|
break;
|
||||||
case N_EXCL:
|
case N_EXCL:
|
||||||
if (stabs_add_include(stabs_find_include(ptr, stab_ptr->n_value)) < 0)
|
if (stabs_add_include(stabs_find_include(ptr, n_value)) < 0)
|
||||||
{
|
{
|
||||||
ERR("Excluded header not found (%s,%ld)\n", ptr, (unsigned long)stab_ptr->n_value);
|
ERR("Excluded header not found (%s,%ld)\n", ptr, (unsigned long)n_value);
|
||||||
module_reset_debug_info(module);
|
module_reset_debug_info(module);
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -1656,7 +1665,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
if (*ptr == '_') ptr++;
|
if (*ptr == '_') ptr++;
|
||||||
stab_strcpy(symname, sizeof(symname), ptr);
|
stab_strcpy(symname, sizeof(symname), ptr);
|
||||||
|
|
||||||
callback(module, load_offset, symname, stab_ptr->n_value,
|
callback(module, load_offset, symname, n_value,
|
||||||
is_public, is_global, stab_ptr->n_other, compiland, user);
|
is_public, is_global, stab_ptr->n_other, compiland, user);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1666,7 +1675,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
|
||||||
}
|
}
|
||||||
stabbuff[0] = '\0';
|
stabbuff[0] = '\0';
|
||||||
TRACE("0x%02x %lx %s\n",
|
TRACE("0x%02x %lx %s\n",
|
||||||
stab_ptr->n_type, (unsigned long)stab_ptr->n_value, debugstr_a(strs + stab_ptr->n_strx));
|
stab_ptr->n_type, (unsigned long)n_value, debugstr_a(strs + stab_ptr->n_strx));
|
||||||
}
|
}
|
||||||
module->module.SymType = SymDia;
|
module->module.SymType = SymDia;
|
||||||
module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
|
module->module.CVSig = 'S' | ('T' << 8) | ('A' << 16) | ('B' << 24);
|
||||||
|
|
Loading…
Reference in New Issue