dbginfo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 899 行 · 第 1/2 页
C
899 行
}
extern void ODBIGenGlobal( symbol * sym, section *sect )
/******************************************************/
{
int len;
int entrylen;
gblinfo *data;
char *name;
debug_info *dptr;
dptr = sect->dbg_info;
if( dptr == NULL )
return;
if( ODBISymIsForGlobalDebugging( sym, CurrMod ) ) {
name = sym->name;
len = strlen( name );
if( len > 255 ) {
len = 255;
}
entrylen = sizeof( gblinfo ) + len;
data = (gblinfo *) alloca( entrylen );
_HostU32toTarg( sym->addr.off, data->off );
_HostU16toTarg( sym->addr.seg, data->seg );
_HostU16toTarg( dptr->modnum, data->mod_idx );
data->flags = 0;
if( sym->info & SYM_STATIC ) {
data->flags |= DBG_GBL_STATIC;
}
if( sym->p.seg != NULL ) {
if( sym->p.seg->u.leader->info & SEG_CODE ) {
data->flags |= DBG_GBL_CODE;
} else {
data->flags |= DBG_GBL_DATA;
}
}
DoName( name, data->name, len );
DumpInfo( dptr, data, entrylen );
dptr->global.size += entrylen;
}
}
extern void ODBIAddModule( mod_entry *obj, section *sect )
/********************************************************/
{
debug_info *dptr;
dptr = sect->dbg_info;
if( ( dptr == NULL ) || !( obj->modinfo & DBI_ALL ) )
return;
dptr->modnum++;
obj->d.o->modnum = dptr->modnum;
}
static void DoName( char *cname, char *intelname, int len )
/*********************************************************/
{
intelname[ 0 ] = len;
memcpy( &intelname[ 1 ], cname, len );
}
extern void ODBIP2Start( section * sect )
/***************************************/
/* initialize pointers for pass 2 processing */
{
debug_info *dptr;
if( sect == NonSect ) {
dptr = Root->dbg_info;
} else {
dptr = sect->dbg_info;
}
if( dptr != NULL ) {
dptr->DBIWrite = dptr->addr.curr;
SectWalkClass( sect, ODBIGenAddrInfo );
dptr->DBIWrite = dptr->line.curr;
dptr->modnum = 0;
}
}
static int CmpLn386( const void *a, const void *b )
/*************************************************/
{
return( ((ln_off_386 UNALIGN *)a)->off - ((ln_off_386 UNALIGN *)b)->off );
}
static int CmpLn286( const void *a, const void *b )
/*************************************************/
{
return( ((ln_off_286 *)a)->off - ((ln_off_286 *)b)->off );
}
static bool CheckFirst( void *_seg, void *_firstseg )
/***************************************************/
{
segdata *seg = _seg;
segdata **firstseg = _firstseg;
if( ( seg->a.delta < (*firstseg)->a.delta )
&& ( seg->addrinfo == (*firstseg)->addrinfo ) ) {
*firstseg = seg;
}
return( FALSE );
}
extern void ODBIGenLines( segdata * seg, void *lines, unsigned size,
bool is32bit )
/******************************************************************/
{
unsigned linelen;
ln_off_pair UNALIGN *pair;
ln_off_386 tmp_ln;
unsigned_32 temp;
unsigned lineqty;
debug_info *dinfo;
lineseg lseg;
segdata *firstseg;
unsigned_32 prevoff;
offset adjust;
bool needsort;
dinfo = CurrSect->dbg_info;
if( ( dinfo == NULL ) || !( CurrMod->modinfo & DBI_LINE ) )
return;
linelen = size;
lineqty = CalcLineQty( size, is32bit );
DoGenLocal( &dinfo->line, &dinfo->linelinks, &CurrMod->d.o->lines,
lineqty * sizeof( ln_off_386 ) + sizeof( lineseg ) );
lseg.segment = seg->addrinfo;
lseg.num = lineqty;
DumpInfo( dinfo, &lseg, sizeof( lineseg ) );
/*
fix the offset so that, together with modinfo.seg, it
represents the offset of that line in the image
also when we have multiple segdefs for the same segment, we collapse the
addr infos, so we have to adjust the line # offset to account for this.
*/
firstseg = Ring2Step( CurrMod->segs, NULL );
Ring2Lookup( CurrMod->segs, CheckFirst, &firstseg );
adjust = seg->a.delta - firstseg->a.delta;
pair = (ln_off_pair *) lines;
prevoff = 0;
needsort = FALSE;
if( is32bit ) {
while( size > 0 ) {
pair->_386.off += adjust;
if( prevoff > pair->_386.off ) {
needsort = TRUE;
}
prevoff = pair->_386.off;
pair = (void *)( (char *)pair + sizeof( ln_off_386 ) );
size -= sizeof( ln_off_386 );
}
if( needsort ) {
qsort( lines, lineqty, sizeof( ln_off_386 ), CmpLn386 );
}
DumpInfo( dinfo, lines, linelen );
} else {
while( size > 0 ) {
_TargU16toHost( pair->_286.off, temp );
if( prevoff > temp ) {
needsort = TRUE;
}
prevoff = temp;
pair = (void *)( (char *)pair + sizeof( ln_off_286 ) );
size -= sizeof( ln_off_286 );
}
if( needsort ) {
qsort( lines, lineqty, sizeof( ln_off_286 ), CmpLn286 );
}
pair = lines;
size = linelen;
while( size > 0 ) {
_TargU16toHost( pair->_286.off, temp );
_HostU32toTarg( temp + adjust, tmp_ln.off );
tmp_ln.linnum = pair->_286.linnum;
// NYI: might have to do some buffering here
DumpInfo( dinfo, &tmp_ln, sizeof( ln_off_386 ) );
pair = (void *)( (char *)pair + sizeof( ln_off_286 ) );
size -= sizeof( ln_off_286 );
}
}
}
static void ODBIAddAddrInit( segdata *sdata, void *cookie )
/*********************************************************/
{
cookie = cookie;
sdata->u.leader->num = 0;
}
static void ODBIAddAddrAdd( segdata *sdata, offset delta, offset size,
void *_dinfo, bool isnewmod )
/*******************************************************/
{
delta = delta;
size = size;
if( !isnewmod )
return;
((debug_info *)_dinfo)->addr.size += sizeof( addrinfo );
sdata->u.leader->num++;
}
extern void ODBIAddAddrInfo( seg_leader *seg )
/********************************************/
{
debug_info *dptr;
if( CurrSect == NonSect ) {
dptr = Root->dbg_info;
} else {
dptr = CurrSect->dbg_info;
}
if( dptr == NULL )
return;
DBIAddrInfoScan( seg, ODBIAddAddrInit, ODBIAddAddrAdd, dptr );
if( seg->num > 0 ) {
dptr->addr.size += sizeof( segheader );
}
}
static void ODBIGenAddrInit( segdata *sdata, void *_dinfo )
/********************************************************/
{
segheader seghdr;
seg_leader *seg;
debug_info *dptr = _dinfo;
seg = sdata->u.leader;
if( seg->group == NULL ) {
seghdr.off = seg->seg_addr.off;
seghdr.seg = seg->seg_addr.seg;
} else {
seghdr.off = seg->group->grp_addr.off
+ SUB_ADDR( seg->seg_addr, seg->group->grp_addr );
seghdr.seg = seg->group->grp_addr.seg;
}
seghdr.num = seg->num;
if( CurrSect == NonSect )
seghdr.num |= NON_SECT_INFO;
DumpInfo( dptr, &seghdr, sizeof( segheader ) );
dptr->addr.curr += sizeof( segheader );
}
static void ODBIGenAddrAdd( segdata *sdata, offset delta, offset size,
void *_dinfo, bool isnewmod )
/********************************************************************/
{
addrinfo addr;
debug_info *dptr = _dinfo;
delta = delta;
if( isnewmod ) {
addr.size = size;
addr.mod_idx = sdata->o.mod->d.o->modnum;
DumpInfo( dptr, &addr, sizeof( addrinfo ) );
sdata->addrinfo = dptr->addr.curr - dptr->addr.init;
dptr->addr.curr += sizeof( addrinfo );
} else {
sdata->addrinfo = dptr->addr.curr - dptr->addr.init;
}
}
static void ODBIGenAddrInfo( seg_leader *seg )
/********************************************/
{
debug_info *dptr;
if( CurrSect == NonSect ) {
dptr = Root->dbg_info;
} else {
dptr = CurrSect->dbg_info;
}
if( ( dptr == NULL ) || ( seg->num == 0 ) )
return;
DBIAddrInfoScan( seg, ODBIGenAddrInit, ODBIGenAddrAdd, dptr );
}
extern void ODBIFini( section *sect )
/***********************************/
// write out the final links in the link tables.
{
debug_info *dptr;
unsigned_32 spot;
if( sect == NonSect ) {
dptr = Root->dbg_info;
} else {
dptr = sect->dbg_info;
}
if( dptr != NULL ) {
if( ( dptr->local.size > 0 )
|| ( dptr->type.size > 0 )
|| ( dptr->line.size > 0 ) ) {
spot = dptr->line.start + ( dptr->line.curr - dptr->line.init );
PutInfo( dptr->linelinks.curr, &spot, sizeof( unsigned_32 ) );
}
}
}
extern void ODBIGenModule( void )
/*******************************/
{
odbimodinfo *rec;
modinfo *info;
int len;
char *name;
debug_info *dptr;
dptr = CurrSect->dbg_info;
if( ( dptr == NULL ) || !( CurrMod->modinfo & DBI_ALL ) )
return;
rec = CurrMod->d.o;
name = CurrMod->name;
len = strlen( name );
info = (modinfo *) alloca( len + sizeof( modinfo ) );
_HostU16toTarg( rec->types.num, info->types.len );
_HostU32toTarg( rec->types.offset, info->types.off );
_HostU16toTarg( rec->locals.num, info->locals.len );
_HostU32toTarg( rec->locals.offset, info->locals.off );
_HostU16toTarg( rec->lines.num, info->lines.len );
_HostU32toTarg( rec->lines.offset, info->lines.off );
DoName( name, info->name, len );
info->language = rec->dbisourceoffset;
PutInfo( dptr->mod.curr, (char *)info, len + sizeof( modinfo ) );
dptr->mod.curr += len + sizeof( modinfo );
dptr->modnum++;
}
extern void ODBISectCleanup( section *sect )
/******************************************/
{
sect = sect;
_PermFree( sect->dbg_info );
}
static void DBIWriteInfo( virt_mem stg, unsigned long len )
/*********************************************************/
{
if( len == 0 )
return;
DBISize += len;
WriteInfo( stg, len );
}
static void DBIWriteLocal( void *buff, unsigned len )
/***************************************************/
{
if( len == 0 )
return;
DBISize += len;
WriteLoad( buff, len );
}
static unsigned_16 WriteSegValues( void )
/***************************************/
// write out all possible group segment values
{
unsigned_16 segarray[2];
group_entry * currgrp;
unsigned_16 * buffer;
unsigned_16 buflen;
if( FmtData.type & MK_FLAT ) {
segarray[0] = 1;
DBIWriteLocal( segarray, sizeof( unsigned_16 ) );
return( sizeof( unsigned_16 ) );
} else if( FmtData.type & MK_ID_SPLIT ) {
segarray[0] = CODE_SEGMENT;
segarray[1] = DATA_SEGMENT;
DBIWriteLocal( segarray, sizeof( unsigned_16 ) * 2 );
return( sizeof( unsigned_16 ) * 2 );
} else {
buffer = (unsigned_16 *) TokBuff;
buflen = 0;
for( currgrp = Groups; currgrp != NULL; currgrp = currgrp->next_group ) {
*buffer++ = currgrp->grp_addr.seg;
buflen += sizeof( unsigned_16 );
}
DBIWriteLocal( TokBuff, buflen );
return( buflen );
}
}
extern void OWriteDBI( void )
/***************************/
/* copy debugging info from extra memory to loadfile */
{
snamelist * node;
snamelist * nextnode;
CurrSect = Root;
Master.lang_size = 0;
node = DBISourceLang;
while( node != NULL ) {
Master.lang_size += node->len + 1;
DBIWriteLocal( node->name, node->len + 1 ); // +1 for nullchar
nextnode = node->next;
_PermFree( node );
node = nextnode;
}
DBISourceLang = NULL;
Master.seg_size = WriteSegValues();
ProcAllSects( WriteDBISecs );
Master.debug_size = DBISize;
if( Master.obj_major_ver == 0 )
Master.obj_major_ver = 1;
WriteLoad( &Master, sizeof( dbgheader ) );
#ifdef _INT_DEBUG
if( TraceInfo.sizeadded != TraceInfo.sizegenned ) {
LnkMsg( WRN+MSG_INTERNAL, "s", "size mismatch in watcom dbi" );
}
#endif
}
extern void WriteDBISecs( section *sec )
/**************************************/
{
debug_info *dptr;
sectheader header;
unsigned long pos;
dptr = sec->dbg_info;
if( dptr != NULL ) {
header.section_size = dptr->addr.start + dptr->addr.size;
header.mod_offset = dptr->mod.start;
header.gbl_offset = dptr->global.start;
header.addr_offset = dptr->addr.start;
header.section_id = sec->ovl_num;
DBIWriteLocal( &header, sizeof( sectheader ) );
DBIWriteInfo( dptr->locallinks.init, dptr->locallinks.size );
DBIWriteInfo( dptr->typelinks.init, dptr->typelinks.size );
DBIWriteInfo( dptr->linelinks.init, dptr->linelinks.size );
pos = PosLoad();
if( dptr->LocalClass != NULL ) {
RingWalk( dptr->LocalClass->segs, WriteLeaderLoad );
}
if( dptr->TypeClass != NULL ) {
RingWalk( dptr->TypeClass->segs, WriteLeaderLoad );
}
DBISize += PosLoad() - pos;
DBIWriteInfo( dptr->line.init, dptr->line.size );
DBIWriteInfo( dptr->mod.init, dptr->mod.size );
DBIWriteInfo( dptr->global.init, dptr->global.size );
DBIWriteInfo( dptr->addr.init, dptr->addr.size );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?