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