swig/Tools/WAD/Wad/stab.c
Dave Beazley 047feee80d *** empty log message ***
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@938 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2000-11-08 02:47:07 +00:00

163 lines
5 KiB
C

/* -----------------------------------------------------------------------------
* stab.c
*
* This file reads stabs data and looks for various properties of a
* given symbol.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
#include "wad.h"
/* stabs data structure. This appears to be somewhat universal. I ripped
it out of the Sun C compiler include directory */
typedef struct Stab {
unsigned n_strx; /* index into file string table */
unsigned char n_type; /* type flag (N_TEXT,..) */
char n_other; /* used by N_SLINE stab */
short n_desc; /* see stabs documentation */
unsigned n_value; /* value of symbol (or sdb offset) */
} Stab;
/* Match a stabs symbol name against a stab string (which may contain
extra information delimetered by a colon */
int match_stab_symbol(char *symbol, char *stabtext, int slen) {
/* printf("matching: %s -> %s\n", symbol, stabtext); */
if (strcmp(symbol,stabtext) == 0) {
return 1;
}
if ((strncmp(symbol, stabtext, slen) == 0) && (*(stabtext+slen) == ':')) return 1;
return 0;
}
/* Given a stabs data segment (obtained somehow), this function tries to
collect as much information as it can about a given symbol.
s points to the stab data. stabstr points to the stab string section,
ns is the size of the stab section, symbol is the item of interest,
and offset is the offset in the object file of the symbol
Note: this function may recurse upon itself if there are multiple
stabs sections
*/
static WadDebug debug;
WadDebug *
wad_search_stab(void *sp, int size, char *stabstr, char *symbol, unsigned long offset) {
Stab *s;
int ns;
int infunc;
int slen;
int i;
char *file;
int chk = 0;
s = (Stab *) sp; /* Stabs data */
ns = size/sizeof(Stab); /* number of stabs */
slen = strlen(symbol);
/* Reset the debug information section */
debug.found = 0;
debug.srcfile[0] = 0;
debug.objfile[0] = 0;
debug.line_number = -1;
debug.nargs = 0;
for (i = 0; i < ns; i++, s++) {
/*#define DEBUG_DEBUG */
#ifdef DEBUG_DEBUG
printf(" %10d %10x %10d %10d %10d: '%s'\n", s->n_strx, s->n_type, s->n_other, s->n_desc, s->n_value,
stabstr+s->n_strx);
#endif
#undef DEBUG_DEBUG
if (s->n_type == 0) {
/* New stabs section. We need to be a little careful here. Do a recursive
search of the subsection. */
WadDebug *wd;
#ifdef DEBUG_DEBUG
printf("Section: %d stabs.\n", s->n_desc);
#endif
wd = wad_search_stab(s+1,s->n_desc*sizeof(Stab), stabstr, symbol, offset);
if (wd) return wd;
stabstr += s->n_value; /* Update the string table location*/
i += s->n_desc;
s += s->n_desc;
debug.objfile[0] = 0;
debug.srcfile[0] = 0;
debug.line_number = -1;
debug.found = 0;
} else if (s->n_type == 0x64) {
if (debug.found) return &debug; /* New file and we already found what we wanted */
/* Source file specification */
/* Look for directory */
file = stabstr+s->n_strx;
if (file[strlen(file)] == '/') {
strcpy(debug.srcfile,file);
} else {
strcat(debug.srcfile,file);
}
debug.objfile[0] = 0;
} else if (s->n_type == 0x38) {
/* Object file specifier */
if (debug.objfile[0]) {
strcat(debug.objfile,"/");
}
strcat(debug.objfile,stabstr+s->n_strx);
} else if (s->n_type == 0x24) {
if (match_stab_symbol(symbol, stabstr+s->n_strx, slen)) {
infunc = 1;
debug.found = 1;
debug.nargs = 0;
} else {
infunc = 0;
}
} else if (debug.found && (s->n_type == 0x44) && (infunc)) {
/* Line number location */
if (s->n_value < offset) {
debug.line_number = s->n_desc;
} else return &debug;
} else if (debug.found && ((s->n_type == 0xa0) || (s->n_type == 0x40)) && (infunc)) {
/* Parameter counting */
char *pname;
char *c;
int len;
pname = stabstr+s->n_strx;
c = strchr(pname,':');
if (c) {
len = (c-pname);
} else {
len = strlen(pname);
}
/* Check if already used */
/* In this case, the first stab simply identifies an argument. The second
one identifies its location for the debugger */
if (debug.nargs > 0) {
if (strcmp(debug.parms[debug.nargs-1].name, pname) == 0)
debug.nargs--;
}
strncpy(debug.parms[debug.nargs].name,pname,len);
debug.parms[debug.nargs].name[len] = 0;
if (s->n_type == 0x40)
debug.parms[debug.nargs].loc = PARM_REGISTER;
else
debug.parms[debug.nargs].loc = PARM_STACK;
debug.parms[debug.nargs].value = s->n_value;
/* printf("%s : %d: %d : %s\n", debug.parms[debug.nargs].name, s->n_type, debug.parms[debug.nargs].value,pname); */
debug.nargs++;
}
}
if (debug.found) return &debug;
return 0;
}