wcomdef.c

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

C
534
字号
/****************************************************************************
*
*                            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: COMDEF -- support for Microsoft COMDEFs 
*
****************************************************************************/

#include <string.h>
#include <stdlib.h>
#include "linkstd.h"
#include "virtmem.h"
#include "pcobj.h"
#include "alloc.h"
#include "specials.h"
#include "msg.h"
#include "wlnkmsg.h"
#include "objnode.h"
#include "objcalc.h"
#include "objpass1.h"
#include "objomf.h"
#include "overlays.h"
#include "objio.h"
#include "dbgall.h"
#include "objstrip.h"
#include "objcache.h"
#include "omfreloc.h"
#include "ring.h"
#include "wcomdef.h"

/* these are handy constants used when processing comdat records */
#define CDAT_ALLOC_MASK         0xF
#define CDAT_CONTINUATION       0x1
#define CDAT_ITERATED           0x2
#define CDAT_STATIC             0x4
#define CDAT_SELECT_MASK        0xF0
#define CDAT_SELECT_SHIFT       12

#if 0
static char *   CDatClassNames[] = {
        CodeClassName,
        FarDataClassName,
        CodeClassName,
        DataClassName
};

static seg_leader *     CDatSegments[4];
static unsigned         CDatSegNum;     /* for making the comdat seg. name */

/* keep a base-36 number after the COMDAT_SEG to differentiate the segments*/
/* 32-bit unsigned int gives a maximum of 7 digits in base 36. */
#define CDAT_SEG_NAME "COMDAT_SEG\0\0\0\0\0\0\0\0"
static char     CDatSegName[] = CDAT_SEG_NAME;

#define CDAT_SEG_NAME_LEN sizeof(CDatSegName)
#define CDAT_SEG_NUM_OFF  10
#endif

static comdat_info *    CDatList;
static comdat_info *    FreedInfos;
static comdat_piece *   FreedPieces;


void ResetComdef( void )
/**********************/
{
#if 0
    memcpy( CDatSegName, CDAT_SEG_NAME, CDAT_SEG_NAME_LEN );
    CDatSegments[0] = NULL;
    CDatSegments[1] = NULL;
    CDatSegments[2] = NULL;
    CDatSegments[3] = NULL;
    CDatSegNum = 0;
#endif
    CDatList = NULL;
    FreedInfos = NULL;
    FreedPieces = NULL;
}

static comdat_info * AllocCDatInfo( void )
/****************************************/
{
    comdat_info *       info;

    if( FreedInfos != NULL ) {
        info = FreedInfos;
        FreedInfos = info->next;
    } else {
        _Pass1Alloc( info, sizeof(comdat_info) );
    }
    info->pieces = NULL;
    return( info );
}

static void FreeCDatInfo( comdat_info * info )
/********************************************/
{
    info->next = FreedInfos;
    FreedInfos = info;
}

static comdat_piece * AllocCDatPiece( void )
/******************************************/
{
    comdat_piece *      piece;

    if( FreedPieces != NULL ) {
        piece = FreedPieces;
        FreedPieces = piece->next;
    } else {
        _Pass1Alloc( piece, sizeof(comdat_piece) );
    }
    memset( piece, 0, sizeof(comdat_piece) );
    return( piece );
}

static void FreeCDatPiece( void * piec )
/**************************************/
{
    comdat_piece *piece = piec;
    if( piece->free_data ) {
        _LnkFree( piece->data );
    }
    piece->next = FreedPieces;
    FreedPieces = piece;
}

static unsigned_32 GetLeaf( void )
/********************************/
{
    unsigned char       leaf;
    unsigned_32         value;

    leaf = *ObjBuff++;
    if( leaf <= COMDEF_LEAF_SIZE ) {
        value = leaf;
    } else if( leaf == COMDEF_LEAF_2 ) {
        value = GET_U16_UN(ObjBuff);
        ObjBuff += sizeof( unsigned_16 );
    } else if( leaf == COMDEF_LEAF_3 ) {
        value = GET_U16_UN(ObjBuff);
        ObjBuff += sizeof( unsigned_16 );
        value += ( unsigned_32 )( *( unsigned char UNALIGN * )ObjBuff ) << 16;
        ObjBuff += sizeof( char );
    } else if( leaf == COMDEF_LEAF_4 ) {
        value = GET_U32_UN(ObjBuff);
        ObjBuff += sizeof( unsigned_32 );
    }
    return( value );
}

static bool isCOMDEF32( void )
/****************************/
{
    SEGDATA *segs = CurrMod->segs;
    SEGDATA *seg = NULL;

    for(;;) {
        seg = Ring2Step( segs, seg );
        if( seg == NULL ) break;
        // none of these are generated for Dwarf debug info so
        // we should not get confused when we are 16-bit
        if( seg->isuninit || seg->iscdat || seg->iscode ) {
            return( seg->is32bit );
        }
    }
    return( (ObjFormat & FMT_32BIT_REC) != 0 );
}

extern void ProcComdef( bool isstatic )
/*************************************/
{
    bool                is32bit = isCOMDEF32();
    char *              sym_name;
    unsigned_8          sym_len;
    byte                kind;
    unsigned_32         size;
    symbol *            sym;
    extnode *           ext;
    sym_flags           flags;

    flags = ST_CREATE | ST_REFERENCE;
    if( isstatic ) {
        flags |= ST_STATIC;
    }
    while( ObjBuff < EOObjRec ) {
        sym_name = ( ( obj_name UNALIGN * ) ObjBuff )->name;
        sym_len = ( ( obj_name UNALIGN * ) ObjBuff )->len;
        ObjBuff += sym_len + sizeof( byte );
        SkipIdx();
        kind = *ObjBuff++;
        size = GetLeaf();
        if( kind == COMDEF_FAR ) {
            size *= GetLeaf();
        }
        sym = SymXOp( flags, sym_name, sym_len );
        sym = MakeCommunalSym( sym, size, kind == COMDEF_FAR, is32bit );
        ext = AllocNode( ExtNodes );
        ext->entry = sym;
        ext->ovlref = 0;
    }
}

extern void ProcLinsym( void )
/****************************/
{
    list_of_names *     symname;
    symbol *            sym;
    bool                is32bit;
    unsigned            sym_len;

    ObjBuff++;          /* skip flags */
    symname = FindName( GetIdx() );
    sym_len = strlen( symname->name );
    sym = SymOp( ST_FIND | ST_STATIC, symname->name, sym_len );
    if( sym == NULL ) sym = SymOp( ST_FIND, symname->name, sym_len );
    if( sym == NULL ) {
        BadObject();
        return;
    }
    if( !IS_SYM_COMDAT(sym) ) return;
    is32bit = (ObjFormat & FMT_32BIT_REC) != 0;
    if( sym->mod == CurrMod && !(sym->info & SYM_DEAD) ) {
        DBIAddLines( sym->p.seg, ObjBuff, EOObjRec - ObjBuff, is32bit );
    }
}

static void DoAltDef( comdat_info *info )
/***************************************/
{
    if( !(LinkFlags & INC_LINK_FLAG) ) {
        FreeSegData( info->sdata );
    } else {
        Ring2Append( &CurrMod->segs, info->sdata );
        info->sdata->isdead = TRUE;
        InfoCDatAltDef( info );
    }
}

static void FinishComdat( void *inf )
/***********************************/
{
    comdat_info *info = inf;
    if( info->flags & SYM_DEAD ) {      // is redefined
        DoAltDef( info );

⌨️ 快捷键说明

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