Enhanced ELF files lookup for symbolic info.
This commit is contained in:
parent
7c7e3ba5b2
commit
9454801cd9
|
@ -405,7 +405,6 @@ extern int DEBUG_GetCurrentFrame(struct name_hash ** name,
|
|||
|
||||
/* debugger/stabs.c */
|
||||
extern int DEBUG_ReadExecutableDbgInfo(const char* exe_name);
|
||||
extern int DEBUG_ProcessElfObject(const char* filename, unsigned int load_offset);
|
||||
extern int DEBUG_ParseStabs(char * addr, unsigned int load_offset, unsigned int staboff,
|
||||
int stablen, unsigned int strtaboff, int strtablen);
|
||||
|
||||
|
|
140
debugger/stabs.c
140
debugger/stabs.c
|
@ -1179,10 +1179,19 @@ DEBUG_ProcessElfSymtab(char * addr, unsigned int load_offset,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
||||
/*
|
||||
* Loads the symbolic information from ELF module stored in 'filename'
|
||||
* the module has been loaded at 'load_offset' address, so symbols' address
|
||||
* relocation is performed
|
||||
* returns
|
||||
* -1 if the file cannot be found/opened
|
||||
* 0 if the file doesn't contain symbolic info (or this info cannot be
|
||||
* read or parsed)
|
||||
* 1 on success
|
||||
*/
|
||||
static int DEBUG_ProcessElfFile(const char * filename, unsigned int load_offset)
|
||||
{
|
||||
int rtn = FALSE;
|
||||
int rtn = -1;
|
||||
char * addr = (char*)0xffffffff;
|
||||
int fd = -1;
|
||||
struct stat statbuf;
|
||||
|
@ -1194,57 +1203,20 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
|||
int stabsect;
|
||||
int stabstrsect;
|
||||
|
||||
/*
|
||||
* Make sure we can stat and open this file.
|
||||
*/
|
||||
if( filename == NULL )
|
||||
goto leave;
|
||||
|
||||
if (stat(filename, &statbuf) == -1)
|
||||
{
|
||||
char *s,*t,*fn,*paths;
|
||||
if (strchr(filename,'/'))
|
||||
goto leave;
|
||||
paths = DBG_strdup(getenv("PATH"));
|
||||
s = paths;
|
||||
while (s && *s) {
|
||||
t = strchr(s,':');
|
||||
if (t) *t='\0';
|
||||
fn = (char*)DBG_alloc(strlen(filename)+1+strlen(s)+1);
|
||||
strcpy(fn,s);
|
||||
strcat(fn,"/");
|
||||
strcat(fn,filename);
|
||||
if ((rtn = DEBUG_ProcessElfObject(fn,load_offset))) {
|
||||
DBG_free(fn);
|
||||
DBG_free(paths);
|
||||
goto leave;
|
||||
}
|
||||
DBG_free(fn);
|
||||
if (t) s = t+1; else break;
|
||||
}
|
||||
if (!s || !*s) DEBUG_Printf(DBG_CHN_MESG," not found");
|
||||
DBG_free(paths);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (DEBUG_FindModuleByName(filename, DM_TYPE_ELF))
|
||||
goto leave;
|
||||
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Loading stabs debug symbols from %s (0x%08x)\n",
|
||||
filename, load_offset);
|
||||
/* check that the file exists, and that the module hasn't been loaded yet */
|
||||
if (stat(filename, &statbuf) == -1) goto leave;
|
||||
|
||||
/*
|
||||
* Now open the file, so that we can mmap() it.
|
||||
*/
|
||||
if ((fd = open(filename, O_RDONLY)) == -1)
|
||||
goto leave;
|
||||
if ((fd = open(filename, O_RDONLY)) == -1) goto leave;
|
||||
|
||||
rtn = 0;
|
||||
/*
|
||||
* Now mmap() the file.
|
||||
*/
|
||||
addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (addr == (char*)0xffffffff)
|
||||
goto leave;
|
||||
if (addr == (char*)0xffffffff) goto leave;
|
||||
|
||||
/*
|
||||
* Next, we need to find a few of the internal ELF headers within
|
||||
|
@ -1253,10 +1225,7 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
|||
*/
|
||||
ehptr = (Elf32_Ehdr *) addr;
|
||||
|
||||
if( load_offset == 0 )
|
||||
DEBUG_RegisterELFModule(ehptr->e_entry, filename);
|
||||
else
|
||||
DEBUG_RegisterELFModule(load_offset, filename);
|
||||
DEBUG_RegisterELFModule((load_offset == 0) ? ehptr->e_entry : load_offset, filename);
|
||||
|
||||
spnt = (Elf32_Shdr *) (addr + ehptr->e_shoff);
|
||||
nsect = ehptr->e_shnum;
|
||||
|
@ -1264,8 +1233,7 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
|||
|
||||
stabsect = stabstrsect = -1;
|
||||
|
||||
for(i=0; i < nsect; i++)
|
||||
{
|
||||
for (i = 0; i < nsect; i++) {
|
||||
if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
|
||||
stabsect = i;
|
||||
|
||||
|
@ -1290,8 +1258,7 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
|||
goto leave;
|
||||
}
|
||||
|
||||
for(i=0; i < nsect; i++)
|
||||
{
|
||||
for (i = 0; i < nsect; i++) {
|
||||
if ( (strcmp(shstrtab + spnt[i].sh_name, ".symtab") == 0)
|
||||
&& (spnt[i].sh_type == SHT_SYMTAB))
|
||||
DEBUG_ProcessElfSymtab(addr, load_offset,
|
||||
|
@ -1304,15 +1271,68 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
|||
}
|
||||
|
||||
leave:
|
||||
|
||||
if (addr != (char*)0xffffffff)
|
||||
munmap(addr, statbuf.st_size);
|
||||
|
||||
if (addr != (char*)0xffffffff) munmap(addr, statbuf.st_size);
|
||||
if (fd != -1) close(fd);
|
||||
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static int DEBUG_ProcessElfFileFromPath(const char * filename,
|
||||
unsigned int load_offset, const char* path)
|
||||
{
|
||||
int rtn = FALSE;
|
||||
char *s, *t, *fn;
|
||||
char* paths = NULL;
|
||||
|
||||
for (s = paths = DBG_strdup(path); s && *s; s = (t) ? (t+1) : NULL) {
|
||||
t = strchr(s, ':');
|
||||
if (t) *t = '\0';
|
||||
fn = (char*)DBG_alloc(strlen(filename) + 1 + strlen(s) + 1);
|
||||
if (!fn) break;
|
||||
strcpy(fn, s );
|
||||
strcat(fn, "/");
|
||||
strcat(fn, filename);
|
||||
rtn = DEBUG_ProcessElfFile(fn, load_offset);
|
||||
DBG_free(fn);
|
||||
if (rtn >= 0) break;
|
||||
s = (t) ? (t+1) : NULL;
|
||||
}
|
||||
|
||||
DBG_free(paths);
|
||||
return rtn;
|
||||
}
|
||||
|
||||
static int DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
||||
{
|
||||
int rtn = -1;
|
||||
const char* fmt;
|
||||
|
||||
DEBUG_Printf(DBG_CHN_TRACE, "Processing elf file '%s'\n", filename);
|
||||
|
||||
if (filename == NULL) return FALSE;
|
||||
if (DEBUG_FindModuleByName(filename, DM_TYPE_ELF)) return TRUE;
|
||||
|
||||
rtn = DEBUG_ProcessElfFile(filename, load_offset);
|
||||
|
||||
/* if relative pathname, try some absolute base dirs */
|
||||
if (rtn < 0 && !strchr(filename, '/')) {
|
||||
rtn = DEBUG_ProcessElfFileFromPath(filename, load_offset, getenv("PATH"));
|
||||
if (rtn < 0)
|
||||
rtn = DEBUG_ProcessElfFileFromPath(filename, load_offset, getenv("LD_LIBRARY_PATH"));
|
||||
}
|
||||
|
||||
switch (rtn) {
|
||||
case 1: fmt = "Loaded stabs debug symbols from ELF '%s' (0x%08x)\n"; break;
|
||||
case 0: fmt = "No stabs debug symbols in ELF '%s' (0x%08x)\n"; break;
|
||||
case -1:fmt = "Can't find file for ELF '%s' (0x%08x)\n"; break;
|
||||
default: DEBUG_Printf(DBG_CHN_ERR, "Oooocch (%d)\n", rtn); return FALSE;
|
||||
}
|
||||
|
||||
DEBUG_Printf(DBG_CHN_MESG, fmt, filename, load_offset);
|
||||
|
||||
return rtn >= 0;
|
||||
}
|
||||
|
||||
static BOOL DEBUG_WalkList(struct r_debug* dbg_hdr)
|
||||
{
|
||||
u_long lm_addr;
|
||||
|
@ -1424,12 +1444,6 @@ leave:
|
|||
|
||||
#else /* !__ELF__ */
|
||||
|
||||
int
|
||||
DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
DEBUG_ReadExecutableDbgInfo(const char* exe_name)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<title>I Introduction</title>
|
||||
|
||||
<para>
|
||||
written by Eric Pouech (???) (Last updated: 6/14/2000)
|
||||
written by Eric Pouech (Last updated: 8/15/2000)
|
||||
</para>
|
||||
<para>
|
||||
(Extracted from <filename>wine/documentation/winedbg</filename>)
|
||||
|
@ -107,6 +107,12 @@
|
|||
use of this API to allow debugging both any Wine or WineLib
|
||||
applications as well as Wine itself (kernel and all DLLs).
|
||||
</para>
|
||||
<para>
|
||||
<command>WineDbg</command> understands symbolic information
|
||||
from both Unix world (mainly ELF stabs) and from Windows
|
||||
(most Microsoft debugging formats are supported - CodeView,
|
||||
.DBG files...)
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
|
@ -553,6 +559,18 @@ UseXTerm = 1
|
|||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>III.3 Finding files</title>
|
||||
|
||||
<para>
|
||||
WineDbg uses some lookup algorithms to find the files containing
|
||||
the debugging information. For ELF files, the current directory,
|
||||
the list of directories pointed by PATH, LD_LIBRARY_PATH are
|
||||
searched (in that order). For Microsoft debugging files,
|
||||
current directory, and directories pointed by _NT_SYMBOL_PATH and
|
||||
_NT_ALT_SYMBOL_PATH (in that order) are searched.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="dbg-commands">
|
||||
|
|
Loading…
Reference in New Issue