📄 dbg386.c
字号:
}
//-------------------------------------------------------------------------
void debug_outputtypedef(SYM *sp)
{
char buf[256];
UDTSYM *us = buf;
us->reclen = sizeof(UDTSYM) + putname(us->name, sp->name);
us->rectyp = S_UDT;
us->typind = debug_outputtype(sp->tp);
emitsym(buf);
}
//-------------------------------------------------------------------------
int debug_outputtype(TYP *type)
{
char qbuf[32];
if (type->type == bt_ellipse)
// nothing can access it
return 0;
if (type->bits != - 1)
{
int val = debug_outputtypell(type), len;
lfBitfield *ptr = qbuf + 2;
ptr->leaf = LF_BITFIELD;
ptr->length = type->bits;
ptr->position = type->startbit;
ptr->type = val;
len = sizeof(lfBitfield);
qbuf[0] = len;
qbuf[1] = 0;
emittype(qbuf);
return nexttype++;
}
else
return debug_outputtypell(type);
}
//-------------------------------------------------------------------------
void debug_outfunc(SYM *sp)
{
dbgblock = 0;
funcSyms = 0;
symSize = 0;
blockSyms = 0;
dbgblocknum = 0;
}
//-------------------------------------------------------------------------
void debug_beginblock(TABLE lsyms)
{
DBGBLOCK *p = xalloc(sizeof(DBGBLOCK));
if (!dbgblock)
{
dbgblock = p;
currentblock = p;
}
else
{
DBGBLOCK *n = currentblock->child;
if (!n)
currentblock->child = p;
else
{
while (n->next)
n = n->next;
n->next = p;
}
p->parent = currentblock;
currentblock = p;
}
p->oldsyms = lsyms.head;
DbgBlocks[dbgblocknum = blockSyms++] = currentblock;
}
//-------------------------------------------------------------------------
static void getSymSize(DBGBLOCK *blk)
{
SYM *s = blk->syms;
while (s && s != blk->oldsyms)
{
int l;
char internal[256];
funcSyms++;
unmangle(internal, s->name);
l = strlen(internal);
if (s->inreg)
{
l += sizeof(REGSYM);
}
else if (s->funcparm | s->storage_class == sc_auto || s->storage_class
== sc_autoreg)
{
l += sizeof(BPRELSYM32);
}
else
{
l += sizeof(DATASYM32);
}
if (l % 4)
l += 4-l % 4;
symSize += l;
s = s->next;
}
if (blk->child)
getSymSize(blk->child);
if (blk->next)
getSymSize(blk->next);
}
//-------------------------------------------------------------------------
static void dumpblocks(DBGBLOCK *blk, char *buf, int *ofs, int parent, int
baseoffs)
{
SYM *p = blk->syms;
SYMTYPE *ss;
BLOCKSYM32 *bss;
int startofs = *ofs;
if (blk != dbgblock)
{
bss = buf + *ofs;
bss->reclen = sizeof(BLOCKSYM32) + 1-2;
*ofs += bss->reclen + 2;
bss->rectyp = S_BLOCK32;
bss->pParent = parent;
bss->off = blk->startofs;
bss->len = blk->endofs - blk->startofs;
bss->seg = codeseg;
bss->name[0] = 0;
}
while (p && p != blk->oldsyms)
{
int l;
char internal[256];
unmangle(internal, p->name);
l = strlen(internal);
if (p->inreg)
{
REGSYM *rs = buf + *ofs;
int size;
l += sizeof(REGSYM);
if (l % 4)
l += 4-l % 4;
*ofs += l;
rs->reclen = l - 2;
rs->rectyp = S_REGISTER;
rs->typind = debug_outputtype(p->tp);
size = ( - p->value.i) / 256;
rs->reg = ( - p->value.i) &255;
if (rs->reg > 15)
// ESI,EDI,
rs->reg -= 12;
rs->reg += (size == 4 ? 2 : size - 1) *8+CV_REG_AL;
rs->name[0] = strlen(internal);
memcpy(rs->name + 1, internal, rs->name[0]);
}
else if (p->funcparm | p->storage_class == sc_auto || p->storage_class
== sc_autoreg)
{
BPRELSYM32 *bs = buf + *ofs;
l += sizeof(BPRELSYM32);
if (l % 4)
l += 4-l % 4;
*ofs += l;
bs->reclen = l - 2;
bs->rectyp = S_BPREL32;
bs->off = p->value.i;
bs->typind = debug_outputtype(p->tp);
bs->name[0] = strlen(internal);
memcpy(bs->name + 1, internal, bs->name[0]);
}
else
{
DATASYM32 *ds = buf + *ofs;
l += sizeof(DATASYM32);
if (l % 4)
l += 4-l % 4;
*ofs += l;
ds->reclen = l - 2;
ds->rectyp = S_LDATA32;
ds->off = p->offset;
ds->seg = omfgetseg(p);
if (ds->seg &0xc0000000)
ds->seg = codeseg;
ds->typind = debug_outputtype(p->tp);
ds->name[0] = strlen(internal);
memcpy(ds->name + 1, internal, ds->name[0]);
}
p = p->next;
}
if (blk->child)
{
if (blk != dbgblock)
dumpblocks(blk->child, buf, ofs, startofs + baseoffs, baseoffs);
else
dumpblocks(blk->child, buf, ofs, parent, baseoffs);
}
if (blk != dbgblock)
{
bss->pEnd = *ofs + baseoffs;
ss = buf + *ofs;
ss->reclen = 4-2;
ss->rectyp = S_END;
*ofs += 4;
}
if (blk->next)
dumpblocks(blk->next, buf, ofs, parent, baseoffs);
}
//-------------------------------------------------------------------------
void dumptypes(DBGBLOCK *blk)
{
SYM *p = blk->syms;
while (p && p != blk->oldsyms)
{
debug_outputtype(p->tp);
p = p->next;
}
if (blk->child)
dumptypes(blk->child);
if (blk->next)
dumptypes(blk->next);
}
//-------------------------------------------------------------------------
void debug_endblock(TABLE lsyms, TABLE oldsyms)
{
DBGBLOCK *p = currentblock;
SYM *s;
int size = 0, offset, procsize, l, bufofs = 0, retsize, retstyle;
char *buf;
PROCSYM32 *ps, *funcsym;
RETURNSYM *rets;
BLOCKSYM32 *bss;
SYMTYPE *ss;
ENDARGSYM *es;
BPRELSYM32 *bs;
REGSYM *rs;
char internal[256];
int proctype;
p->syms = s = lsyms.head;
if (currentblock != dbgblock)
{
currentblock = currentblock->parent;
return ;
}
getSymSize(dbgblock);
s = currentfunc->tp->lst.head;
while (s && s != (SYM*) - 1)
{
if (s->storage_class != sc_type)
{
debug_outputtype(s->tp);
funcSyms++;
unmangle(internal, s->name);
l = strlen(internal);
if (s->inreg)
l += sizeof(REGSYM);
else
l += sizeof(BPRELSYM32);
if (l % 4)
l += 4-l % 4;
symSize += l;
}
s = s->next;
}
dumptypes(dbgblock);
proctype = debug_outputtype(currentfunc->tp->btp);
/* if we get here it is time to dump the function and its blocks */
unmangle(internal, currentfunc->name);
procsize = sizeof(PROCSYM32) + strlen(internal);
if (procsize % 4)
procsize += (4-procsize % 4);
retsize = sizeof(RETURNSYM);
if (currentfunc->tp->btp->type == bt_void)
retstyle = CV_GENERIC_VOID;
else if (currentfunc->calleenearret)
{
retstyle = CV_GENERIC_ICAN;
}
else
{
retstyle = CV_GENERIC_REG;
retsize += 2;
}
if (retsize % 4)
retsize += 4-retsize % 4;
size = procsize + retsize + symSize + sizeof(S_ENDARG) + (blockSyms - 1)*(
(sizeof(BLOCKSYM32) + 1) + sizeof(SYMTYPE) - CV_ZEROLEN) + sizeof
(SYMTYPE) - 1;
funcsym = ps = buf = xalloc(size);
bufofs += (ps->reclen = procsize - 2) + 2;
/* fill in the procedure data last */
offset = segs[symseg].last->filled + segs[symseg].last->address;
if (lastfuncoffset)
{
write_to_seg(symseg, lastfuncoffset, &offset, 4);
}
lastfuncoffset = offset + (int) &ps->pNext - (int)ps;
ps->rectyp = currentfunc->storage_class == sc_static ? S_LPROC32 :
S_GPROC32;
ps->pParent = 0;
ps->pEnd = offset + size - (sizeof(SYMTYPE) - CV_ZEROLEN);
// Will be filled in later
ps->pNext = 0; // will be filled in later
ps->len = outcode_base_address - currentfunc->offset;
ps->DbgStart = LabelAddress(startlab) - currentfunc->offset;
ps->DbgEnd = LabelAddress(retlab) - currentfunc->offset;
ps->off = currentfunc->offset;
ps->seg = codeseg; // should not be relocated
ps->typind = proctype;
// ps->flags = 0 ; // technically we should track FPO here, but I'm not using it
ps->name[0] = strlen(internal);
memcpy(ps->name + 1, internal, ps->name[0]);
rets = buf + bufofs;
rets->reclen = retsize - 2;
rets->rectyp = S_RETURN;
rets->flags.cstyle = !(currentfunc->pascaldefn);
rets->flags.rsclean = currentfunc->pascaldefn | currentfunc->isstdcall;
rets->style = retsize > 8 ? CV_GENERIC_REG : CV_GENERIC_VOID;
if (rets->style == CV_GENERIC_REG)
{
TYP *tp = currentfunc->tp->btp;
int sz = tp->size;
if (sz < 0)
sz = - sz;
buf[bufofs + sizeof(RETURNSYM)] = 1;
if (tp->type == bt_float || tp->type == bt_double || tp->type ==
bt_longdouble || tp->type == bt_fcomplex || tp->type == bt_rcomplex
|| tp->type == bt_lrcomplex)
buf[bufofs + sizeof(RETURNSYM) + 1] = CV_REG_ST0;
else
buf[bufofs + sizeof(RETURNSYM) + 1] = CV_REG_AL + 8 *(sz == 4 ? 2 :
sz - 1);
}
bufofs += retsize;
s = currentfunc->tp->lst.head;
while (s && s != (SYM*) - 1)
{
if (s->storage_class != sc_type)
{
unmangle(internal, s->name);
if (s->inreg)
{
int size;
rs = buf + bufofs;
retsize = sizeof(REGSYM) + strlen(internal);
if (retsize % 4)
retsize += 4-retsize % 4;
bufofs += retsize;
rs->reclen = retsize - 2;
rs->rectyp = S_REGISTER;
rs->typind = debug_outputtype(s->tp);
size = ( - s->value.i) / 256;
rs->reg = ( - s->value.i) &255;
if (rs->reg > 15)
// ESI,EDI,
rs->reg -= 12;
rs->reg += (size == 4 ? 2 : size - 1) *8+CV_REG_AL;
rs->name[0] = strlen(internal);
memcpy(rs->name + 1, internal, rs->name[0]);
}
else
{
bs = buf + bufofs;
retsize = sizeof(BPRELSYM32) + strlen(internal);
if (retsize % 4)
retsize += 4-retsize % 4;
bufofs += retsize;
bs->reclen = retsize - 2;
bs->rectyp = S_BPREL32;
bs->off = s->value.i;
bs->typind = debug_outputtype(s->tp);
bs->name[0] = strlen(internal);
memcpy(bs->name + 1, internal, bs->name[0]);
}
}
s = s->next;
}
es = bufofs + buf;
bufofs += sizeof(ENDARGSYM);
es->reclen = sizeof(ENDARGSYM) - 2;
es->rectyp = S_ENDARG;
dumpblocks(dbgblock, buf, &bufofs, offset, offset);
ss = buf + bufofs;
ss->reclen = 4-2;
ss->rectyp = S_END;
bufofs += 4; /* should equal SIZE now if we did everything right */
if (bufofs != size)
{
char bf[256];
sprintf(bf, "Debug output - function size mismatch %d %d", size, bufofs)
;
DIAG(bf);
}
emit(symseg, buf, size);
s = currentfunc->tp->lst.head;
while (s && s != (SYM*) - 1)
{
if (s->storage_class == sc_type && s->istypedef)
debug_outputtypedef(s);
s = s->next;
}
}
//-------------------------------------------------------------------------
void debug_outdata(SYM *sp, int BSS)
{
char buf[256];
DATASYM32 *p = buf;
char internal[256];
int offset;
unmangle(internal, sp->name);
p->reclen = sizeof(DATASYM32) + (p->name[0] = strlen(internal)) - 2;
p->rectyp = sp->storage_class == sc_static ? S_LDATA32 : S_GDATA32;
p->off = sp->offset;
p->seg = omfgetseg(sp);
if (p->seg &0xc0000000)
p->seg = codeseg;
/* complex types should already be in the table, but not all
* inherent types have been resolved to thier CV version yet
*/
p->typind = debug_outputtype(sp->tp);
strcpy(p->name + 1, internal);
offset = segs[symseg].last->filled + segs[symseg].last->address;
if (lastfuncoffset)
{
write_to_seg(symseg, lastfuncoffset, &offset, 4);
lastfuncoffset = 0;
}
emitsym(buf);
}
//-------------------------------------------------------------------------
static void dumphashtable(HASHREC **syms)
{
int i;
SYM *sp;
for (i = 0; i < HASHTABLESIZE; i++)
{
if ((sp = (SYM*)syms[i]) != 0)
{
while (sp)
{
if (sp->storage_class == sc_type && sp->istypedef && sp->tp
->typeindex && *sp->tp->typeindex)
debug_outputtypedef(sp);
if (sp->storage_class == sc_namespace && !sp
->value.classdata.parentns->anonymous)
dumphashtable(sp->value.classdata.parentns->table);
sp = sp->next;
}
}
}
}
//-------------------------------------------------------------------------
void debug_dumpglobaltypedefs(void)
{
dumphashtable(gsyms);
}
//-------------------------------------------------------------------------
static void out_sym_header(void)
{
char buf[256], buf1[256];
CFLAGSYM *p = buf;
OBJNAMESYM *q = buf;
sprintf(buf1, "CC386 Version %s (LADSoft)", version);
memset(buf, 0, 256);
p->reclen = sizeof(CFLAGSYM) + (p->ver[0] = strlen(buf1));
p->rectyp = S_COMPILE;
p->machine = CV_CFL_80386;
p->flags.language = prm_cplusplus ? CV_CFL_CXX : CV_CFL_C;
p->flags.pcode = FALSE;
p->flags.floatprec = TRUE;
p->flags.floatpkg = CV_CFL_NDP;
p->flags.ambdata = CV_CFL_DNEAR;
p->flags.ambcode = CV_CFL_CNEAR;
p->flags.mode32 = TRUE;
strcpy(p->ver + 1, buf1);
emitsym(buf);
memset(buf, 0, 256);
q->reclen = sizeof(OBJNAMESYM) + (q->name[0] = strlen(outfile));
q->rectyp = S_OBJNAME;
q->signature = 0;
strcpy(q->name + 1, outfile);
emitsym(buf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -