📄 symtab.c
字号:
return offset;
}
offset = p->pNext;
}
}
return 0;
}
//-------------------------------------------------------------------------
static int FindFunctionByAddress(DEBUG_INFO *dbg, char **symtab, int *offset,
int Address, int SelAddress)
{
OMFSignature *sig;
OMFDirHeader *dh;
OMFDirEntry *e;
int i, j, k, l;
sig = dbg->info;
dh = dbg->info + sig->filepos;
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstModule)
{
OMFModule *m;
OMFSegDesc *s;
m = dbg->info + e->lfo;
s = &m->SegInfo;
for (j = 0; j < m->cSeg; j++)
{
if (s->Seg == 1)
{
/* code seg */
if (Address >= s->Off && Address < s->Off + s->cbSeg)
{
OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
for (k = 0; k < dh->cDir; k++)
{
if (e1->SubSection == sstAlignSym && e->iMod == e1
->iMod)
{
DWORD offs = FindFunctionInSymtab(dbg, e1->lfo,
Address, SelAddress);
if (offs)
{
*symtab = dbg->info + e1->lfo;
*offset = offs;
return TRUE;
}
break;
}
e1++;
}
}
break;
}
s++;
}
}
e++;
}
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstGlobalSym)
{
DWORD offs = FindFunctionInSymtab(dbg, e->lfo + sizeof(OMFSymHash),
Address, SelAddress);
if (offs)
{
*symtab = dbg->info + e->lfo + sizeof(OMFSymHash);
*offset = offs;
return TRUE;
}
else
return FALSE;
}
e++;
}
return 0;
}
//-------------------------------------------------------------------------
static int namematch(SYMTYPE *s, char *name)
{
char *funcname;
switch (s->rectyp)
{
case S_BPREL32:
funcname = ((BPRELSYM32*)s)->name;
break;
case S_REGISTER:
funcname = ((REGSYM*)s)->name;
break;
case S_LDATA32:
case S_GDATA32:
funcname = ((DATASYM32*)s)->name;
break;
case S_LPROC32:
case S_GPROC32:
funcname = ((PROCSYM32*)s)->name;
break;
case S_UDT:
funcname = ((UDTSYM*)s)->name;
break;
case S_LABEL32:
funcname = ((LABELSYM32*)s)->name;
break;
default:
return FALSE;
}
if (strlen(name) != funcname[0])
return 0;
return !strncmp(funcname + 1, name, funcname[0]);
}
//-------------------------------------------------------------------------
static int FindSymbolInFunction(char *symtab, int offset, char *name, int
Address)
{
PROCSYM32 *func = symtab + offset;
int endoffs = func->pEnd;
int blockoffs = offset;
int findoffs = blockoffs;
BLOCKSYM32 *blk;
// First find the enclosing block
while (findoffs < endoffs)
{
BLOCKSYM32 *b = symtab + findoffs;
if (b->rectyp == S_BLOCK32)
{
if (b->off <= Address && Address < b->off + b->len)
{
blockoffs = findoffs;
endoffs = b->pEnd;
findoffs += b->reclen + 2;
}
else
findoffs = b->pEnd;
}
else
findoffs += b->reclen + 2;
}
// now blockoffs has the point to the innermost block
blk = symtab + blockoffs;
while (blk)
{
int end = blk->rectyp == S_BLOCK32 ? blk->pEnd: func->pEnd;
findoffs = (unsigned char*)blk - (unsigned char*)symtab + blk->reclen +
2;
while (findoffs < end)
{
BLOCKSYM32 *p = findoffs + symtab;
if (p->rectyp == S_BLOCK32)
findoffs = p->pEnd;
else
{
if (namematch(p, name))
{
return findoffs;
}
findoffs += p->reclen + 2;
}
}
if (blk->rectyp == S_BLOCK32)
blk = symtab + blk->pParent;
else
blk = 0;
}
return 0;
}
//-------------------------------------------------------------------------
static int FindSymbolInSymtab(char *symtab, int len, char *name)
{
int offset = 0;
while (offset < len)
{
struct SYMTYPE *s = symtab + offset;
if (s->rectyp == S_LPROC32 || s->rectyp == S_GPROC32)
{
PROCSYM32 *p = s;
if (namematch(s, name))
return offset;
offset = p->pEnd;
}
else
{
if (namematch(s, name))
{
return offset;
}
offset = offset + s->reclen + 2;
}
}
return 0;
}
//-------------------------------------------------------------------------
int FindSymbol(DEBUG_INFO **dbg_info, char **typetab, char **symtab, int
*offset, int Address, int SelAddress, char *name)
{
OMFSignature *sig;
OMFDirHeader *dh;
OMFDirEntry *e;
int i, j;
DEBUG_INFO *dbg = DebugProcess.dbg_info;
DLL_INFO *dll = DebugProcess.dll_info;
int funcoffs;
*typetab = 0;
while (dll && (unsigned)dll->base <= (unsigned)Address)
{
dbg = dll->dbg_info;
dll = dll->next;
}
if (!dbg)
return 0;
*dbg_info = dbg;
// Find the types table
sig = dbg->info;
dh = dbg->info + sig->filepos;
// See if it is a function argument or variable
funcoffs = FindFunctionByAddress(dbg, symtab, offset, Address - dbg->base,
SelAddress - dbg->base);
if (funcoffs)
{
int offs = FindSymbolInFunction(*symtab, *offset, name, Address - dbg
->base);
if (offs)
{
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstGlobalTypes)
{
*typetab = dbg->info + e->lfo;
break;
}
e++;
}
*offset = offs;
return TRUE;
}
}
if (dbg)
{
sig = dbg->info;
dh = dbg->info + sig->filepos;
*dbg_info = dbg;
// check the local symbol table
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstModule)
{
OMFModule *m;
OMFSegDesc *s;
m = dbg->info + e->lfo;
s = &m->SegInfo;
for (j = 0; j < m->cSeg; j++)
{
if (s->Seg == 1)
{
/* code seg */
// if (SelAddress-dbg->base >= s->Off && SelAddress-dbg->base < s->Off + s->cbSeg) {
int k, l;
OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
for (k = 0; k < dh->cDir; k++)
{
if (e1->SubSection == sstAlignSym && e->iMod == e1
->iMod)
{
int offs = FindSymbolInSymtab(dbg->info + e1
->lfo, e1->cb, name);
if (offs)
{
e = (unsigned char*)dh + dh->cbDirHeader;
for (l = 0; l < dh->cDir; l++)
{
if (e->SubSection == sstGlobalTypes)
{
*typetab = dbg->info + e->lfo;
break;
}
e++;
}
*symtab = dbg->info + e1->lfo;
*offset = offs;
return 1;
}
break;
}
e1++;
}
// }
break;
}
s++;
}
}
e++;
}
// And check the global symtab for the program this is a part of
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstGlobalSym)
{
int offs = FindSymbolInSymtab(dbg->info + e->lfo + sizeof
(OMFSymHash), e->cb - sizeof(OMFSymHash), name);
if (offs)
{
OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e1->SubSection == sstGlobalTypes)
{
*typetab = dbg->info + e1->lfo;
break;
}
e1++;
}
*symtab = dbg->info + e->lfo + sizeof(OMFSymHash);
*offset = offs;
return TRUE;
}
else
return FALSE;
}
e++;
}
}
return 0;
}
//-------------------------------------------------------------------------
int FindAddressInSymtab(DEBUG_INFO *dbg, char *symtab, int len, int address,
char *buf)
{
int offset = 0;
while (offset < len)
{
struct SYMTYPE *s = symtab + offset;
switch (s->rectyp)
{
case S_LDATA32:
case S_GDATA32:
if (address == ((DATASYM32*)s)->off + dbg->base)
{
memcpy(buf, ((DATASYM32*)s)->name + 1, ((DATASYM32*)s)
->name[0]);
buf[((DATASYM32*)s)->name[0]] = 0;
return offset;
}
offset = offset + s->reclen + 2;
break;
case S_LPROC32:
case S_GPROC32:
if (address == ((PROCSYM32*)s)->off + dbg->base)
{
memcpy(buf, ((PROCSYM32*)s)->name + 1, ((PROCSYM32*)s)
->name[0]);
buf[((PROCSYM32*)s)->name[0]] = 0;
return offset;
}
offset = ((PROCSYM32*)s)->pEnd;
break;
case S_LABEL32:
if (address == ((LABELSYM32*)s)->off + dbg->base)
{
memcpy(buf, ((LABELSYM32*)s)->name + 1, ((LABELSYM32*)s)
->name[0]);
buf[((LABELSYM32*)s)->name[0]] = 0;
return offset;
}
// fallthrough
default:
offset = offset + s->reclen + 2;
break;
}
}
return 0;
}
//-------------------------------------------------------------------------
int FindSymbolByAddress(DEBUG_INFO **dbg_info, char **typetab, char **symtab,
int *offset, int Address, char *buf)
{
OMFSignature *sig;
OMFDirHeader *dh;
OMFDirEntry *e;
int i, j;
DEBUG_INFO *dbg = DebugProcess.dbg_info;
DLL_INFO *dll = DebugProcess.dll_info;
int funcoffs;
*typetab = 0;
while (dll && (unsigned)dll->base <= (unsigned)Address)
{
dbg = dll->dbg_info;
dll = dll->next;
}
if (!dbg)
return 0;
*dbg_info = dbg;
// Find the types table
sig = dbg->info;
dh = dbg->info + sig->filepos;
if (dbg)
{
sig = dbg->info;
dh = dbg->info + sig->filepos;
*dbg_info = dbg;
// check the local symbol table
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstModule)
{
OMFModule *m;
OMFSegDesc *s;
m = dbg->info + e->lfo;
s = &m->SegInfo;
for (j = 0; j < m->cSeg; j++)
{
if (s->Seg == 1)
{
/* code seg */
if (Address - dbg->base >= s->Off && Address - dbg
->base < s->Off + s->cbSeg)
{
OMFDirEntry *e1 = (unsigned char*)dh + dh
->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e1->SubSection == sstAlignSym && e->iMod ==
e1->iMod)
{
int offs = FindAddressInSymtab(dbg, dbg
->info + e1->lfo, e1->cb, Address, buf);
if (offs)
{
e = (unsigned char*)dh + dh
->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstGlobalTypes)
{
*typetab = dbg->info + e->lfo;
break;
}
e++;
}
*symtab = dbg->info + e1->lfo;
*offset = offs;
return 1;
}
}
e1++;
}
}
break;
}
s++;
}
}
e++;
}
// And check the global symtab for the program this is a part of
e = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
if (e->SubSection == sstGlobalSym)
{
int offs = FindAddressInSymtab(dbg, dbg->info + e->lfo + sizeof
(OMFSymHash), e->cb - sizeof(OMFSymHash), Address, buf);
if (offs)
{
OMFDirEntry *e1 = (unsigned char*)dh + dh->cbDirHeader;
for (i = 0; i < dh->cDir; i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -