drdecnam.c

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

C
2,033
字号
/****************************************************************************
*
*                            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:  Decode names in DWARF debug info. Language dependent.
*
****************************************************************************/


#include <stdlib.h>
#include <string.h>
#include <watcom.h>
#include <dwarf.h>
#include "drpriv.h"
#include "drutils.h"
#include "drscope.h"
#include "drdecnam.h"

/*----------------*
 * type definitions
 *----------------*/

/*
 * A simple string type to store a pointer to the string and its length
 */
typedef struct {
    char *         s;   /* the string */
    unsigned short l;   /* length of the string (excluding \0) */
} String;

typedef struct Node_S {
    struct Node_S   *next;
    bool            user_def;   /* TRUE if defined by user */
    dr_handle       entry;      /* if this is user-def'd, the entry */
    dr_sym_type     sym_type;   /* if u_def'd, the type of symbol */
    String          buf;        /* may contain several (non usr-def) words */
} *Node_T;                      /* note - a pointer to Node_S */

/*
 * Put new nodes at front or back?
 */
typedef enum { LIST_HEAD, LIST_TAIL } ListEnd_T;

typedef struct {
    Node_T      head;           /* head */
    Node_T      tail;           /* tail */
    ListEnd_T   end;            /* end to add at */
} List_T;

/*
 * this structure stores the various parts of a name.
 */

typedef struct {
    List_T dec_plg;     /* prolog for the declaration .. this is stored */
                        /* in forward order, not reversed */
    List_T type_plg;    /* prolog of type .. eg extern, const, volatile */
    List_T type_bas;    /* base part of type .. int * */
    List_T type_ptr;    /* pointer part of type *, & */
    List_T type_elg;    /* epilog of type .. const, volatile */
    List_T type_inh;    /* list of base classes */

    List_T var_plg;     /* prolog for variable name .. eg (* */
    List_T var_bas;     /* base of variable name .. foo */
    List_T var_elg;     /* epilog for variable name .. eg ) (param list) */

    /*
     * these are stored in forward order, and the space is put on at
     * the front
     */
    List_T func_plg;    /* plg for function paragmeters "(" */
    List_T func_bas;    /* base of function's parameters */
    List_T func_elg;    /* elg for function parms " )" */
} BrokenName_T;

static BrokenName_T Empty_Broken_Name = {
    { NULL, NULL, LIST_TAIL },     /* dec_plg */
    { NULL, NULL, LIST_HEAD },     /* type_plg */
    { NULL, NULL, LIST_HEAD },     /* type_bas */
    { NULL, NULL, LIST_HEAD },     /* type_ptr */
    { NULL, NULL, LIST_TAIL },     /* type_elg */
    { NULL, NULL, LIST_TAIL },     /* type_inh */
    { NULL, NULL, LIST_HEAD },     /* var_plg */
    { NULL, NULL, LIST_HEAD },     /* var_bas */
    { NULL, NULL, LIST_HEAD },     /* var_elg */
    { NULL, NULL, LIST_TAIL },     /* func_plg */
    { NULL, NULL, LIST_TAIL },     /* func_bas */
    { NULL, NULL, LIST_TAIL }      /* func_elg*/
};

/*
 * this structure holds the current location
 */
typedef struct {
    dr_handle  parent;      /* containing die */
    dr_handle  entry_st;    /* start of the die */
    dr_handle  entry_cr;    /* location in the die */
    dr_handle  abbrev_st;   /* start of the abbrev */
    dr_handle  abbrev_cr;   /* location within the abbrev */
    dr_handle  tag;         /* the tag */
    unsigned_8 child;       /* DW_children_yes if entry has children */
    bool       inParam;     /* decorating parameters? (only used for FORTRAN)*/
} Loc_T;

/*
 * put new symbols to left or right of base type?
 */
typedef enum { TYPE_PLG, TYPE_BAS, TYPE_PTR, TYPE_ELG } TypeSide_T;

typedef struct {
    BrokenName_T    *decname;
    int             firstTime;
} BaseSearchInfo;


/*----------------*
 * static functions
 *----------------*/

static BrokenName_T  BuildList( dr_handle, dr_handle );
static void          BuildCList( BrokenName_T *, Loc_T * );
static void          BuildFortranList( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateVariable( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateMember( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateTypedef( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateNameSpace( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateLabel( BrokenName_T *, Loc_T * );
static BrokenName_T *DecorateFunction( BrokenName_T *, Loc_T * );
static List_T        StartFunctionParms( Loc_T * );
static List_T        DecorateParameter( Loc_T * );
static BrokenName_T *DecorateType( BrokenName_T *, Loc_T *, dr_handle );
static void          SwapModifier( BrokenName_T * );
static BrokenName_T *AddPtrModifier( BrokenName_T *, Loc_T * );
static BrokenName_T *DecSubroutineType( BrokenName_T *, Loc_T *, dr_handle );
static void          AddTypeString( BrokenName_T *, String, TypeSide_T);
static BrokenName_T *DecorateCompoundType( BrokenName_T *, Loc_T *,
                                           String, dr_sym_type );
static BrokenName_T *DecorateBases( BrokenName_T *, Loc_T * );
static int           baseHook( dr_sym_type, dr_handle, char *, dr_handle, void * );
static BrokenName_T *DecorateArray( BrokenName_T *, Loc_T * );
static BrokenName_T *DecoratePtrToMember( BrokenName_T *, Loc_T * );

static void ReadBlock( unsigned_8 **buf, dr_handle entry, unsigned len );
static void FORDecVariable( BrokenName_T *, Loc_T * );
static void FORAddConstVal( BrokenName_T * decname, Loc_T * loc, Loc_T * type_loc );
static void FORDecParam( BrokenName_T *, Loc_T * );
static void FORDecMember( BrokenName_T *, Loc_T * );
static void FORDecSubprogram( BrokenName_T *, Loc_T * );
static void FORDecEntryPoint( BrokenName_T *, Loc_T * );
static void FORDecStructure( BrokenName_T *, Loc_T * );
static void FORDecNameList( BrokenName_T *, Loc_T * );
static void FORDecRecord( BrokenName_T *, Loc_T * );
static void FORDecUnion( BrokenName_T *, Loc_T * );
static void FORDecType( BrokenName_T *, Loc_T * );
static void FORDecArray( BrokenName_T *, Loc_T * );
static void FORDecString( BrokenName_T *, Loc_T * );
static void FORDecCommon( BrokenName_T *, Loc_T * );

static String         FormName( BrokenName_T * );
static List_T         FormList( BrokenName_T * );
static void           FillLoc( Loc_T *, dr_handle );
static void           FreeList( List_T );
static void           IterateList( void (*)( void *, char *,
                                             int, dr_handle, dr_sym_type ),
                                   void *, List_T );
static void           ReallocStr( String * );
static void           ListConcat( List_T *, String );
static void           ListAdd( List_T *, Node_T );
static void           EndNode( List_T *, bool, dr_handle, dr_sym_type );
static Node_T         DeleteTail( List_T * );

/*-----------------*
 * static variables
 *-----------------*/

static String const ArrayLeftKwd = { "[", 1 };
static String const ArrayRightKwd = { "]", 1 };
static String const BaseKwd = { " : ", 3 };
static String const BaseSepKwd = { ", ", 2 };
static String const ClassKwd = { " ssalc", 6 };
static String const ConstKwd = { "const ", 6 };
static String const EnumKwd = { " mune", 5 };
static String const ExternKwd = { "extern ", 7 };
static String const FarKwd = { " raf", 4 };
static String const FuncEndKwd = { ")", 1 };
static String const FuncStartKwd = { "(", 1 };
static String const HugeKwd = { " eguh", 5 };
static String const LabelKwd = { " :",  2 };
static String const MemberKwd = { "::", 2 };
static String const NearKwd = { " raen", 5 };
static String const ParmSepKwd = { ", ", 2 };
static String const PtrKwd = { "*", 1 };
static String const RefKwd = { "&", 1 };
static String const SpaceKwd = { " ", 1 };
static String const StructKwd = { " tcurts", 7 };
static String const TypedefKwd = { "typedef ", 8 };
static String const NameSpaceKwd = { "namespace ", 10 };
static String const UnionKwd = { " noinu", 6 };
static String const UnspecParamKwd = { "...", 3 };
static String const VolatileKwd = { "volatile ", 9 };

static String const FORArrayLeftKwd =   { "(", 1 };
static String const FORArrayRightKwd =  { ")", 1 };
static String const FORAllocArrKwd =    { ":", 1 };     /* allocatable array */
static String const FORAssumeArrKwd =   { "*", 1 };    /* assumed-size array */
static String const FORSepKwd =         { ",", 1 };
static String const FORFuncStartKwd =   { "(", 1 };
static String const FORFuncEndKwd =     { ")", 1 };
static String const FORFuncKwd =        { " NOITCNUF", 9 };
static String const FORSubprogramKwd =  { " ENITUORBUS", 11 };
static String const FOREntryPointKwd =  { " YRTNE", 6 };
static String const FORMemberKwd =      { ".", 1 };
static String const FORParmSepKwd =     { ", ", 2 };
static String const FORSlashKwd =       { "/", 1 };
static String const FORStructKwd =      { " ERUTCURTS", 10 };
static String const FORNameListKwd =    { " TSILEMAN", 9 };
static String const FORCommonKwd =      { " NOMMOC", 7 };
static String const FORRecordKwd =      { " DROCER", 7 };
static String const FORUnionKwd =       { "NOINU", 5 };
static String const FORStringKwd =      { "*RETCARAHC", 10 };
static String const FORParamKwd =       { " RETEMARAP", 10 };
static String const FOREqualKwd =       { "=", 1 };

static const char *FORMainProgMatch = "MARGORP NIAM";

static String const * const AddressClasses[] = {
    NULL,       /* ADDR_none */
    &NearKwd,   /* ADDR_near16 */
    &FarKwd,    /* ADDR_far16 */
    &HugeKwd,   /* ADDR_huge16 */
    &NearKwd,   /* ADDR_near32 */
    &FarKwd     /* ADDR_far32 */
};

static const char *LBLFunction =            "Function";
static const char *LBLSubprogram =          "Subprogram";
static const char *LBLTypedef =             "Typedef";
static const char *LBLEnum =                "Enum";
static const char *LBLUnion =               "Union";
static const char *LBLStructure =           "Structure";
static const char *LBLClass =               "Class";
static const char *LBLCommonBlock =         "Common Block";
static const char *LBLVariable =            "Variable";
static const char *LBLParameter =           "Parameter";

extern void DRDecorateLabel( dr_handle die, char *buf )
/*****************************************************/
{
    Loc_T           loc;
    dr_language     lang;
    compunit_info   *compunit;
    const char      *label;
    dr_handle       tmp_abbrev;
    dr_handle       tmp_entry;

    FillLoc( &loc, die );

    compunit = DWRFindCompileInfo( die );
    lang = DRGetLanguageAT( compunit->start + COMPILE_UNIT_HDR_SIZE );

    switch( loc.tag ) {
    case DW_TAG_subprogram:
        switch( lang ) {
        case DR_LANG_C:
        case DR_LANG_CPLUSPLUS:
            label = LBLFunction;
            break;
        case DR_LANG_FORTRAN:
            tmp_abbrev = loc.abbrev_cr;
            tmp_entry = loc.entry_cr;
            if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_type ) ) {
                label = LBLFunction;
            } else {
                label = LBLSubprogram;
            }
            break;
        default:
            DWREXCEPT( DREXCEP_BAD_DBG_INFO );
        }
        break;
    case DW_TAG_typedef:
        label = LBLTypedef;
        break;
    case DW_TAG_enumeration_type:
        label = LBLEnum;
        break;
    case DW_TAG_union_type:
        label = LBLUnion;
        break;
    case DW_TAG_structure_type:
        label = LBLStructure;
        break;
    case DW_TAG_class_type:
        label = LBLClass;
        break;
    case DW_TAG_common_block:
        label = LBLCommonBlock;
        break;
    case DW_TAG_formal_parameter:
    case DW_TAG_member:
    case DW_TAG_variable:
        switch( lang ) {
        case DR_LANG_C:
        case DR_LANG_CPLUSPLUS:
            label = LBLVariable;
            break;
        case DR_LANG_FORTRAN:
            tmp_abbrev = loc.abbrev_cr;
            tmp_entry = loc.entry_cr;
            if( DWRScanForAttrib( &tmp_abbrev, &tmp_entry, DW_AT_const_value ) ) {
                label = LBLParameter;
            } else {
                label = LBLVariable;
            }
            break;
        default:
            DWREXCEPT( DREXCEP_BAD_DBG_INFO );
        }
        break;
    default:
        DWREXCEPT( DREXCEP_BAD_DBG_INFO );
    }

    strncpy( buf, label, DRDECLABELLEN );
}

extern char * DRDecoratedName( dr_handle die, dr_handle parent )
/**************************************************************/
{
    BrokenName_T    decstruct;
    char            *retstr;

    decstruct = BuildList( die, parent );
    retstr = ( FormName( &decstruct ) ).s;

    return( retstr );
}

extern void DRDecoratedNameList( void *obj, dr_handle die, dr_handle parent,
                                 void (* cb)( void *, char *,
                                               int, dr_handle,
                                               dr_sym_type ) )
/**************************************************************************/
{
    BrokenName_T    decstruct;
    List_T          list;

    decstruct = BuildList( die, parent );

    list = FormList( &decstruct );
    IterateList( cb, obj, list );
}

static BrokenName_T BuildList( dr_handle die, dr_handle parent )
/**************************************************************/
{
    Loc_T           loc;
    BrokenName_T    decstruct = Empty_Broken_Name;
    compunit_info   *compunit;
    dr_language     lang;

    FillLoc( &loc, die );
    loc.parent = parent;

    compunit = DWRFindCompileInfo( die );
    lang = DRGetLanguageAT( compunit->start + COMPILE_UNIT_HDR_SIZE );

    switch( lang ) {
    case DR_LANG_CPLUSPLUS:
    case DR_LANG_C:
        BuildCList( &decstruct, &loc );
        break;
    case DR_LANG_FORTRAN:
        BuildFortranList( &decstruct, &loc );
        break;
    default:
        DWREXCEPT( DREXCEP_DWARF_LIB_FAIL );
    }

    return( decstruct );
}

static void BuildFortranList( BrokenName_T *decname, Loc_T *loc )
/***************************************************************/
{

⌨️ 快捷键说明

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