dfloc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,260 行 · 第 1/3 页
C
1,260 行
{ CI_MIPS_f7, 0, 64 }, //DW_MIPS_f7
{ CI_MIPS_f8, 0, 64 }, //DW_MIPS_f8
{ CI_MIPS_f9, 0, 64 }, //DW_MIPS_f9
{ CI_MIPS_f10, 0, 64 }, //DW_MIPS_f10
{ CI_MIPS_f11, 0, 64 }, //DW_MIPS_f21
{ CI_MIPS_f12, 0, 64 }, //DW_MIPS_f22
{ CI_MIPS_f13, 0, 64 }, //DW_MIPS_f23
{ CI_MIPS_f14, 0, 64 }, //DW_MIPS_f24
{ CI_MIPS_f15, 0, 64 }, //DW_MIPS_f25
{ CI_MIPS_f16, 0, 64 }, //DW_MIPS_f26
{ CI_MIPS_f17, 0, 64 }, //DW_MIPS_f27
{ CI_MIPS_f18, 0, 64 }, //DW_MIPS_f28
{ CI_MIPS_f19, 0, 64 }, //DW_MIPS_f29
{ CI_MIPS_f20, 0, 64 }, //DW_MIPS_f20
{ CI_MIPS_f21, 0, 64 }, //DW_MIPS_f21
{ CI_MIPS_f22, 0, 64 }, //DW_MIPS_f22
{ CI_MIPS_f23, 0, 64 }, //DW_MIPS_f23
{ CI_MIPS_f24, 0, 64 }, //DW_MIPS_f24
{ CI_MIPS_f25, 0, 64 }, //DW_MIPS_f25
{ CI_MIPS_f26, 0, 64 }, //DW_MIPS_f26
{ CI_MIPS_f27, 0, 64 }, //DW_MIPS_f27
{ CI_MIPS_f28, 0, 64 }, //DW_MIPS_f28
{ CI_MIPS_f29, 0, 64 }, //DW_MIPS_f29
{ CI_MIPS_f30, 0, 64 }, //DW_MIPS_f30
{ CI_MIPS_f31, 0, 64 }, //DW_MIPS_f31
};
/*
Stuff dealing with evaluating dwarf location expr's
*/
typedef struct {
imp_image_handle *ii;
location_context *lc; /* addr context */
location_list *ll; /* where to store addr */
address base; /* base segment & offset */
dip_status ret;
dr_loc_kind init; /* how to get stack going */
uint_32 value;/* value on top of stack */
int val_count;
uint_32 seg;
} loc_handle;
static dr_loc_kind Init( void *_d, uint_32 *where )
{
loc_handle *d = _d;
// Set location expr initial value
switch( d->init ){
case DR_LOC_NONE:
break;
case DR_LOC_REG:
break;
case DR_LOC_ADDR:
*where = 0;
break;
}
return( d->init );
}
static int Ref( void *_d, uint_32 offset, uint_32 size, dr_loc_kind kind )
{
// Collect a reference from location expr and stuff in ret ll
// Assume d->ll init num == 0, flags == 0
loc_handle *d = _d;
location_list tmp, *ll;
if( kind == DR_LOC_ADDR ){
LocationCreate( &tmp, LT_ADDR, &d->base );
tmp.e[0].u.addr.mach.offset = offset;
tmp.e[0].bit_length = size*8;
}else{
mad_handle kind;
int areg;
int start;
kind = DCCurrMAD();
switch( kind ){
case MAD_X86:
areg = CLRegX86[offset].ci;
start = CLRegX86[offset].start;
break;
case MAD_AXP:
areg = CLRegAXP[offset];
start = 0;
break;
case MAD_PPC:
areg = CLRegPPC[offset].ci;
// This should really be dynamic; anyway the registers are really
// stored as 64-bit values, so if we want to get at the lower 32
// bits only, we need to start 32 bits into the storage.
#if defined( __BIG_ENDIAN__ )
if( CLRegPPC[offset].len == 32 )
start = 32;
else
start = 0;
#else
start = CLRegPPC[offset].start;
#endif
break;
case MAD_MIPS:
areg = CLRegMIPS[offset].ci;
// See PowerPC comments above
#if defined( __BIG_ENDIAN__ )
if( CLRegMIPS[offset].len == 32 )
start = 32;
else
start = 0;
#else
start = CLRegMIPS[offset].start;
#endif
break;
case MAD_NIL:
default:
DCStatus( DS_ERR | DS_BAD_LOCATION );
return( FALSE );
}
d->ret = SafeDCItemLocation( d->lc, areg, &tmp );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
LocationAdd( &tmp, start );
LocationTrunc( &tmp, size*8 );
}
ll = d->ll;
LocationJoin( ll, &tmp );
return( TRUE );
}
static int DRef( void *_d, uint_32 *where, uint_32 offset, uint_32 size ){
// Dereference a value use default address space
// The offset on top of the stack is relative to it
loc_handle *d = _d;
address a;
location_list tmp;
location_list ll;
#if 1
d->ret = SafeDCItemLocation( d->lc, CI_DEF_ADDR_SPACE, &ll );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
a = ll.e[0].u.addr;
#else
a = d->base;
#endif
a.mach.offset = offset;
LocationCreate( &ll, LT_ADDR, &a );
ll.e[0].bit_length = size*8;
LocationCreate( &tmp, LT_INTERNAL, where );
d->ret = DCAssignLocation( &tmp, &ll, sizeof( *where ) );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
return( TRUE );
}
static int DRefX( void *_d, uint_32 *where, uint_32 offset, uint_32 seg, uint_16 size )
{
// Dereference an extended address
loc_handle *d = _d;
address a;
location_list tmp;
location_list ll;
a = NilAddr;
a.mach.segment = seg;
a.mach.offset = offset;
// DCMapAddr( &a.mach, d->ii->dcmap );
LocationCreate( &ll, LT_ADDR, &a );
ll.e[0].bit_length = size*8;
LocationCreate( &tmp, LT_INTERNAL, where );
d->ret = DCAssignLocation( &tmp, &ll, sizeof( *where ) );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
return( TRUE );
}
static int Frame( void *_d, uint_32 *where )
{
loc_handle *d = _d;
location_list ll;
mad_handle kind;
// Get frame location
kind = DCCurrMAD();
d->ret = SafeDCItemLocation( d->lc, CI_FRAME, &ll );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
d->base = ll.e[0].u.addr; /* set base */
*where = ll.e[0].u.addr.mach.offset;
return( TRUE );
}
static int Reg( void *_d, uint_32 *where, uint_16 reg )
{
// get value of reg
loc_handle *d = _d;
location_list ll;
location_list tmp;
mad_handle kind;
int areg;
int start;
int size;
kind = DCCurrMAD();
switch( kind ){
case MAD_X86:
areg = CLRegX86[reg].ci;
start = CLRegX86[reg].start;
size = CLRegX86[reg].len;
break;
case MAD_AXP:
areg = CLRegAXP[reg];
start = 0;
/* a massive kludge here */
if( areg >= CI_AXP_f0 && areg <= CI_AXP_f31 ) {
size = 64;
} else {
size = 32;
}
break;
case MAD_PPC:
areg = CLRegPPC[reg].ci;
/* yep, another and even worse kludge */
#if defined( __BIG_ENDIAN__ )
if( CLRegPPC[reg].len == 32 )
start = 32;
else
start = 0;
#else
start = CLRegPPC[reg].start;
#endif
size = CLRegPPC[reg].len;
break;
case MAD_MIPS:
areg = CLRegMIPS[reg].ci;
/* just as bad as PPC */
#if defined( __BIG_ENDIAN__ )
if( CLRegMIPS[reg].len == 32 )
start = 32;
else
start = 0;
#else
start = CLRegMIPS[reg].start;
#endif
size = CLRegMIPS[reg].len;
break;
case MAD_NIL:
default:
DCStatus( DS_ERR | DS_BAD_LOCATION );
return( FALSE );
}
d->ret = SafeDCItemLocation( d->lc, areg, &ll );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
LocationAdd( &ll, start );
LocationTrunc( &ll, size);
// ll.e[0].bit_start = start;
// ll.e[0].bit_length = size;
LocationCreate( &tmp, LT_INTERNAL, where );
d->ret = DCAssignLocation( &tmp, &ll, sizeof( *where ) );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
if( kind == MAD_X86 && (reg == DW_X86_esp || reg == DW_X86_sp) ){ /* kludge for now */
d->ret = SafeDCItemLocation( d->lc, CI_STACK, &ll );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
d->base = ll.e[0].u.addr; /* set base */
d->base.mach.offset = 0;
}else{
d->ret = SafeDCItemLocation( d->lc, CI_DEF_ADDR_SPACE, &ll );
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
d->base = ll.e[0].u.addr; /* set base */
d->base.mach.offset = 0;
}
return( TRUE );
}
static int ACon( void *_d, uint_32 *where, bool isfar )
{
// relocate a map address constant
loc_handle *d = _d;
d->base.mach.offset = where[0];
if( isfar ){ /* assume next in stack is a seg and an xdref is coming */
d->base.mach.segment = where[1];
}else{
d->base.mach.segment = d->seg;
}
DCMapAddr( &d->base.mach, d->ii->dcmap );
where[0] = d->base.mach.offset;
if( isfar ){ /* assume next in stack is a seg and an xdref is coming */
where[1] = d->base.mach.segment;
}
return( TRUE );
}
static int Live( void *_d, uint_32 *where )
{
// find the appropriate live range
loc_handle *d = _d;
location_list ll;
dip_status ret;
// Get execution location
ret = SafeDCItemLocation( d->lc, CI_EXECUTION, &ll );
d->ret = DS_OK;
if( d->ret != DS_OK ){
DCStatus( d->ret );
return( FALSE );
}
if( !Real2Map( d->ii->addr_map, &ll.e[0].u.addr ) ){
d->ret = DS_ERR|DS_BAD_LOCATION;
DCStatus( DS_ERR|DS_BAD_LOCATION );
}
*where = ll.e[0].u.addr.mach.offset;
return( TRUE );
}
static dr_loc_callbck_def const CallBck = {
Init,
Ref,
DRef,
DRefX,
Frame,
Reg,
ACon,
Live
};
static int IsEntry( imp_image_handle *ii, location_context *lc ){
/*
Determine if we are at function entry
*/
location_list ll;
addrsym_info info;
dip_status ret;
seg_list *addr_sym;
im_idx imx;
// Get execution location
ret = SafeDCItemLocation( lc, CI_EXECUTION, &ll );
if( ret != DS_OK ){
return( FALSE );
}
if( DFAddrMod( ii, ll.e[0].u.addr, &imx ) == SR_NONE ){
return( FALSE );
}
if( !Real2Map( ii->addr_map, &ll.e[0].u.addr ) ){
return( FALSE );
}
addr_sym = DFLoadAddrSym( ii, imx );
if( FindAddrSym( addr_sym, &ll.e[0].u.addr.mach, &info ) >= 0 ){
if( info.map_offset == ll.e[0].u.addr.mach.offset ){
return( TRUE );
}
}
return( FALSE );
}
extern dip_status EvalLocation( imp_image_handle *ii,
location_context *lc,
dr_handle sym,
word seg,
location_list *ll ){
loc_handle d;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
d.ii = ii;
d.lc = lc;
d.ll = ll;
d.ret = DS_OK;
d.base = NilAddr;
d.val_count = 0;
d.base.mach.segment = 0;
d.base.mach.offset = 0;
d.seg = seg;
d.init = DR_LOC_NONE;
LocationInit( ll ); /* set to 0 */
if( !DRLocationAT( sym, &CallBck, &d ) ){
if( d.ret == DS_OK ){
d.ret = DS_FAIL;
}
}
if( d.ret != DS_OK ){
if( DRIsParm( sym ) ){
if( IsEntry( ii, lc ) ){
d.val_count = 0;
d.base.mach.segment = 0;
d.base.mach.offset = 0;
d.init = DR_LOC_NONE;
LocationInit( ll ); /* set to 0 */
if( !DRParmEntryAT( sym, &CallBck, &d ) ){
if( d.ret == DS_OK ){
d.ret = DS_FAIL;
}
}
}
}
}
LocationLast( ll );
return( d.ret );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?