Started handling of several symbols with the same name.
Fixed trampoline identification.
This commit is contained in:
parent
36eed034c9
commit
52c7534f41
|
@ -407,7 +407,7 @@ void DEBUG_AddBreakpointFromLineno(int lineno)
|
|||
DEBUG_AddBreakpoint( &value, NULL );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
/***********************************************************************
|
||||
* DEBUG_AddWatchpoint
|
||||
*
|
||||
* Add a watchpoint.
|
||||
|
@ -482,11 +482,11 @@ void DEBUG_AddWatchpoint( const DBG_VALUE *_value, BOOL is_write )
|
|||
*
|
||||
* Add a watchpoint from a symbol name (and eventually a line #)
|
||||
*/
|
||||
void DEBUG_AddWatchpointFromId(const char *name, int lineno)
|
||||
void DEBUG_AddWatchpointFromId(const char *name)
|
||||
{
|
||||
DBG_VALUE value;
|
||||
|
||||
if( DEBUG_GetSymbolValue(name, lineno, &value, TRUE) )
|
||||
if( DEBUG_GetSymbolValue(name, -1, &value, TRUE) )
|
||||
DEBUG_AddWatchpoint( &value, 1 );
|
||||
else
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Unable to add watchpoint\n");
|
||||
|
@ -876,7 +876,7 @@ enum exec_mode DEBUG_RestartExecution( enum exec_mode mode, int count )
|
|||
* FIXME - we need to check for things like thunks or trampolines,
|
||||
* as the actual function may in fact have debug info.
|
||||
*/
|
||||
if( ch == 0xe8 )
|
||||
if ( ch == 0xe8 )
|
||||
{
|
||||
DEBUG_READ_MEM((void*)(instr + 1), &delta, sizeof(delta));
|
||||
addr2 = addr;
|
||||
|
|
|
@ -202,7 +202,7 @@ break_command:
|
|||
|
||||
watch_command:
|
||||
tWATCH '*' expr_addr tEOL { DEBUG_AddWatchpoint( &$3, 1 ); DEBUG_FreeExprMem(); }
|
||||
| tWATCH tIDENTIFIER tEOL { DEBUG_AddWatchpointFromId($2, -1); }
|
||||
| tWATCH tIDENTIFIER tEOL { DEBUG_AddWatchpointFromId($2); }
|
||||
|
||||
info_command:
|
||||
tINFO tBREAK tEOL { DEBUG_InfoBreakpoints(); }
|
||||
|
|
|
@ -208,6 +208,7 @@ extern DBG_THREAD* DEBUG_CurrThread;
|
|||
extern DWORD DEBUG_CurrTid;
|
||||
extern DWORD DEBUG_CurrPid;
|
||||
extern CONTEXT DEBUG_context;
|
||||
extern BOOL DEBUG_interactiveP;
|
||||
|
||||
#define DEBUG_READ_MEM(addr, buf, len) \
|
||||
(ReadProcessMemory(DEBUG_CurrProcess->handle, (addr), (buf), (len), NULL))
|
||||
|
@ -230,7 +231,7 @@ typedef struct tagDBG_MODULE {
|
|||
char* module_name;
|
||||
enum DbgInfoLoad dil;
|
||||
enum DbgModuleType type;
|
||||
unsigned char main;
|
||||
unsigned short main : 1;
|
||||
short int dbg_index;
|
||||
HMODULE handle;
|
||||
struct tagMSC_DBG_INFO* msc_info;
|
||||
|
@ -255,7 +256,7 @@ extern void DEBUG_AddBreakpoint( const DBG_VALUE *addr, BOOL (*func)(void) );
|
|||
extern void DEBUG_AddBreakpointFromId( const char *name, int lineno );
|
||||
extern void DEBUG_AddBreakpointFromLineno( int lineno );
|
||||
extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );
|
||||
extern void DEBUG_AddWatchpointFromId( const char *name, int lineno );
|
||||
extern void DEBUG_AddWatchpointFromId( const char *name );
|
||||
extern void DEBUG_DelBreakpoint( int num );
|
||||
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
|
||||
extern void DEBUG_InfoBreakpoints(void);
|
||||
|
@ -314,8 +315,8 @@ extern struct name_hash * DEBUG_AddSymbol( const char *name,
|
|||
const DBG_VALUE *addr,
|
||||
const char *sourcefile,
|
||||
int flags);
|
||||
extern BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_VALUE *addr, int );
|
||||
extern int DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_VALUE *addr, int );
|
||||
extern BOOL DEBUG_SetSymbolValue( const char * name, const DBG_VALUE *addr );
|
||||
extern const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
||||
struct name_hash ** rtn,
|
||||
|
@ -390,6 +391,7 @@ extern DBG_MODULE* DEBUG_AddModule(const char* name, enum DbgModuleType type,
|
|||
void* mod_addr, u_long size, HMODULE hmod);
|
||||
extern DBG_MODULE* DEBUG_FindModuleByName(const char* name, enum DbgModuleType type);
|
||||
extern DBG_MODULE* DEBUG_FindModuleByHandle(HANDLE handle, enum DbgModuleType type);
|
||||
extern DBG_MODULE* DEBUG_FindModuleByAddr(void* addr, enum DbgModuleType type);
|
||||
extern DBG_MODULE* DEBUG_GetProcessMainModule(DBG_PROCESS* process);
|
||||
extern DBG_MODULE* DEBUG_RegisterPEModule(HMODULE, u_long load_addr, u_long size,
|
||||
const char* name);
|
||||
|
|
165
debugger/hash.c
165
debugger/hash.c
|
@ -181,14 +181,13 @@ DEBUG_ResortSymbols(void)
|
|||
* Add a symbol to the table.
|
||||
*/
|
||||
struct name_hash *
|
||||
DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
|
||||
int flags)
|
||||
DEBUG_AddSymbol( const char * name, const DBG_VALUE *value,
|
||||
const char * source, int flags)
|
||||
{
|
||||
struct name_hash * new;
|
||||
struct name_hash *nh;
|
||||
static char prev_source[PATH_MAX] = {'\0', };
|
||||
static char * prev_duped_source = NULL;
|
||||
char * c;
|
||||
int hash;
|
||||
|
||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||
|
@ -284,24 +283,17 @@ DEBUG_AddSymbol( const char * name, const DBG_VALUE *value, const char * source,
|
|||
* calling things and the GCC way of calling things. In general we
|
||||
* always want to step through.
|
||||
*/
|
||||
if( source != NULL )
|
||||
{
|
||||
c = strrchr(source, '.');
|
||||
if( c != NULL && strcmp(c, ".s") == 0 )
|
||||
{
|
||||
c = strrchr(source, '/');
|
||||
if( c != NULL )
|
||||
{
|
||||
c++;
|
||||
if( (strcmp(c, "callfrom16.s") == 0)
|
||||
|| (strcmp(c, "callto16.s") == 0)
|
||||
|| (strcmp(c, "call32.s") == 0) )
|
||||
{
|
||||
if ( source != NULL ) {
|
||||
int len = strlen(source);
|
||||
|
||||
if (len > 2 && source[len-2] == '.' && source[len-1] == 's') {
|
||||
char* c = strrchr(source - 2, '/');
|
||||
if (c != NULL) {
|
||||
if (strcmp(c + 1, "asmrelay.s") == 0)
|
||||
new->flags |= SYM_TRAMPOLINE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sortlist_valid = FALSE;
|
||||
return new;
|
||||
|
@ -341,52 +333,79 @@ BOOL DEBUG_Normalize(struct name_hash * nh )
|
|||
*
|
||||
* Get the address of a named symbol.
|
||||
*/
|
||||
BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_VALUE *value, int bp_flag )
|
||||
static int DEBUG_GSV_Helper(const char* name, const int lineno,
|
||||
DBG_VALUE* value, int num, int bp_flag)
|
||||
{
|
||||
struct name_hash *nh;
|
||||
struct name_hash* nh;
|
||||
int i = 0;
|
||||
DBG_ADDR addr;
|
||||
|
||||
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
|
||||
for (nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
|
||||
{
|
||||
if ((nh->flags & SYM_INVALID) != 0) continue;
|
||||
if (!strcmp(nh->name, name) && DEBUG_GetLineNumberAddr( nh, lineno, &addr, bp_flag ))
|
||||
{
|
||||
if( (nh->flags & SYM_INVALID) != 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(nh->name, name)) break;
|
||||
if (i >= num) return num + 1;
|
||||
value[i].addr = addr;
|
||||
value[i].type = nh->value.type;
|
||||
value[i].cookie = nh->value.cookie;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
if (!nh && (name[0] != '_'))
|
||||
{
|
||||
char buffer[256];
|
||||
BOOL DEBUG_GetSymbolValue( const char * name, const int lineno,
|
||||
DBG_VALUE *rtn, int bp_flag )
|
||||
{
|
||||
#define NUMDBGV 10
|
||||
/* FIXME: NUMDBGV should be made variable */
|
||||
DBG_VALUE value[NUMDBGV];
|
||||
DBG_VALUE vtmp;
|
||||
int num, i;
|
||||
|
||||
num = DEBUG_GSV_Helper(name, lineno, value, NUMDBGV, bp_flag);
|
||||
if (!num && (name[0] != '_'))
|
||||
{
|
||||
char buffer[256];
|
||||
|
||||
assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
|
||||
buffer[0] = '_';
|
||||
strcpy(buffer+1, name);
|
||||
for(nh = name_hash_table[name_hash(buffer)]; nh; nh = nh->next)
|
||||
{
|
||||
if( (nh->flags & SYM_INVALID) != 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(nh->name, buffer)) break;
|
||||
}
|
||||
}
|
||||
assert(strlen(name) < sizeof(buffer) - 2); /* one for '_', one for '\0' */
|
||||
buffer[0] = '_';
|
||||
strcpy(buffer + 1, name);
|
||||
num = DEBUG_GSV_Helper(buffer, lineno, value, NUMDBGV, bp_flag);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we don't have anything here, then try and see if this
|
||||
* is a local symbol to the current stack frame. No matter
|
||||
* what, we have nothing more to do, so we let that function
|
||||
* decide what we ultimately return.
|
||||
*/
|
||||
if (!nh)
|
||||
{
|
||||
return DEBUG_GetStackSymbolValue(name, value);
|
||||
/* now get the local symbols if any */
|
||||
if (DEBUG_GetStackSymbolValue(name, &vtmp) && num < NUMDBGV)
|
||||
{
|
||||
value[num] = vtmp;
|
||||
num++;
|
||||
}
|
||||
|
||||
if (num == 0) {
|
||||
return FALSE;
|
||||
} else if (!DEBUG_interactiveP || num == 1) {
|
||||
i = 0;
|
||||
} else {
|
||||
char* ptr;
|
||||
if (num == NUMDBGV+1) {
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Too many addresses for symbol '%s', limiting the first %d\n", name, NUMDBGV);
|
||||
num = NUMDBGV;
|
||||
}
|
||||
|
||||
value->type = nh->value.type;
|
||||
value->cookie = nh->value.cookie;
|
||||
return DEBUG_GetLineNumberAddr( nh, lineno, &value->addr, bp_flag );
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Many symbols with name '%s', choose the one you want (<cr> to abort):\n", name);
|
||||
for (i = 0; i < num; i++) {
|
||||
DEBUG_Printf(DBG_CHN_MESG, "[%d]: ", i + 1);
|
||||
DEBUG_PrintAddress( &value[i].addr, DEBUG_GetSelectorType(value[i].addr.seg), TRUE);
|
||||
DEBUG_Printf(DBG_CHN_MESG, "\n");
|
||||
}
|
||||
do {
|
||||
ptr = readline("=> ");
|
||||
if (!*ptr) return FALSE;
|
||||
i = atoi(ptr);
|
||||
} while (i < 0 || i >= num);
|
||||
}
|
||||
*rtn = value[i];
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -495,6 +514,8 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
|||
int i;
|
||||
char linebuff[16];
|
||||
unsigned val;
|
||||
DBG_MODULE* module;
|
||||
char modbuf[256];
|
||||
|
||||
if( rtn != NULL )
|
||||
{
|
||||
|
@ -666,6 +687,16 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
|||
}
|
||||
}
|
||||
|
||||
module = DEBUG_FindModuleByAddr((void*)DEBUG_ToLinear(addr), DMT_UNKNOWN);
|
||||
if (module) {
|
||||
char* ptr = strrchr(module->module_name, '/');
|
||||
|
||||
if (!ptr++) ptr = module->module_name;
|
||||
sprintf( modbuf, " in %s", ptr);
|
||||
}
|
||||
else
|
||||
modbuf[0] = '\0';
|
||||
|
||||
if( (nearest->sourcefile != NULL) && (flag == TRUE)
|
||||
&& (addr->off - nearest->value.addr.off < 0x100000) )
|
||||
{
|
||||
|
@ -702,25 +733,25 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
|||
sourcefile = strrchr( nearest->sourcefile, '/' );
|
||||
if (!sourcefile) sourcefile = nearest->sourcefile;
|
||||
else sourcefile++;
|
||||
|
||||
|
||||
if (addr->off == nearest->value.addr.off)
|
||||
sprintf( name_buffer, "%s%s [%s%s]", nearest->name,
|
||||
arglist, sourcefile, lineinfo);
|
||||
sprintf( name_buffer, "%s%s [%s%s]%s", nearest->name,
|
||||
arglist, sourcefile, lineinfo, modbuf);
|
||||
else
|
||||
sprintf( name_buffer, "%s+0x%lx%s [%s%s]", nearest->name,
|
||||
sprintf( name_buffer, "%s+0x%lx%s [%s%s]%s", nearest->name,
|
||||
addr->off - nearest->value.addr.off,
|
||||
arglist, sourcefile, lineinfo );
|
||||
arglist, sourcefile, lineinfo, modbuf );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr->off == nearest->value.addr.off)
|
||||
sprintf( name_buffer, "%s%s", nearest->name, arglist);
|
||||
sprintf( name_buffer, "%s%s%s", nearest->name, arglist, modbuf);
|
||||
else {
|
||||
if (addr->seg && (nearest->value.addr.seg!=addr->seg))
|
||||
return NULL;
|
||||
else
|
||||
sprintf( name_buffer, "%s+0x%lx%s", nearest->name,
|
||||
addr->off - nearest->value.addr.off, arglist);
|
||||
sprintf( name_buffer, "%s+0x%lx%s%s", nearest->name,
|
||||
addr->off - nearest->value.addr.off, arglist, modbuf);
|
||||
}
|
||||
}
|
||||
return name_buffer;
|
||||
|
@ -732,7 +763,7 @@ const char * DEBUG_FindNearestSymbol( const DBG_ADDR *addr, int flag,
|
|||
*
|
||||
* Read a symbol file into the hash table.
|
||||
*/
|
||||
void DEBUG_ReadSymbolTable( const char * filename )
|
||||
void DEBUG_ReadSymbolTable( const char* filename )
|
||||
{
|
||||
FILE * symbolfile;
|
||||
DBG_VALUE value;
|
||||
|
|
|
@ -76,10 +76,13 @@ DBG_MODULE* DEBUG_FindModuleByAddr(void* addr, enum DbgModuleType type)
|
|||
for (i = 0; i < DEBUG_CurrProcess->num_modules; i++) {
|
||||
if ((type == DMT_UNKNOWN || type == amod[i]->type) &&
|
||||
(u_long)addr >= (u_long)amod[i]->load_addr &&
|
||||
(!res || res->load_addr < amod[i]->load_addr))
|
||||
res = amod[i];
|
||||
(u_long)addr < (u_long)amod[i]->load_addr + (u_long)amod[i]->size) {
|
||||
/* amod[i] contains it... check against res now */
|
||||
if (!res || res->load_addr < amod[i]->load_addr)
|
||||
res = amod[i];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -367,7 +370,7 @@ enum DbgInfoLoad DEBUG_RegisterPEDebugInfo(DBG_MODULE* wmod, HANDLE hFile,
|
|||
((names = DBG_alloc(sizeof(names[0]) * exports.NumberOfNames))) &&
|
||||
DEBUG_READ_MEM_VERBOSE((void*)(base + (DWORD)exports.AddressOfNames),
|
||||
names, sizeof(names[0]) * exports.NumberOfNames)) {
|
||||
|
||||
|
||||
for (i = 0; i < exports.NumberOfNames; i++) {
|
||||
if (!names[i] ||
|
||||
!DEBUG_READ_MEM_VERBOSE((void*)(base + names[i]), bufstr, sizeof(bufstr)))
|
||||
|
|
|
@ -28,6 +28,7 @@ DBG_THREAD* DEBUG_CurrThread = NULL;
|
|||
DWORD DEBUG_CurrTid;
|
||||
DWORD DEBUG_CurrPid;
|
||||
CONTEXT DEBUG_context;
|
||||
BOOL DEBUG_interactiveP = FALSE;
|
||||
int curr_frame = 0;
|
||||
static char* DEBUG_LastCmdLine = NULL;
|
||||
|
||||
|
@ -44,7 +45,7 @@ void DEBUG_Output(int chn, const char* buffer, int len)
|
|||
|
||||
int DEBUG_Printf(int chn, const char* format, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
static char buf[4*1024];
|
||||
va_list valist;
|
||||
int len;
|
||||
|
||||
|
@ -499,6 +500,7 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL
|
|||
DEBUG_CurrThread->dbg_exec_mode, DEBUG_CurrThread->dbg_exec_count);
|
||||
|
||||
if (DEBUG_ExceptionProlog(is_debug, force, rec->ExceptionCode)) {
|
||||
DEBUG_interactiveP = TRUE;
|
||||
while ((ret = DEBUG_Parser())) {
|
||||
if (DEBUG_ValidateRegisters()) {
|
||||
if (DEBUG_CurrThread->dbg_exec_mode != EXEC_PASS || first_chance)
|
||||
|
@ -506,6 +508,7 @@ static BOOL DEBUG_HandleException(EXCEPTION_RECORD *rec, BOOL first_chance, BOOL
|
|||
DEBUG_Printf(DBG_CHN_MESG, "Cannot pass on last chance exception. You must use cont\n");
|
||||
}
|
||||
}
|
||||
DEBUG_interactiveP = FALSE;
|
||||
}
|
||||
*cont = DEBUG_ExceptionEpilog();
|
||||
|
||||
|
@ -861,7 +864,7 @@ int DEBUG_main(int argc, char** argv)
|
|||
}
|
||||
|
||||
DEBUG_Printf(DBG_CHN_MESG, "WineDbg starting... ");
|
||||
|
||||
|
||||
if (argc == 3) {
|
||||
HANDLE hEvent;
|
||||
DWORD pid;
|
||||
|
|
Loading…
Reference in New Issue