watlcl.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 979 行 · 第 1/3 页
C
979 行
/****************************************************************************
*
* 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: Locals processing for Watcom style debugging information.
*
****************************************************************************/
#include "dipwat.h"
#include "watlcl.h"
#include <string.h>
extern void *InfoLoad(imp_image_handle *, imp_mod_handle, unsigned, unsigned, void (*)() );
extern void InfoSpecUnlock( void * );
extern unsigned int InfoSize(imp_image_handle *,imp_mod_handle,unsigned, unsigned );
extern address FindModBase(imp_image_handle *, imp_mod_handle);
extern void AddressMap( imp_image_handle *, addr_ptr * );
extern section_info *FindInfo( imp_image_handle *, imp_mod_handle );
extern byte *SkipLocation( loc_expr );
extern dip_status EvalLocation( imp_image_handle *, location_context *, loc_expr, location_list * );
extern walk_result WalkTypeSymList( imp_image_handle *, imp_type_handle *, IMP_SYM_WKR *, imp_sym_handle *, void * );
extern dip_status FindTypeHandle( imp_image_handle *, imp_mod_handle, unsigned, imp_type_handle * );
extern search_result LookupTypeName( imp_image_handle *, imp_mod_handle, lookup_item *, imp_type_handle * );
extern search_result SearchMbr( imp_image_handle *, imp_type_handle *, lookup_item *, void * );
extern void LocationCreate( location_list *, location_type, void * );
extern search_result LookupGblAddr( imp_image_handle *, address, imp_sym_handle * );
extern dip_status SymHdl2GblInfo( imp_image_handle *, imp_sym_handle *, sym_info * );
extern dip_status Link2GblHdl( imp_image_handle *, void *, imp_sym_handle * );
extern unsigned RegSize( unsigned );
extern address NilAddr;
typedef struct lclinfo {
section_info *inf;
byte *start;
byte *end;
unsigned base_off;
address code_base;
imp_mod_handle im;
} lclinfo;
#define NO_BASE ((unsigned short)-1)
byte *GetIndex( byte *ptr, unsigned *value )
{
unsigned tmp;
tmp = *ptr++;
if ( tmp & 0x80 ) {
tmp = (tmp & 0x7f) << 8;
tmp += *ptr++;
}
*value = tmp;
return( ptr );
}
static byte *GetMachAddr( imp_image_handle *ii, byte *ptr, addr_ptr *addr,
int is32 )
{
if( is32 ) {
*addr = *(addr48_ptr *)ptr;
ptr += sizeof( addr48_ptr );
} else {
ConvAddr32ToAddr48( *(addr32_ptr *)ptr, *addr );
ptr += sizeof( addr32_ptr );
}
AddressMap( ii, addr );
return( ptr );
}
byte *GetAddress( imp_image_handle *ii, byte *ptr, address *addr, int is32 )
{
ptr = GetMachAddr( ii, ptr, &addr->mach, is32 );
DCAddrSection( addr );
return( ptr );
}
static void LclCreate( imp_sym_handle *is, byte *ptr, byte *name, lclinfo *local )
{
is->type = SH_LCL;
is->im = local->im;
is->u.lcl.base = local->base_off;
is->u.lcl.offset = ptr - local->start;
is->u.lcl.gbl_link = NULL;
is->name_off = name - ptr;
}
/*
* LoadLocalSyms -- load the local symbol information for the module
*/
static dip_status LoadLocalSyms( imp_image_handle *ii, imp_mod_handle im,
lclinfo *new )
{
if( im == (imp_mod_handle)NO_MOD ) return( DS_FAIL );
new->start = InfoLoad( ii, im, DMND_LOCALS, 0, NULL );
if( new->start == NULL ) {
return( DS_FAIL );
}
new->end = new->start + InfoSize( ii, im, DMND_LOCALS, 0 );
new->im = im;
new->inf = FindInfo( ii, im );
new->base_off = NO_BASE;
return( DS_OK );
}
static void PopLoad( lclinfo *local )
{
if( local->start != NULL ) {
InfoSpecUnlock( local->start );
}
}
void KillLclLoadStack( void )
{
// Nothing to do - not using globals anymore
}
/*
* ProcBlock -- process a block definition
*/
static byte *ProcBlock( byte *ptr, lcl_defn *defn, lclinfo *local )
{
if( local->base_off == NO_BASE ) {
defn->b.start = FindModBase( local->inf->ctl, local->im );
} else {
defn->b.start = local->code_base;
}
if( defn->i.class >= (CODE_SYMBOL + CODE_BLOCK386) ) {
defn->b.start.mach.offset += *((dword *) ptr);
ptr += sizeof( dword );
defn->b.size = *((dword *) ptr);
ptr += sizeof( dword );
} else {
defn->b.start.mach.offset += *((word *) ptr);
ptr += sizeof( word );
defn->b.size = *((word *) ptr);
ptr += sizeof( word );
}
defn->b.parent_block = *((word *) ptr);
ptr += sizeof( word );
return( ptr );
}
/*
* ProcDefn -- process the next definition in the local symbol information
*/
static byte *ProcDefn( byte *ptr, lcl_defn *defn, lclinfo *local )
{
byte *end;
int parms;
end = ptr + *ptr;
ptr++;
defn->i.class = *ptr++;
defn->i.unparsed = ptr;
switch( defn->i.class ) {
case VAR_SYMBOL | VAR_MODULE386:
ptr += sizeof( addr48_ptr );
ptr = GetIndex( ptr, &defn->i.type_index );
break;
case VAR_SYMBOL | VAR_MODULE :
ptr += sizeof( addr32_ptr );
ptr = GetIndex( ptr, &defn->i.type_index );
break;
case VAR_SYMBOL | VAR_MODULE_LOC:
case VAR_SYMBOL | VAR_LOCAL :
ptr = SkipLocation( ptr );
ptr = GetIndex( ptr, &defn->i.type_index );
break;
case CODE_SYMBOL | CODE_BLOCK386:
case CODE_SYMBOL | CODE_BLOCK :
ptr = ProcBlock( ptr, defn, local );
break;
case CODE_SYMBOL | CODE_NEAR_ROUT386:
case CODE_SYMBOL | CODE_FAR_ROUT386:
case CODE_SYMBOL | CODE_NEAR_ROUT :
case CODE_SYMBOL | CODE_FAR_ROUT :
ptr = ProcBlock( ptr, defn, local );
defn->r.pro_size = *ptr++;
defn->r.epi_size = *ptr++;
if( defn->i.class >= (CODE_SYMBOL + CODE_BLOCK386) ) {
defn->r.ret_addr_offset = *((dword *) ptr);
ptr += sizeof( dword );
} else {
defn->r.ret_addr_offset = *((word *) ptr);
ptr += sizeof( word );
}
ptr = GetIndex( ptr, &defn->i.type_index );
defn->i.unparsed = ptr;
ptr = SkipLocation( ptr );
for( parms = *ptr++; parms != 0; --parms ) {
ptr = SkipLocation( ptr );
}
break;
case CODE_SYMBOL | CODE_MEMBER_SCOPE:
defn->b.parent_block = *((word *) ptr);
ptr += sizeof( word );
ptr = GetIndex( ptr, &defn->i.type_index );
if( ptr < end ) {
defn->i.unparsed = ptr;
/* skip the 'this' pointer type and the object loc expr */
ptr = SkipLocation( ptr + 1 );
} else {
defn->i.unparsed = NULL;
}
break;
}
defn->i.name = ptr;
defn->i.namelen = end - ptr;
return( end );
}
static void NewBase( byte *ptr, lclinfo *local )
{
ptr += 1;
if( (ptr[0] & CLASS_MASK) == NEW_BASE ) {
local->base_off = ptr - local->start - 1;
local->code_base.sect_id = local->inf->sect_id;
local->code_base.indirect = 1;
switch( ptr[0] & SUBCLASS_MASK ) {
case ADD_PREV_SEG:
ptr += 1;
local->code_base.mach.segment += *((word *) ptr);
local->code_base.mach.offset = 0;
break;
case SET_BASE386:
GetMachAddr( local->inf->ctl, ptr+1, &local->code_base.mach, 1 );
break;
case SET_BASE:
GetMachAddr( local->inf->ctl, ptr+1, &local->code_base.mach, 0 );
break;
}
}
}
static byte *FindBlockRout( byte *ptr, lclinfo *local )
{
byte cls;
while( ptr < local->end ) {
cls = ptr[1];
if( (cls & CLASS_MASK) == CODE_SYMBOL &&
cls != (CODE_SYMBOL | CODE_MEMBER_SCOPE) ) {
return( ptr );
}
NewBase( ptr, local );
ptr += *ptr;
}
return( NULL );
}
static byte *ModAddrLkupVar( byte *ptr, lclinfo *local )
{
while( ptr < local->end ) {
switch( ptr[1] ) {
case VAR_SYMBOL | VAR_MODULE:
case VAR_SYMBOL | VAR_MODULE386:
case CODE_SYMBOL | CODE_NEAR_ROUT:
case CODE_SYMBOL | CODE_FAR_ROUT:
case CODE_SYMBOL | CODE_NEAR_ROUT386:
case CODE_SYMBOL | CODE_FAR_ROUT386:
return( ptr );
}
NewBase( ptr, local );
ptr += *ptr;
}
return( NULL );
}
static byte *FindLclVar( byte *ptr, lclinfo *local )
{
while( ptr < local->end ) {
if( (*(ptr+1) & CLASS_MASK) == CODE_SYMBOL ) break;
if( *(ptr+1) == (VAR_SYMBOL | VAR_LOCAL) ) return( ptr );
NewBase( ptr, local );
ptr += *ptr;
}
return( NULL );
}
static dip_status DefnLocation( lcl_defn *defn, location_context *lc,
location_list *ll, lclinfo *local )
{
address addr;
switch( defn->i.class ) {
case VAR_SYMBOL | VAR_MODULE386:
GetAddress( local->inf->ctl, defn->i.unparsed, &addr, 1 );
LocationCreate( ll, LT_ADDR, &addr );
break;
case VAR_SYMBOL | VAR_MODULE:
GetAddress( local->inf->ctl, defn->i.unparsed, &addr, 0 );
LocationCreate( ll, LT_ADDR, &addr );
break;
case VAR_SYMBOL | VAR_LOCAL:
case VAR_SYMBOL | VAR_MODULE_LOC:
return( EvalLocation( local->inf->ctl, lc, defn->i.unparsed, ll ) );
default:
LocationCreate( ll, LT_ADDR, &defn->b.start );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?