dfmod.c

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

C
641
字号
/****************************************************************************
*
*                            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:  Stuff dealing with module handles.
*
****************************************************************************/


#include <string.h>
#include <stdlib.h>
#include "dfdip.h"
#include "dfmod.h"
#include "dfmodinf.h"
#include "dfmodbld.h"
#include "dfld.h"
#include "dfaddr.h"
#include "dfaddsym.h"

//NYI: should be OS && location sensitive
#define IS_PATH_CHAR( c ) ((c)=='\\'||(c)=='/'||(c)==':')
#define EXT_CHAR        '.'
#define MAX_PATH        256

static void GetModName( char *path, char *buff ){
/************************************************/
/* find the module name from the path           */
/************************************************/
    char *end, *start;
    int ext_found;
    start = path;
    ext_found = FALSE;
    while( *path != '\0' ){
        if( IS_PATH_CHAR( *path ) ){
            start = path+1;
        }else if( *path == EXT_CHAR ){
            ext_found = TRUE;
            end = path;
        }else if( *path == '(' ){
            start = path+1;
            while( *path != ')' )++path;
            end = path;
            ext_found = TRUE;
            goto do_copy;
        }
        ++path;
    }
    if( !ext_found ){
        end = path;
    }
do_copy:
    while( start < end ){
        *buff = *start;
        ++start;
        ++buff;
    }
    *buff = '\0';
}

static bool ModFill( void *_mod, dr_handle mod_handle ){
/**************************************************************/
// fill in mod_handle for dip to dwarf mod map
// pick up general info about mod while here for later calls
    mod_list *mod = _mod;
    char    fname[MAX_PATH];
    char   *name;
    char   *path;
    dr_handle   cu_tag;
    dr_model    model;
    mod_info   *curr;

    curr = NextModInfo( mod );
    curr->mod_handle = mod_handle;
    InitAddrSym( curr->addr_sym );
    curr->addr_size = DRGetAddrSize( mod_handle );
    cu_tag = DRGetCompileUnitTag( mod_handle );
    curr->cu_tag = cu_tag;
    curr->stmts = DRGetStmtList( cu_tag );
    path = DRGetName( cu_tag );
    if( path != NULL ){
        GetModName( path, fname );
        DCFree( path );
        name = DCAlloc( strlen( fname )+1 );
        strcpy( name, fname );
    }else{
        name = NULL;
    }
    path = DRGetProducer( cu_tag );
    if( path != NULL ){

        df_ver version;

        if( strcmp( path, "V2.0 WATCOM" ) == 0 ) {
            version = VER_V3;
        } else if( strcmp( path, "V1.0 WATCOM" ) == 0 ) {
            version = VER_V2;
        }else if( strcmp( path, "WATCOM" ) == 0 ){
            version = VER_V1;
        }else{
            version = VER_NONE;
        }
        if( mod->version == VER_NONE ){
            mod->version = version;
        }else if( mod->version != version ){
            mod->version = VER_ERROR;
        }
        DCFree( path );
    }
    curr->name = name;
    model = DRGetMemModelAT( cu_tag );
    if( DCCurrMAD() == MAD_X86 ) {
        switch( model ){
        case DR_MODEL_NONE:
        case DR_MODEL_FLAT:
            curr->is_segment = FALSE;
            break;
        default:
            curr->is_segment = TRUE;
            break;
        }
    } else {
        curr->is_segment = FALSE;
    }
    curr->model = model;
    curr->lang  = DRGetLanguageAT( cu_tag );
    curr->dbg_pch = DRDebugPCHDef( cu_tag );
    curr->has_pubnames = FALSE;
    return( TRUE );
}

extern  dip_status     InitModMap( imp_image_handle *ii ){
/**************************************************/
// Make the imp_mod_handle  to  dr_handle map
    mod_list list;
    dip_status ret;

    ret = DS_OK;
    ii->mod_count = 0;
    InitModList( &list );
    InitAddrSym( ii->addr_sym );
    DRSetDebug( ii->dwarf->handle ); /* set dwarf to image */
    DRIterateCompileUnits( &list, ModFill );
    DRDbgClear( ii->dwarf->handle ); /* clear some mem */
    ii->mod_count = list.count;
    ii->mod_map = FiniModInfo( &list );
    if( list.version == VER_V1 ) {
        DRDbgOldVersion( ii->dwarf->handle, 1 );
    } else if( list.version == VER_V2 ) {
        DRDbgOldVersion( ii->dwarf->handle, 2 );
    } else if( list.version == VER_ERROR ) {
        DCStatus( DS_INFO_BAD_VERSION );
        ret = DS_FAIL | DS_INFO_BAD_VERSION;
    }
    return( ret );
}

extern  bool    ClearMods( imp_image_handle *ii ){
/********************************/
// free any cached mem for modules
    int i;
    int ret;

    ret = FALSE;
    if( ii->mod_map != NULL ){
        for( i = 0; i < ii->mod_count; ++i ){
            if( ii->mod_map[i].addr_sym->head != NULL ){
                FiniAddrSym( ii->mod_map[i].addr_sym );
                ret = TRUE;
            }
        }
    }
   return( ret );
}

extern  void    FiniModMap( imp_image_handle *ii ){
/**************************************************/
// Make the imp_mod_handle  to  dr_handle map
    int i;

    ClearMods( ii );
    FiniAddrSym( ii->addr_sym );
    if( ii->mod_map != NULL ){
        for( i = 0; i < ii->mod_count; ++i ){
            if( ii->mod_map[i].name != NULL ){
                DCFree( ii->mod_map[i].name );
            }
        }
        DCFree( ii->mod_map  );
        ii->mod_map = NULL;
    }
}

extern  im_idx  Dwarf2ModIdx( imp_image_handle *ii, dr_handle mod_handle ){
/******************************************************************************/
// Look up mod_handle in mod_map
    im_idx i;

    for( i = FIRST_IMX; i < ii->mod_count; ++i ){
        if( mod_handle == ii->mod_map[i].mod_handle ){
            return( i );
        }
    }
    return( INVALID_IMX );
}

extern  im_idx  DwarfModIdx( imp_image_handle *ii, dr_handle mod_handle ){
/************************************************************************/
// find the im_idx where a dwarf dbginfo comes from
    im_idx i;
    im_idx last;

    if( ii->mod_count == 0 ){
        return( INVALID_IMX );
    }
    last = ii->mod_count - 1;
    for( i = 0; i < last; ++i ){
        if( mod_handle < ii->mod_map[i+1].mod_handle ){
            return( i );
        }
    }
    return( i );
}

extern  im_idx  CuTag2ModIdx( imp_image_handle *ii, dr_handle cu_handle ){
/******************************************************************************/
// Look up mod_handle in mod_map
    im_idx i;

    for( i = FIRST_IMX; i < ii->mod_count; ++i ){
        if( cu_handle == ii->mod_map[i].cu_tag ){
            return( i );
        }
    }
    return( INVALID_IMX );
}

extern walk_result DFWalkModList( imp_image_handle *ii,
                        MY_MOD_WKR wk, void *d )
{
    im_idx imx;
    walk_result ret;
    dr_dbg_handle  saved;

    ret = WR_CONTINUE;
    for( imx = FIRST_IMX; imx < ii->mod_count; ++imx ){
        saved = DRGetDebug();
        ret = wk( ii, imx, d );
        DRSetDebug( saved );
        if( ret != WR_CONTINUE )break;
    }
    return( ret );
}

extern walk_result DFWalkModListSrc( imp_image_handle *ii,
                                 int src,
                                 MY_MOD_WKR wk, void *d )
{
    im_idx          imx;
    int             hassrc;
    walk_result ret;
    dr_dbg_handle  saved;

    ret = WR_CONTINUE;
    for( imx = FIRST_IMX; imx < ii->mod_count; ++imx ){
        hassrc =  ii->mod_map[imx].has_pubnames;
        if( src == hassrc ){
            saved = DRGetDebug();
            ret = wk( ii, imx, d );
            DRSetDebug( saved );
            if( ret != WR_CONTINUE )break;
        }
    }
    return( ret );
}

walk_result DIPENTRY DIPImpWalkModList( imp_image_handle *ii,
                        IMP_MOD_WKR wk, void *d )
{
    int im;
    walk_result ret;
    dr_dbg_handle  saved;

    ret = WR_CONTINUE;
    for( im = 1; im <= ii->mod_count; ++im ){
        saved = DRGetDebug();
        ret = wk( ii, im, d );
        DRSetDebug( saved );
        if( ret != WR_CONTINUE )break;
    }
    return( ret );

}

unsigned        DIPENTRY DIPImpModName( imp_image_handle *ii,
                        imp_mod_handle im, char *buff, unsigned max )
{
    char        *name;
    unsigned    len;
    im_idx      imx;

⌨️ 快捷键说明

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