hllsym.c

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

C
1,855
字号
/****************************************************************************
*
*                            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:  HLL/CV debugging symbol support.
*
****************************************************************************/


#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "walloca.h"
#include "demangle.h"
#include "hllinfo.h"


#define SCOPE_CLASS_FLAG        0x80000000UL
#define SCOPE_UNIQUE_MASK       (~SCOPE_CLASS_FLAG)

dip_status SymFillIn( imp_image_handle *ii, imp_sym_handle *is,
                                virt_mem h )
{
    s_all               *ref;
    cv_directory_entry  *cde;

    is->containing_type = 0;
    is->adjustor_type = 0;
    is->adjustor_offset = 0;
    is->mfunc_idx = 0;
    ref = VMBlock( ii, h, sizeof( ref->procref ) );
    if( ref == NULL ) return( DS_ERR|DS_FAIL );
    switch( ref->common.code ) {
    case S_PROCREF:
    case S_DATAREF:
        is->im = ref->procref.f.module;
        cde = FindDirEntry( ii, is->im, sstAlignSym );
        if( cde == NULL ) return( DS_ERR|DS_FAIL );
        h = ref->procref.f.offset + cde->lfo;
        ref = VMBlock( ii, h, sizeof( s_common ) );
        if( ref == NULL ) return( DS_ERR|DS_FAIL );
    }
    is->handle = h;
    is->len = ref->common.length + sizeof( ref->common.length );
    return( DS_OK );
}

static dip_status SymGetName( imp_image_handle *ii, imp_sym_handle *is,
                            char **namep, unsigned *lenp, s_all **pp )
{
    s_all               *p;
    unsigned            skip;
    char                *name;
    numeric_leaf        val;

    if( is->containing_type != 0 ) {
        static const s_common dummy = { 0, S_LDATA16 };

        if( pp != NULL ) *pp = (s_all *)&dummy;
        return( TypeSymGetName( ii, is, namep, lenp ) );
    }
    p = VMBlock( ii, is->handle, is->len );
    if( p == NULL ) return( DS_FAIL );
    if( pp != NULL ) *pp = p;
    if( p->common.code == S_ENTRYTHIS ) {
        p = (void *) (&p->common + 1 );
    }
    switch( p->common.code ) {
    case S_REGISTER:
        skip = sizeof( s_register );
        break;
    case S_CONSTANT:
        name = (unsigned_8 *)p + sizeof( s_constant );
        skip = (unsigned_8 *)GetNumLeaf( name, &val ) - (unsigned_8 *)p;
        break;
    case S_UDT:
        skip = sizeof( s_udt );
        break;
    case S_COBOLUDT:
        skip = sizeof( s_coboludt );
        break;
    case S_MANYREG:
        skip = sizeof( s_manyreg ) + p->manyreg.f.count;
        break;
    case S_BPREL16:
        skip = sizeof( s_bprel16 );
        break;
    case S_LDATA16:
    case S_GDATA16:
    case S_PUB16:
        skip = sizeof( s_ldata16 );
        break;
    case S_LPROC16:
    case S_GPROC16:
        skip = sizeof( s_lproc16 );
        break;
    case S_BLOCK16:
        skip = sizeof( s_block16 );
        break;
    case S_LABEL16:
        skip = sizeof( s_label16 );
        break;
    case S_REGREL16:
        skip = sizeof( s_regrel16 );
        break;
    case S_BPREL32:
        skip = sizeof( s_bprel32 );
        break;
    case S_LDATA32:
    case S_GDATA32:
    case S_PUB32:
        skip = sizeof( s_ldata32 );
        break;
    case S_LPROC32:
    case S_GPROC32:
        skip = sizeof( s_lproc32 );
        break;
    case S_BLOCK32:
        skip = sizeof( s_block32 );
        break;
    case S_LABEL32:
        skip = sizeof( s_label32 );
        break;
    case S_REGREL32:
        skip = sizeof( s_regrel32 );
        break;
    case S_LTHREAD32:
    case S_GTHREAD32:
        skip = sizeof( s_lthread32 );
        break;
    default:
        Confused();
    }
    name = (unsigned_8 *)p + skip;
    *lenp = name[0];
    *namep = &name[1];
    return( DS_OK );
}

static unsigned SymTypeIdx( imp_image_handle *ii, s_all *p )
{
    unsigned    idx;

#define DEFTYPE( t ) if( idx == 0 ) idx = t;
    switch( p->common.code ) {
    case S_REGISTER:
        idx = p->register_.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_CONSTANT:
        idx = p->constant.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_UDT:
        idx = p->udt.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_COBOLUDT:
        idx = p->coboludt.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_MANYREG:
        idx = p->manyreg.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_BPREL16:
        idx = p->bprel16.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_LDATA16:
    case S_GDATA16:
        idx = p->ldata16.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_PUB16:
        idx = p->pub16.f.type;
        if( SegIsExecutable( ii, p->pub16.f.segment ) ) {
            DEFTYPE( T_CODE_LBL16 );
        } else {
            DEFTYPE( T_DATA_LBL16 );
        }
        break;
    case S_LPROC16:
    case S_GPROC16:
        idx = p->lproc16.f.proctype;
        DEFTYPE( T_CODE_LBL16 );
        break;
    case S_LABEL16:
        idx = T_CODE_LBL16;
        if( SegIsExecutable( ii, p->label16.f.segment ) ) {
            DEFTYPE( T_CODE_LBL16 );
        } else {
            DEFTYPE( T_DATA_LBL16 );
        }
        break;
    case S_BPREL32:
        idx = p->bprel32.f.type;
        DEFTYPE( T_DATA_LBL16 );
        break;
    case S_LDATA32:
    case S_GDATA32:
        idx = p->ldata32.f.type;
        DEFTYPE( T_DATA_LBL32 );
        break;
    case S_PUB32:
        idx = p->ldata32.f.type;
        if( SegIsExecutable( ii, p->pub32.f.segment ) ) {
            DEFTYPE( T_CODE_LBL32 );
        } else {
            DEFTYPE( T_DATA_LBL32 );
        }
        break;
    case S_LPROC32:
    case S_GPROC32:
        idx = p->lproc32.f.proctype;
        DEFTYPE( T_CODE_LBL32 );
        break;
    case S_LABEL32:
        idx = T_CODE_LBL32;
        if( SegIsExecutable( ii, p->label32.f.segment ) ) {
            DEFTYPE( T_CODE_LBL32 );
        } else {
            DEFTYPE( T_DATA_LBL32 );
        }
        break;
    case S_REGREL32:
        idx = p->regrel32.f.type;
        DEFTYPE( T_DATA_LBL32 );
        break;
    case S_LTHREAD32:
    case S_GTHREAD32:
        idx = p->lthread32.f.type;
        DEFTYPE( T_DATA_LBL32 );
        break;
    default:
        Confused();
        idx = 0;
    }
    return( idx );
}

dip_status ImpSymLocation( imp_image_handle *ii,
                imp_sym_handle *is, location_context *lc, location_list *ll )
{
    dip_status          ds;
    address             addr;
    s_all               *p;
    signed_32           disp;
    location_list       tmp_ll;
    union {
        addr32_off      off32;
        addr48_off      off48;
    }                   tmp;

    //NYI: parameters when at the start of a routine.
    if( is->containing_type != 0 ) {
        return( TypeSymGetAddr( ii, is, lc, ll ) );
    }
    p = VMBlock( ii, is->handle, is->len );
    if( p == NULL ) return( DS_FAIL );
    switch( p->common.code ) {
    case S_REGISTER:
        return( LocationOneReg( ii, p->register_.f.reg, lc, ll ) );
    case S_CONSTANT:
    case S_UDT:
    case S_COBOLUDT:
        return( SR_FAIL );
    case S_MANYREG:
        return( LocationManyReg( ii, p->manyreg.f.count, (unsigned_8 *)&p->manyreg + 1, lc, ll ) );
    case S_BPREL16:
        ds = DCItemLocation( lc, CI_FRAME, ll );
        if( ds != DS_OK ) {
            DCStatus( ds );
            return( ds );
        }
        LocationAdd( ll, p->bprel16.f.offset * 8 );
        break;
    case S_LDATA16:
    case S_GDATA16:
    case S_PUB16:
        addr.mach.offset = p->ldata16.f.offset;
        addr.mach.segment = p->ldata16.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_LPROC16:
    case S_GPROC16:
        addr.mach.offset = p->lproc16.f.offset;
        addr.mach.segment = p->lproc16.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_BLOCK16:
        addr.mach.offset = p->block16.f.offset;
        addr.mach.segment = p->block16.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_LABEL16:
        addr.mach.offset = p->label16.f.offset;
        addr.mach.segment = p->label16.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_REGREL16:
        disp = p->regrel16.f.offset;
        ds = LocationOneReg( ii, p->regrel16.f.reg, lc, ll );
        if( ds != DS_OK ) return( ds );
        LocationCreate( &tmp_ll, LT_INTERNAL, &tmp.off32 );
        ds = DCAssignLocation( ll, &tmp_ll, sizeof( addr32_off ) );
        if( ds != DS_OK ) return( ds );
        ds = DCItemLocation( lc, CI_DEF_ADDR_SPACE, ll );
        if( ds != DS_OK ) return( ds );
        ll->e[0].u.addr.mach.offset = tmp.off32 + disp;
        break;
    case S_BPREL32:
        ds = DCItemLocation( lc, CI_FRAME, ll );
        if( ds != DS_OK ) {
            DCStatus( ds );
            return( ds );
        }
        LocationAdd( ll, p->bprel32.f.offset * 8 );
        break;
    case S_LDATA32:
    case S_GDATA32:
    case S_PUB32:
        addr.mach.offset = p->ldata32.f.offset;
        addr.mach.segment = p->ldata32.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_LPROC32:
    case S_GPROC32:
        addr.mach.offset = p->lproc32.f.offset;
        addr.mach.segment = p->lproc32.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_BLOCK32:
        addr.mach.offset = p->block32.f.offset;
        addr.mach.segment = p->block32.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );
        break;
    case S_LABEL32:
        addr.mach.offset = p->label32.f.offset;
        addr.mach.segment = p->label32.f.segment;
        MapLogical( ii, &addr );
        LocationCreate( ll, LT_ADDR, &addr );

⌨️ 快捷键说明

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