dbginfo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 899 行 · 第 1/2 页
C
899 行
/****************************************************************************
*
* 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: Produce Watcom style debugging information in load file.
*
****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "walloca.h"
#include "linkstd.h"
#include "pcobj.h"
#include "alloc.h"
#include "dbginfo.h"
#include "newmem.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "virtmem.h"
#include "objnode.h"
#include "loadfile.h"
#include "objcalc.h"
#include "objomf.h"
#include "overlays.h"
#include "specials.h"
#include "ring.h"
#include "dbgwat.h"
#include "dbgcomm.h"
#define EXE_MAJOR_VERSION 3
#define EXE_MINOR_VERSION 0
#define ADDR_INFO_LIMIT ( 63 * 1024U / sizeof( addrinfo ) )
#define DEMAND_INFO_SPLIT ( 16 * 1024 )
#define NON_SECT_INFO 0x8000
typedef struct {
unsigned_32 offset;
unsigned_16 num;
unsigned_16 size;
} demanddata;
typedef struct odbimodinfo {
unsigned_32 linelinksize;
demanddata types;
demanddata locals;
demanddata lines;
unsigned_32 modnum;
unsigned dbisourceoffset;
} odbimodinfo;
typedef struct seginfo {
struct seginfo *next;
unsigned_32 dbioff;
segheader head;
unsigned_32 endoflast;
seg_leader * prevlead;
seg_leader * final;
byte nonsect : 1;
byte full : 1;
byte finished : 1;
} seginfo;
typedef struct snamelist { // source name list
struct snamelist * next;
byte len; // length of the name
char name[1]; // stored WITH a nullchar
} snamelist;
static unsigned_32 DBISize;
static dbgheader Master; // rest depend on .obj files.
static snamelist * DBISourceLang; // list of source languages
static void ReadSegInfo( section *, void ** );
static snamelist * LangAlloc( byte len, void *buff );
static void ODBIGenAddrInfo( seg_leader * );
static void AllocDBIClasses( class_entry *class );
static void NewArea( section *sect );
static void DoName( char *cname, char *intelname, int len );
#ifdef _INT_DEBUG
struct {
offset sizeadded;
offset sizegenned;
} TraceInfo;
#endif
extern void ODBIInit( section *sect )
/***********************************/
{
DBISize = sizeof( dbgheader );
Master.signature = DBG_SIGNATURE;
Master.exe_major_ver = EXE_MAJOR_VERSION;
Master.exe_minor_ver = EXE_MINOR_VERSION;
Master.obj_major_ver = 0;
Master.obj_minor_ver = 0;
DBISourceLang = LangAlloc( 1, "C" );
DBISourceLang->next = NULL;
_PermAlloc( sect->dbg_info, sizeof( debug_info ) );
memset( sect->dbg_info, 0, sizeof( debug_info ) ); //assumes NULL == 0
#ifdef _INT_DEBUG
memset( &TraceInfo, 0, sizeof( TraceInfo ) );
#endif
}
extern void ODBIInitModule( mod_entry *mod )
/******************************************/
{
if( CurrSect->dbg_info == NULL )
return;
_PermAlloc( mod->d.o, sizeof( odbimodinfo ) );
memset( mod->d.o, 0, sizeof( odbimodinfo ) );
}
static void DumpInfo( debug_info *dinfo, void *data, unsigned len )
/*****************************************************************/
{
PutInfo( dinfo->DBIWrite, data, len );
dinfo->DBIWrite += len;
}
static bool FindMatch( byte len, void *buff, unsigned *offset )
/*************************************************************/
// returns FALSE if not found
{
snamelist * node;
node = DBISourceLang;
*offset = 0;
while( node != NULL ) {
if( node->len == len ) {
if( memicmp( buff, node->name, len ) == 0 ) {
return( TRUE );
}
}
*offset += node->len + 1; // +1 for NULLCHAR
node = node->next;
}
return( FALSE );
}
static snamelist * LangAlloc( byte len, void *buff )
/**************************************************/
{
snamelist *node;
_PermAlloc( node, sizeof( snamelist ) + len );
node->len = len;
memcpy( node->name, buff, len );
node->name[len] = '\0';
return( node );
}
extern void ODBIP1Source( byte major, byte minor, char *name, int len )
/*********************************************************************/
{
snamelist * node;
if( Master.obj_major_ver == 0 )
Master.obj_major_ver = major;
if( major != Master.obj_major_ver ) {
LnkMsg( LOC+WRN+MSG_CANT_USE_LOCALS, NULL );
CurrMod->modinfo &= ~( DBI_TYPE | DBI_LOCAL );
}
if( minor > Master.obj_minor_ver ) {
Master.obj_minor_ver = minor;
}
if( !FindMatch( len, name, &CurrMod->d.o->dbisourceoffset ) ) {
node = LangAlloc( len, name );
node->next = DBISourceLang->next;
DBISourceLang->next = node; // keep "C" the first entry.
}
}
static void DoAddLocal( dbi_section * dbi, offset length )
/********************************************************/
{
if( ( dbi->size == 0 ) || ( dbi->size + length > DEMAND_INFO_SPLIT ) ) {
dbi->curr += sizeof( unsigned_32 );
dbi->size = 0;
}
dbi->size += length;
#ifdef _INT_DEBUG
TraceInfo.sizeadded += length;
#endif
}
extern void ODBIAddLocal( unsigned_16 info, offset length )
/*********************************************************/
{
debug_info *dinfo;
dinfo = CurrSect->dbg_info;
if( dinfo == NULL )
return;
if( info == MS_TYPE ) {
DEBUG(( DBG_DBGINFO, "adding type info %h", length ));
DoAddLocal( &dinfo->typelinks, length );
} else if( info == MS_LOCAL ) {
DEBUG(( DBG_DBGINFO, "adding local info %h", length ));
DoAddLocal( &dinfo->locallinks, length );
}
}
extern void ODBIP1ModuleScanned( void )
/*************************************/
{
debug_info *dinfo;
dinfo = CurrSect->dbg_info;
if( dinfo == NULL )
return;
dinfo->typelinks.size = 0;
dinfo->locallinks.size = 0;
}
static void DoGenLocal( dbi_section *dsect, dbi_section * dlink,
demanddata * dmod, offset length )
/**************************************************************/
{
unsigned_32 spot;
if( ( dmod->size == 0 )
|| ( dmod->size + length > DEMAND_INFO_SPLIT ) ) {
spot = dsect->start + ( dsect->curr - dsect->init );
PutInfo( dlink->curr, &spot, sizeof( unsigned_32 ) );
dmod->num++;
if( dmod->size == 0 ) {
dmod->offset = dlink->start + ( dlink->curr - dlink->init );
} else {
dmod->size = 0;
}
dlink->curr += sizeof( unsigned_32 );
}
dsect->curr += length;
dmod->size += length;
#ifdef _INT_DEBUG
TraceInfo.sizegenned += length;
#endif
}
extern void ODBIGenLocal( segdata *sdata )
/****************************************/
{
debug_info *dinfo;
odbimodinfo *minfo;
dinfo = CurrSect->dbg_info;
if( dinfo == NULL )
return;
if( sdata->isdead )
return;
minfo = CurrMod->d.o;
if( sdata->u.leader->dbgtype == MS_TYPE ) {
DEBUG(( DBG_DBGINFO, "genning type info %h", sdata->length ));
DoGenLocal( &dinfo->type, &dinfo->typelinks, &minfo->types,
sdata->length );
} else if( sdata->u.leader->dbgtype == MS_LOCAL ) {
DEBUG(( DBG_DBGINFO, "genning local info %h", sdata->length ));
DoGenLocal( &dinfo->local, &dinfo->locallinks, &minfo->locals,
sdata->length );
}
}
static void ODBIAddLines( segdata * seg, void *lines, unsigned size,
bool is32bit )
/******************************************************************/
{
unsigned lineqty;
unsigned_32 linesize;
debug_info *dinfo;
lines = lines;
seg = seg;
dinfo = CurrSect->dbg_info;
lineqty = CalcLineQty( size, is32bit );
linesize = lineqty * sizeof( ln_off_386 ) + sizeof( lineseg );
dinfo->line.curr += linesize;
DoAddLocal( &dinfo->linelinks, linesize );
}
extern void ODBIP1ModuleFinished( mod_entry *obj )
/************************************************/
{
debug_info *dinfo;
dinfo = CurrSect->dbg_info;
if( ( dinfo == NULL ) || !( obj->modinfo & DBI_ALL ) )
return;
if( MOD_NOT_DEBUGGABLE( obj ) )
return;
CurrMod = obj;
if( CurrMod->modinfo & DBI_LINE ) {
DBILineWalk( obj->lines, ODBIAddLines );
}
Ring2Walk( obj->publist, DBIModGlobal );
dinfo->mod.curr += strlen( obj->name ) + sizeof( modinfo );
dinfo->linelinks.size = 0;
}
extern void ODBIDefClass( class_entry *cl, unsigned_32 size )
/***********************************************************/
{
debug_info *dinfo;
dinfo = CurrSect->dbg_info;
if( dinfo == NULL )
return;
if( cl->flags & CLASS_MS_TYPE ) {
dinfo->type.curr += size;
dinfo->TypeClass = cl;
} else if( cl->flags & CLASS_MS_LOCAL ) {
dinfo->local.curr += size;
dinfo->LocalClass = cl;
}
}
static int ODBISymIsForGlobalDebugging( symbol *sym, mod_entry *currMod )
/***********************************************************************/
{
return( !( CurrMod->modinfo & DBI_ONLY_EXPORTS )
&& ( ( CurrMod->modinfo & DBI_STATICS ) || !( sym->info & SYM_STATIC ) ) );
}
extern void ODBIAddGlobal( symbol *sym )
/**************************************/
{
debug_info *dinfo;
unsigned add;
dinfo = CurrSect->dbg_info;
if( dinfo == NULL )
return;
if( ODBISymIsForGlobalDebugging( sym, CurrMod ) ) {
add = strlen( sym->name );
if( add > 255 ) {
LnkMsg( WRN+MSG_SYMBOL_NAME_TOO_LONG, "s", sym->name );
add = 255;
}
dinfo->global.curr += add + sizeof( gblinfo );
}
}
extern void ODBIAddrSectStart( section *sect )
/********************************************/
{
debug_info *dptr;
dptr = sect->dbg_info;
if( dptr == NULL )
return;
if( ( dptr->local.curr > 0 )
|| ( dptr->type.curr > 0 )
|| ( dptr->line.curr > 0 ) ) {
dptr->linelinks.curr += sizeof( unsigned_32 );
}
dptr->locallinks.start = sizeof( sectheader );
dptr->locallinks.size = dptr->locallinks.curr;
dptr->locallinks.curr = DBIAlloc( dptr->locallinks.curr );
dptr->locallinks.init = dptr->locallinks.curr;
dptr->typelinks.start = dptr->locallinks.start + dptr->locallinks.size;
dptr->typelinks.size = dptr->typelinks.curr;
dptr->typelinks.curr = DBIAlloc( dptr->typelinks.curr );
dptr->typelinks.init = dptr->typelinks.curr;
dptr->linelinks.start = dptr->typelinks.start + dptr->typelinks.size;
dptr->linelinks.size = dptr->linelinks.curr;
dptr->linelinks.curr = DBIAlloc( dptr->linelinks.curr );
dptr->linelinks.init = dptr->linelinks.curr;
dptr->local.start = dptr->linelinks.start + dptr->linelinks.size;
dptr->local.size = dptr->local.curr;
dptr->local.init = dptr->local.curr;
dptr->type.start = dptr->local.start + dptr->local.size;
dptr->type.size = dptr->type.curr;
dptr->type.init = dptr->type.curr;
dptr->line.start = dptr->type.start + dptr->type.size;
dptr->line.size = dptr->line.curr;
dptr->line.curr = DBIAlloc( dptr->line.curr );
dptr->line.init = dptr->line.curr;
dptr->mod.start = dptr->line.start + dptr->line.size;
dptr->mod.size = dptr->mod.curr;
dptr->mod.curr = DBIAlloc( dptr->mod.curr );
dptr->mod.init = dptr->mod.curr;
dptr->global.start = dptr->mod.start + dptr->mod.size;
dptr->addr.start = dptr->global.start + dptr->global.curr;
dptr->global.size = 0;
dptr->global.curr = DBIAlloc( dptr->global.curr );
dptr->global.init = dptr->global.curr;
dptr->addr.curr = DBIAlloc( dptr->addr.size );
dptr->addr.init = dptr->addr.curr;
dptr->DBIWrite = dptr->global.curr;
dptr->modnum = -1;
AllocDBIClasses( sect->classlist );
}
static bool AllocASeg( void *leader, void *group )
/************************************************/
{
((seg_leader *)leader)->group = group;
return( FALSE );
}
static void AllocDBIClasses( class_entry *class )
/***********************************************/
/* Allocate all classes in the list */
{
group_entry *group;
while( class != NULL ) {
if( class->flags & CLASS_DEBUG_INFO ) {
group = AllocGroup( AutoGrpName, &DBIGroups );
group->grp_addr.seg = 0;
RingLookup( class->segs, AllocASeg, group );
}
class = class->next_class;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?