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 + -
显示快捷键?