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