📄 syms.c
字号:
strcmp(cp, "d.") == 0 /* as in gcc_compiled. */ ||
strcmp(cp, ".o") == 0)
{
if (f && files[f-1].last_address == 0)
files[f-1].last_address = f_aoutsyms[i].val - 1;
break;
}
c = 't';
goto sym_c;
case N_DATA:
c = 'd';
goto sym_c;
case N_ABS:
c = 'a';
goto sym_c;
case N_BSS:
c = 'b';
goto sym_c;
case N_FN:
c = 'f';
goto sym_c;
case N_SETV:
c = 'v';
goto sym_c;
case N_SETA:
c = 'v';
goto sym_c;
case N_SETT:
c = 'v';
goto sym_c;
case N_SETD:
c = 'v';
goto sym_c;
case N_SETB:
c = 'v';
goto sym_c;
case N_INDR:
c = 'i';
sym_c:
syms[s].name = symn;
syms[s].address = f_aoutsyms[i].val;
syms[s].type_c = (f_aoutsyms[i].type & N_EXT) ? (c+'A'-'a') : c;
s ++;
break;
}
}
l = f = 0;
for (i=0; i<nsyms; i++)
{
/* char c, *cp;*/
char *symn = f_string_table + f_aoutsyms[i].string_off;
switch (f_aoutsyms[i].type & ~N_EXT)
{
case N_SO:
if (symn[strlen(symn)-1] == '/')
break;
files[f].lines = (LINENO *)xmalloc(files[f].num_lines * sizeof(LINENO));
f++;
l = 0;
break;
case N_SLINE:
files[f-1].lines[l].l_addr.l_paddr = f_aoutsyms[i].val;
files[f-1].lines[l].l_lnno = f_aoutsyms[i].desc;
l ++;
break;
}
}
}
struct exe_hdr {
unsigned short signatur;
unsigned short low;
unsigned short high;
unsigned short reloc;
unsigned short hdr_para;
};
struct emx_hdr {
char sig[18];
char next_off[4];
};
int skip_exe_hdr(FILE *fd, unsigned long *headoff)
{
struct exe_hdr exehdr;
struct emx_hdr emxhdr;
*headoff=0;
fseek(fd, 0, 0);
fread(&exehdr, sizeof(struct exe_hdr), 1, fd);
if (exehdr.signatur == 0x5a4d) {
*headoff = ((unsigned long) exehdr.hdr_para) * 16;
fseek(fd, *headoff, 0);
fread(&emxhdr, sizeof(struct emx_hdr), 1, fd);
if (memcmp(emxhdr.sig, "emx", 3) == 0)
*headoff = *(int *) emxhdr.next_off;
else { /* not a emx file */
long new_off;
fseek(fd, 0x3C, SEEK_SET);
fread(&new_off, sizeof(long), 1, fd);
if (new_off) {
char pe_sig[4];
fseek(fd, new_off, SEEK_SET);
fread(pe_sig, sizeof(pe_sig), 1, fd);
printf("file is a new executable '%c%c'", pe_sig[0], pe_sig[1]);
if (pe_sig[0]) {
*headoff = new_off + 4;
}
}
else { /* djgpp */
*headoff = (DWORD) exehdr.high * 512L;
if (exehdr.low)
*headoff += (DWORD) exehdr.low - 512L;
}
}
}
if (!fseek(fd, *headoff, 0))
return 0;
else {
*headoff = 0;
fseek(fd, 0, 0);
return -1;
}
}
static void process_file(FILE *fd, long ofs)
{
short s;
skip_exe_hdr(fd, &ofs);
fread(&s, 2, 1, fd);
switch (s)
{
case 0x014c: /* .coff */
process_coff(fd, ofs);
break;
case 0x010b: /* a.out ZMAGIC */
case 0x0107: /* a.out object */
process_aout(fd, ofs);
break;
}
}
void syms_init(char *fname)
{
FILE *fd = fopen(fname, "rb");
if (fd == 0)
{
perror(fname);
}
else
{
process_file(fd, 0);
syms_byname = (SymNode *)xmalloc(num_syms * sizeof(SymNode));
memcpy(syms_byname, syms, num_syms * sizeof(SymNode));
qsort(syms_byname, num_syms, sizeof(SymNode), syms_sort_bn);
qsort(syms, num_syms, sizeof(SymNode), syms_sort_bv);
fclose(fd);
}
}
int lookup_sym_byname(char *name, int idx, int ofs)
{
int below, above;
char ch = name[idx];
name[idx] = 0;
below = -1;
above = num_syms;
while (above - below > 1)
{
int mid = (above + below) / 2;
int c = 0;
if (ofs)
c = '_' - syms_byname[mid].name[0];
if (c == 0)
c = strcmp(name, syms_byname[mid].name+ofs);
if (c == 0)
{
name[idx] = ch;
return mid;
}
if (c < 0)
above = mid;
else
below = mid;
}
name[idx] = ch;
return -1;
}
word32 syms_name2val(char *name)
{
int idx, sign=1, i;
word32 v,pt;
char *cp;
undefined_symbol = 0;
idx = 0;
sscanf(name, "%s", name);
if (name[0] == 0)
return 0;
if (name[0] == '-')
{
sign = -1;
name++;
}
else if (name[0] == '+')
{
name++;
}
if (isdigit(name[0]))
{
if (sign == -1)
return -strtol(name, 0, 0);
return strtol(name, 0, 0);
}
cp = strpbrk(name, "+-");
if (cp)
idx = cp-name;
else
idx = strlen(name);
if (name[0] == '%') /* register */
{
for (i=0; regs[i].name; i++)
if (strncmp(name, regs[i].name, idx) == 0)
{
pt = ptrace_get_register(regs[i].ofs * 4);
switch (regs[i].size)
{
case 0: /* ah */
v = (pt>>8) & 0xFF;
break;
case 1: /* al */
v = pt & 0xFF;
break;
case 2: /* ax */
v = pt & 0xFFFF;
break;
case 4: /* eax */
v = pt;
break;
}
return v + syms_name2val(name+idx);
}
}
for (i=0; i<idx; i++)
if (name[i] == '#')
{
int f;
int lnum, l;
sscanf(name+i+1, "%d", &lnum);
for (f=0; f<num_files; f++)
{
if ((strncmp(name, files[f].filename, i) == 0) && (files[f].filename[i] == 0))
{
for (l=0; l<files[f].num_lines; l++)
{
if (files[f].lines[l].l_lnno == lnum)
return files[f].lines[l].l_addr.l_paddr + syms_name2val(name+idx);
}
printf("undefined line number %.*s\n", idx, name);
undefined_symbol = 1;
return 0;
}
}
printf("Undefined file name %.*s\n", i, name);
undefined_symbol = 1;
return 0;
}
i = lookup_sym_byname(name, idx, 0);
if (i == -1)
i = lookup_sym_byname(name, idx, 1);
if (i != -1)
return syms_byname[i].address * sign + syms_name2val(name+idx);
printf("Undefined symbol %.*s\n", idx, name);
undefined_symbol = 1;
return 0;
}
static char noname_buf[11];
char *syms_val2name(word32 val, word32 *delta)
{
/* static char buf[1000];*/
int above, below, mid;
if (delta)
*delta = 0;
if (num_syms <= 0)
goto noname;
above = num_syms;
below = -1;
while (above-below > 1)
{
mid = (above+below)/2;
if (syms[mid].address == val)
break;
if (syms[mid].address > val)
above = mid;
else
below = mid;
}
if (syms[mid].address > val)
{
if (mid == 0)
goto noname;
mid--; /* the last below was it */
}
if (mid < 0)
goto noname;
if (strcmp(syms[mid].name, "_end") == 0)
goto noname;
if (strcmp(syms[mid].name, "__end") == 0)
goto noname;
if (strcmp(syms[mid].name, "_etext") == 0)
goto noname;
if (delta)
*delta = val - syms[mid].address;
return syms[mid].name;
noname:
sprintf(noname_buf, "%#lx", val);
return noname_buf;
}
char *syms_val2line(word32 val, int *lineret, int exact)
{
int f, l;
for (f=0; f<num_files; f++)
{
if (val >= files[f].first_address && val <= files[f].last_address && files[f].lines)
{
for (l=files[f].num_lines-1; l >= 0 && files[f].lines[l].l_addr.l_paddr > val; l--);
if ((files[f].lines[l].l_addr.l_paddr != val) && exact)
return 0;
*lineret = files[f].lines[l].l_lnno;
return files[f].filename;
}
}
return 0;
}
int wild(char *pattern, char *string)
{
int nlit;
while (*pattern)
{
switch (*pattern)
{
case '*':
pattern++;
if (*pattern == 0)
return 1;
nlit=0;
while ((pattern[nlit] != 0)
&& (pattern[nlit] != '*')
&& (pattern[nlit] != '?') )
nlit++;
while (1)
{
if (strncmp(string, pattern, nlit) == 0)
break;
string++;
if (*string == 0)
return 0;
}
break;
case '?':
if (*string == 0)
return 0;
pattern++;
string++;
break;
default:
if (*pattern != *string)
return 0;
pattern++;
string++;
break;
}
}
if (*string)
return 0;
return 1;
}
void syms_listwild(char *pattern)
{
int linecnt = 0;
int lnum;
char *name;
int i, key;
for (i=0; i<num_syms; i++)
if (wild(pattern, syms_byname[i].name))
{
if (++linecnt > 20)
{
printf("--- More ---");
fflush(stdout);
key = getchar();
printf("\r \r");
switch (key)
{
case ' ':
linecnt = 0;
break;
case 13:
linecnt--;
break;
case 'q':
case 27:
return;
}
}
printf("0x%08lx %c %s", syms_byname[i].address, syms_byname[i].type_c, syms_byname[i].name);
name = syms_val2line(syms_byname[i].address, &lnum, 0);
if (name)
printf(", line %d of %s", lnum, name);
putchar('\n');
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -