dbgcv.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 748 行 · 第 1/2 页
C
748 行
size = ROUND_UP( size + strlen( sym->name ) + 1, 4 );
CurrMod->d.cv->pubsize += size;
SectAddrs[CVSECT_MISC] += size;
}
}
extern void CVGenGlobal( symbol * sym, section *sect )
/****************************************************/
// called during symbol address calculation (between pass 1 & pass 2)
// also called by loadpe between passes
{
s_pub16 pub16;
s_pub32 pub32;
unsigned size;
unsigned pad;
unsigned_32 buf;
byte namelen;
sect = sect;
if( sym->info & SYM_STATIC )
return;
namelen = strlen( sym->name );
size = namelen + 1;
if( ( sym->p.seg == NULL )
|| IS_SYM_IMPORTED( sym )
|| sym->p.seg->is32bit ) {
size += sizeof( s_pub32 );
pub32.common.length = ROUND_UP( size, 4 );
pad = pub32.common.length - size;
pub32.common.length -= 2;
pub32.common.code = S_PUB32;
pub32.f.offset = sym->addr.off;
pub32.f.segment = GetCVSegment( sym->p.seg->u.leader );
pub32.f.type = 0;
DumpInfo( CVSECT_MISC, &pub32, sizeof( s_pub32 ) );
} else {
size += sizeof( s_pub16 );
pub16.common.length = ROUND_UP( size, 4 );
pad = pub16.common.length - size;
pub16.common.length -= 2;
pub16.common.code = S_PUB16;
pub16.f.offset = sym->addr.off;
pub16.f.segment = GetCVSegment( sym->p.seg->u.leader );
pub16.f.type = 0;
DumpInfo( CVSECT_MISC, &pub16, sizeof( s_pub16 ) );
}
DumpInfo( CVSECT_MISC, &namelen, 1 );
DumpInfo( CVSECT_MISC, sym->name, namelen );
if( pad > 0 ) {
buf = 0;
DumpInfo( CVSECT_MISC, &buf, pad );
}
}
static void GenSrcModHeader( void )
/*********************************/
// emit header for line number information now that we know where everything
// is.
{
cheesy_module_header mod_hdr;
cheesy_file_table file_tbl;
cheesy_mapping_table map_tbl;
unsigned adjust;
unsigned_32 buff;
if( LineInfo.linestart == 0 )
return;
memset( &mod_hdr, 0, sizeof( mod_hdr ) );
mod_hdr.cFile = 1;
mod_hdr.cSeg = 1;
mod_hdr.range[0] = LineInfo.range;
mod_hdr.baseSrcFile[0] = sizeof( mod_hdr );
mod_hdr.seg[0] = LineInfo.seg;
mod_hdr.pad = 0;
PutInfo( LineInfo.linestart, &mod_hdr, sizeof( mod_hdr ) );
LineInfo.linestart += sizeof( mod_hdr );
file_tbl.cSeg = 1;
file_tbl.pad = 0;
file_tbl.range[0] = LineInfo.range;
file_tbl.name[0] = strlen( CurrMod->name );
file_tbl.baseSrcLn[0] = sizeof( mod_hdr ) +
ROUND_UP( sizeof( file_tbl ) + file_tbl.name[0], 4 );
PutInfo( LineInfo.linestart, &file_tbl, sizeof( file_tbl ) );
LineInfo.linestart += sizeof( file_tbl );
PutInfo( LineInfo.linestart, CurrMod->name, file_tbl.name[0] );
LineInfo.linestart += file_tbl.name[0];
adjust = file_tbl.baseSrcLn[0] - sizeof( mod_hdr ) - sizeof( file_tbl )
- file_tbl.name[0];
if( adjust != 0 ) {
buff = 0;
PutInfo( LineInfo.linestart, &buff, adjust );
LineInfo.linestart += adjust;
}
map_tbl.Seg = mod_hdr.seg[0];
map_tbl.cPair = CurrMod->d.cv->numlines;
PutInfo( LineInfo.linestart, &map_tbl, sizeof( map_tbl ) );
memset( &LineInfo, 0, sizeof( LineInfo ) );
}
extern void CVGenLines( segdata * seg, void *lines, unsigned size, bool is32bit )
/*******************************************************************************/
// called during pass 2 linnum processing
{
ln_off_pair UNALIGN *pair;
unsigned_32 temp_off;
unsigned_16 temp_num;
offset adjust;
unsigned long cvsize;
if( !( CurrMod->modinfo & DBI_LINE ) )
return;
adjust = seg->a.delta + seg->u.leader->seg_addr.off;
if( LineInfo.offbase == 0 ) { // this is our first time through.
LineInfo.seg = GetCVSegment( seg->u.leader );
LineInfo.linestart = SectAddrs[CVSECT_MISC];
cvsize = sizeof( cheesy_module_header ) + sizeof( cheesy_mapping_table )
+ ROUND_UP( sizeof( cheesy_file_table ) + strlen( CurrMod->name ), 4 );
LineInfo.offbase = SectAddrs[CVSECT_MISC] + cvsize;
LineInfo.numbase = LineInfo.offbase
+ CurrMod->d.cv->numlines * sizeof( unsigned_32 );
cvsize += CurrMod->d.cv->numlines * sizeof( unsigned_32 );
cvsize += ROUND_UP( CurrMod->d.cv->numlines * sizeof( unsigned_16 ), 4 );
GenSubSection( sstSrcModule, cvsize );
SectAddrs[CVSECT_MISC] += cvsize;
LineInfo.range.start = adjust;
LineInfo.range.end = adjust + seg->length;
} else {
if( adjust < LineInfo.range.start ) {
LineInfo.range.start = adjust;
}
if( adjust + seg->length > LineInfo.range.end ) {
LineInfo.range.end = adjust + seg->length;
}
}
pair = lines;
if( is32bit ) {
while( size > 0 ) {
pair->_386.off += adjust;
if( pair->_386.off < LineInfo.prevaddr ) {
LineInfo.needsort = TRUE;
}
LineInfo.prevaddr = pair->_386.off;
_HostU32toTarg( pair->_386.off, temp_off );
_HostU16toTarg( pair->_386.linnum, temp_num );
PutInfo( LineInfo.offbase, &temp_off, sizeof( unsigned_32 ) );
PutInfo( LineInfo.numbase, &temp_num, sizeof( unsigned_16 ) );
LineInfo.offbase += sizeof( unsigned_32 );
LineInfo.numbase += sizeof( unsigned_16 );
pair = (void *)( (char *)pair + sizeof( ln_off_386 ) );
size -= sizeof( ln_off_386 );
}
} else {
while( size > 0 ) {
pair->_286.off += adjust;
if( pair->_286.off < LineInfo.prevaddr ) {
LineInfo.needsort = TRUE;
}
LineInfo.prevaddr = pair->_286.off;
_HostU16toTarg( pair->_286.off, temp_off );
_HostU16toTarg( pair->_286.linnum, temp_num );
PutInfo( LineInfo.offbase, &temp_off, sizeof( unsigned_32 ) );
PutInfo( LineInfo.numbase, &temp_num, sizeof( unsigned_16 ) );
LineInfo.offbase += sizeof( unsigned_32 );
LineInfo.numbase += sizeof( unsigned_16 );
pair = (void *)( (char *)pair + sizeof( ln_off_286 ) );
size -= sizeof( ln_off_286 );
}
}
}
static void CVAddAddrInit( segdata *sdata, void *cookie )
/*******************************************************/
{
sdata = sdata;
cookie = cookie;
}
static void CVAddAddrAdd( segdata *sdata, offset delta, offset size,
void *cookie, bool isnewmod )
/******************************************************************/
{
delta = delta;
size = size;
cookie = cookie;
if( !isnewmod )
return;
sdata->o.mod->d.cv->numsegs++;
SectAddrs[CVSECT_MODULE] += sizeof( cv_seginfo );
}
extern void CVAddAddrInfo( seg_leader *seg )
/******************************************/
{
if( !( seg->info & SEG_CODE ) )
return;
DBIAddrInfoScan( seg, CVAddAddrInit, CVAddAddrAdd, NULL );
}
static void CVGenAddrInit( segdata *sdata, void *_info )
/******************************************************/
{
cv_seginfo *info = _info;
info->Seg = GetCVSegment( sdata->u.leader );
info->pad = 0;
info->offset = sdata->u.leader->seg_addr.off + sdata->a.delta;
}
static void CVGenAddrAdd( segdata *sdata, offset delta, offset size,
void *_info, bool isnewmod )
/******************************************************************/
{
cv_seginfo *info = _info;
if( !isnewmod )
return;
info->cbSeg = size;
PutInfo( sdata->o.mod->d.cv->segloc, info, sizeof( cv_seginfo ) );
sdata->o.mod->d.cv->segloc += sizeof( cv_seginfo );
info->offset = sdata->u.leader->seg_addr.off + delta;
}
extern void CVGenAddrInfo( seg_leader *seg )
/******************************************/
{
cv_seginfo info;
if( !( seg->info & SEG_CODE ) )
return;
DBIAddrInfoScan( seg, CVGenAddrInit, CVGenAddrAdd, &info );
}
extern void CVDefClass( class_entry *class, unsigned_32 size )
/************************************************************/
{
group_entry *group;
if( ( class->flags & CLASS_DEBUG_INFO ) == CLASS_DWARF )
return;
SectAddrs[CVSECT_MISC] += size;
group = AllocGroup( AutoGrpName, &DBIGroups );
group->g.class = class;
group->grp_addr.seg = 0;
}
static void DefLocal( void *_sdata )
/**********************************/
/* NOTE: this assumes that codeview segments are byte aligned! */
{
segdata *sdata = _sdata;
seg_leader *leader;
sst sect;
leader = sdata->u.leader;
if( !sdata->isdead && ( leader->dbgtype != NOT_DEBUGGING_INFO ) ) {
if( leader->dbgtype == MS_TYPE ) {
sect = sstTypes;
} else {
sect = sstSymbols;
}
CurrMod = sdata->o.mod;
GenSubSection( sect, sdata->length );
CopyInfo( SectAddrs[CVSECT_MISC], sdata->data, sdata->length );
sdata->data = SectAddrs[CVSECT_MISC]; // FIXME: inefficient
SectAddrs[CVSECT_MISC] += sdata->length;
}
}
static bool DefLeader( void *_leader, void *group )
/*************************************************/
{
seg_leader *leader = _leader;
leader->group = group;
RingWalk( leader->pieces, DefLocal );
return( FALSE );
}
extern void CVAddrStart( void )
/*****************************/
{
cv_subsection_directory dir;
int index;
cv_trailer start;
virt_mem currpos;
unsigned_32 size;
unsigned_32 numentries;
group_entry *group;
AddSubSection( FALSE ); // for sstSegMap
numentries = ( SectAddrs[CVSECT_MODDIR] + SectAddrs[CVSECT_DIRECTORY] )
/ sizeof( cv_directory_entry );
SectAddrs[CVSECT_MISC] += sizeof( cv_sst_seg_map )
+ ( NumGroups - 1 ) * sizeof( seg_desc );
SectAddrs[CVSECT_MODDIR] += sizeof( cv_subsection_directory );
CVSize = 2 * sizeof( cv_trailer );
for( index = 0; index < NUM_CV_SECTS; index++ ) {
CVSize += SectAddrs[index];
}
CVBase = DBIAlloc( CVSize );
currpos = CVBase + sizeof( cv_trailer );
for( index = 0; index < NUM_CV_SECTS; index++ ) {
size = SectAddrs[index];
SectAddrs[index] = currpos;
currpos += size;
}
memcpy( start.sig, CV4_NB05, CV_SIG_SIZE );
start.offset = SectAddrs[CVSECT_MODDIR] - CVBase;
PutInfo( CVBase, &start, sizeof( cv_trailer ) );
start.offset = CVSize;
PutInfo( CVBase + CVSize - sizeof( cv_trailer ), &start, sizeof( cv_trailer ) );
dir.cbDirHeader = sizeof( cv_subsection_directory );
dir.cbDirEntry = sizeof( cv_directory_entry );
dir.cDir = numentries;
dir.lfoNextDir = 0;
dir.flags = 0;
DumpInfo( CVSECT_MODDIR, &dir, sizeof( cv_subsection_directory ) );
for( group = DBIGroups; group != NULL; group = group->next_group ) {
RingLookup( group->g.class->segs, DefLeader, group );
group->g.class = NULL;
}
}
extern void CVFini( section *sect )
/*********************************/
// called after pass 2 is finished, but before load file generation
{
cv_sst_seg_map map;
seg_desc desc;
group_entry * group;
seg_leader * leader;
if( sect != Root )
return;
CurrMod = NULL;
GenSubSection( sstSegMap, sizeof( cv_sst_seg_map )
+ ( NumGroups - 1 ) * sizeof( seg_desc ) );
map.cSeg = NumGroups;
map.cSegLog = NumGroups;
DumpInfo( CVSECT_MISC, &map, sizeof( cv_sst_seg_map ) - sizeof( seg_desc ) );
memset( &desc, 0, sizeof( seg_desc ) );
desc.u.b.fSel = !( LinkFlags & MK_REAL_MODE );
desc.u.b.fRead = TRUE;
desc.iSegName = 0xFFFF;
desc.iClassName = 0xFFFF;
for( group = Groups; group != NULL; group = group->next_group ) {
desc.frame = group->grp_addr.seg;
desc.offset = group->grp_addr.off;
desc.cbseg = group->totalsize;
if( !( group->segflags & SEG_DATA ) ) {
desc.u.b.fExecute = 1;
} else {
desc.u.b.fExecute = 0;
}
if( ( group->segflags & ( SEG_DATA | SEG_READ_ONLY ) ) == SEG_DATA ) {
desc.u.b.fWrite = 1;
} else {
desc.u.b.fWrite = 0;
}
leader = Ring2First( group->leaders );
if( leader->info & USE_32 ) {
desc.u.b.f32Bit = 1;
}
desc.u.b.fSel = 1;
DumpInfo( CVSECT_MISC, &desc, sizeof( seg_desc ) );
}
}
extern void CVWriteDBI( void )
/****************************/
// called during load file generation. It is assumed that the loadfile is
// positioned to the right spot.
{
WriteInfo( CVBase, CVSize );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?