Commit 52c7534f authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Started handling of several symbols with the same name.

Fixed trampoline identification.
parent 36eed034
......@@ -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);
......
......@@ -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;
for(nh = name_hash_table[name_hash(name)]; nh; nh = nh->next)
struct name_hash* nh;
int i = 0;
DBG_ADDR addr;
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;
}
}
/*
* 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);
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);
}
/* 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;
......
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