Skip to content
Snippets Groups Projects
Commit 9454801c authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard
Browse files

Enhanced ELF files lookup for symbolic info.

parent 7c7e3ba5
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
......@@ -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;
......@@ -1193,87 +1202,46 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
int i;
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
* this thing. We need the main executable header, and the section
* table.
*/
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;
shstrtab = (addr + spnt[ehptr->e_shstrndx].sh_offset);
stabsect = stabstrsect = -1;
for (i = 0; i < nsect; i++) {
if (strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0)
stabsect = i;
for(i=0; i < nsect; i++)
{
if( strcmp(shstrtab + spnt[i].sh_name, ".stab") == 0 )
stabsect = i;
if( strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0 )
stabstrsect = i;
}
if (strcmp(shstrtab + spnt[i].sh_name, ".stabstr") == 0)
stabstrsect = i;
}
if( stabsect == -1 || stabstrsect == -1 ) {
if (stabsect == -1 || stabstrsect == -1) {
DEBUG_Printf(DBG_CHN_WARN, "no .stab section\n");
goto leave;
}
......@@ -1290,29 +1258,81 @@ DEBUG_ProcessElfObject(const char * filename, unsigned int load_offset)
goto leave;
}
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,
spnt + i, spnt + spnt[i].sh_link);
if( (strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0)
&& (spnt[i].sh_type == SHT_DYNSYM) )
DEBUG_ProcessElfSymtab(addr, load_offset,
spnt + i, spnt + spnt[i].sh_link);
}
leave:
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,
spnt + i, spnt + spnt[i].sh_link);
if (addr != (char*)0xffffffff)
munmap(addr, statbuf.st_size);
if ( (strcmp(shstrtab + spnt[i].sh_name, ".dynsym") == 0)
&& (spnt[i].sh_type == SHT_DYNSYM))
DEBUG_ProcessElfSymtab(addr, load_offset,
spnt + i, spnt + spnt[i].sh_link);
}
leave:
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">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment