dbgall.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 589 行 · 第 1/2 页

C
589
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  General routines for producing debugging information in
*               load file.
*
****************************************************************************/


#include <string.h>
#include "linkstd.h"
#include "alloc.h"
#include "specials.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "fileio.h"
#include "virtmem.h"
#include "exeelf.h"
#include "objcalc.h"
#include "loadfile.h"
#include "objio.h"
#include "dbgcv.h"
#include "objfree.h"
#include "overlays.h"
#include "dbgdwarf.h"
#include "dbgwat.h"
#include "ring.h"
#include "loadnov.h"
#include "dbgcomm.h"
#include "dbgall.h"

char *          SymFileName;
group_entry *   DBIGroups;

static void     DBIGenLocal( void * );
static void     DBIGenLines( mod_entry *mod );

extern void ResetDBI( void )
/**************************/
{
    SymFileName = NULL;
    DBIGroups = NULL;
}

extern void DBIInit( void )
/*************************/
// called just after command file parsing
{
    if( LinkFlags & OLD_DBI_FLAG ) {
        ODBIInit( Root );
    } else if( LinkFlags & CV_DBI_FLAG ) {
        CVInit();
    } else if( LinkFlags & DWARF_DBI_FLAG ) {
        DwarfInit();
    }
}

extern void DBISectInit( section *sect )
/**************************************/
// called when a section created in command file parsing
{
    if( LinkFlags & OLD_DBI_FLAG ) {
        ODBIInit( sect );
    }
}

extern void DBIInitModule( mod_entry *obj )
/*****************************************/
// called before pass 1 is done on the module
{
    if( LinkFlags & OLD_DBI_FLAG ) {
        ODBIInitModule( obj );
    } else if( LinkFlags & DWARF_DBI_FLAG ) {
        DwarfInitModule( obj );
    } else if( LinkFlags & CV_DBI_FLAG ) {
        CVInitModule( obj );
    }
}

extern void DBIP1Source( byte *buff, byte *endbuff )
/**************************************************/
{
    int         len;
    byte        major;
    byte        minor;

    major = *buff++;
    minor = *buff++;
    len = endbuff - buff;
    if( len <= 0 ) {
        BadObject();
        return;
    }
    ObjFormat |= FMT_DEBUG_COMENT;
    if( LinkFlags & OLD_DBI_FLAG ) {
        ODBIP1Source( major, minor, buff, len );
    }
}

extern section * DBIGetSect( char *clname )
/*****************************************/
{
    if( ( stricmp( clname, _MSTypeClass ) == 0 )
        || ( stricmp( clname, _MSLocalClass ) == 0 ) ) {
        return( CurrSect );
    } else if( stricmp( clname, _DwarfClass ) == 0 ) {
        return( Root );
    }
    return( NULL );
}

extern void DBIColClass( class_entry *class )
/*******************************************/
{
    bool        isdbi;

    isdbi = TRUE;
    if( stricmp( class->name, _DwarfClass ) == 0 ) {
        class->flags |= CLASS_DWARF;
    } else if( stricmp( class->name, _MSTypeClass ) == 0 ) {
        class->flags |= CLASS_MS_TYPE;
    } else if( stricmp( class->name, _MSLocalClass ) == 0 ) {
        class->flags |= CLASS_MS_LOCAL;
    } else {
        isdbi = FALSE;
    }
}

extern unsigned_16 DBIColSeg( class_entry *class )
/************************************************/
{
    switch( class->flags & CLASS_DEBUG_INFO ) {
    case CLASS_DWARF:
        if( CurrMod->modinfo & DBI_TYPE ) {
            CurrMod->modinfo |= MOD_DBI_SEEN;
        }
        return( DWARF_DEBUG_OTHER );       // assume other until later.
    case CLASS_MS_TYPE:
        return( MS_TYPE );
    case CLASS_MS_LOCAL:
        return( MS_LOCAL );
    }
    return( NOT_DEBUGGING_INFO );
}

extern void DBIP1ModuleScanned( void )
/************************************/
// called in pass 1 when finished looking at a module
// if some segdefs have been delayed due to distributing libraries, this
// will be called twice (once when regular pass 1 is done, once when all
// segdefs processed
{
    if( LinkFlags & OLD_DBI_FLAG ) {
        ODBIP1ModuleScanned();
    } else if( LinkFlags & DWARF_DBI_FLAG ) {
        DwarfP1ModuleScanned();
    } else if( LinkFlags & CV_DBI_FLAG ) {
        CVP1ModuleScanned();
    }
}

static bool MSSkip( void )
/************************/
{
    bool        iscv;
    bool        seencmt;

    if( !( ObjFormat & FMT_OMF ) ) {
        return( LinkFlags & DWARF_DBI_FLAG );
    } else {
        iscv = ( LinkFlags & CV_DBI_FLAG ) != 0;
        seencmt = ( ObjFormat & FMT_DEBUG_COMENT ) != 0;
        return( !( iscv ^ seencmt ) || ( LinkFlags & DWARF_DBI_FLAG ) );
    }
}

extern bool DBISkip( unsigned_16 info )
/*************************************/
// returns TRUE we should skip processing this segment because we are
// ignoring debugging information
{
    switch( info ) {
    case MS_TYPE:
        return( !( CurrMod->modinfo & DBI_TYPE ) || MSSkip() );
    case MS_LOCAL:
        return( !( CurrMod->modinfo & DBI_LOCAL ) || MSSkip() );
    case NOT_DEBUGGING_INFO:
        return( FALSE );
    default:
        return( !( CurrMod->modinfo & DBI_TYPE ) || !( LinkFlags & DWARF_DBI_FLAG ) );
    }
}

extern bool DBINoReloc( unsigned_16 info )
/****************************************/
// called to see if we should handle a relocation specially.
{
    return( info != NOT_DEBUGGING_INFO );
}

static void AddNovGlobals( mod_entry *mod )
/*****************************************/
{
#ifdef _NOVELL
    Ring2Walk( mod->publist, NovDBIAddGlobal );
#endif
}

extern void DBIPreAddrCalc( void )
/********************************/
{
    void (*modptr)( mod_entry * );
    void (*segptr)( seg_leader * );

    if( LinkFlags & NOVELL_DBI_FLAG ) {
        WalkMods( AddNovGlobals );
    }
    if( !( LinkFlags & ANY_DBI_FLAG ) )
        return;
    if( LinkFlags & OLD_DBI_FLAG ) {
        modptr = ODBIP1ModuleFinished;
        segptr = ODBIAddAddrInfo;
    } else if( LinkFlags & DWARF_DBI_FLAG ) {
        modptr = DwarfP1ModuleFinished;
        segptr = DwarfAddAddrInfo;
    } else {
        modptr = CVP1ModuleFinished;
        segptr = CVAddAddrInfo;
    }
    WalkMods( modptr );
    WalkLeaders( segptr );
    if( LinkFlags & DWARF_DBI_FLAG ) {
        WalkMods( DwarfStoreAddrInfo );
    }
}

extern void DBIAddrInfoScan( seg_leader *seg,
                         void (*initfn)( segdata *, void * ),
                         void (*addfn)( segdata *, offset, offset, void *, bool ),
                         void * cookie )
/********************************************************************************/
{
    segdata *   prev;
    segdata *   curr;
    offset      size;
    bool        isnewmod;

    if( seg->dbgtype != NOT_DEBUGGING_INFO )
        return;
    if( ( seg->class->flags & ( CLASS_STACK | CLASS_IDATA ) )
        && ( FmtData.dll || ( FmtData.type & MK_PE ) ) )
        return;
    prev = RingStep( seg->pieces, NULL );
    for( ; ; ) {
        if( prev == NULL )
            return;
        if( !prev->isdead )
            break;
        prev = RingStep( seg->pieces, prev );
    }
    initfn( prev, cookie );
    size = 0;
    curr = RingStep( seg->pieces, prev );
    while( curr != NULL ) {
        if( !curr->isdead ) {
            size += curr->a.delta - prev->a.delta;
            isnewmod = ( ( curr->o.mod != prev->o.mod ) && ( size != 0 ) );
            addfn( prev, curr->a.delta, size, cookie, isnewmod );
            if( isnewmod ) {
                size = 0;
            }
            prev = curr;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?