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