i86obj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,113 行 · 第 1/5 页
C
2,113 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <string.h>
#include "standard.h"
#include "sysmacro.h"
#include "cg.h"
#include "bckdef.h"
#include "cgaux.h"
#include "objrep.h"
#include "system.h"
#include "i86obj.h"
#include "model.h"
#include "hostsys.h"
#include "zoiks.h"
#include "fppatch.h"
#include "ocentry.h"
#include "dbcue.h"
#include "import.h"
#include "feprotos.h"
#ifdef _PHAR_LAP /* This is a misnomer. Let's rename it */
#define _OMF_32
#endif
#define _CopyTrans( src, dst, len ) Copy( src, dst, len )
extern pointer Copy(pointer,pointer,uint);
extern char *AskRTName(int);
extern void TellRTHandle(int,import_handle);
extern import_handle AskRTHandle(int);
extern void TellImportHandle(sym_handle,import_handle);
extern import_handle AskImportHandle(sym_handle);
extern void TellDonePatch(label_handle);
extern pointer AskLblPatch(label_handle);
extern void TellAddress(label_handle,offset);
extern sym_handle AskForLblSym(label_handle);
extern void FatalError(char *);
extern void CloseObj( void );
extern void PatchObj(objhandle,uint,byte*,int);
extern void GetFromObj(objhandle,uint,byte*,int);
extern void ScratchObj( void );
extern objhandle AskObjHandle( void );
extern void PutObjRec(byte,byte*,uint);
extern void OpenObj( void );
extern char *CopyStr(char*,char*);
extern void EmptyQueue( void );
extern uint Length(pointer);
extern void TellCommonLabel(label_handle, int );
extern void TellUnreachLabels(void);
extern void KillLblRedirects( void );
/* DF interface */
extern void DFObjInitInfo( void );
extern void DFObjLineInitInfo( void );
extern void DFBegCCU( seg_id code, long dbg_pch );
extern void DFDefSegs( void );
extern void DFObjFiniDbgInfo( offset codesize );
extern void DFObjLineFiniDbgInfo( void );
extern void DFLineNum( cue_state *, offset );
extern void DFSegRange( void );
extern void DFSymRange( sym_handle, offset );
/* CV interface */
extern void CVObjInitInfo( void );
extern void CVDefSegs( void );
extern void CVLineNum( cue_state *, offset );
extern void CVObjFiniDbgInfo( void );
/* WV interface */
extern void WVObjInitInfo( void );
extern void WVTypesEof( void );
extern void WVDmpCueInfo( long_offset here );
/* Forward ref's */
static array_control *InitArray(int ,int ,int );
extern seg_id SetOP(seg_id );
extern offset AskLocation(void);
static void OutOffset(offset );
static void OutInt(int );
extern void IncLocation(offset );
static void DecLocation(offset );
extern void OutDataInt(int );
static void ChangeObjSrc( char *fname );
static void OutName( char *name, void *dest );
static void DoSegment( segdef *seg, array_control *dgroup_def,
array_control *tgroup_def, bool use_16 );
static void NeedMore( array_control *arr, int more );
static void InitFPPatches(void);
static void OutIdx( int value, array_control *dest );
static void KillArray( array_control *arr );
static void DoSegGrpNames( array_control *dgroup_def,
array_control *tgroup_def );
static void OutModel( array_control *dest );
static void OutString( char *name, array_control *dest );
static void DoASegDef( index_rec *rec, bool use_16 );
static void FillArray( array_control *res, int size,
int starting, int increment );
static void OutCGroup( int sidx );
static void OutGroup( int sidx, array_control *group_def, int *index_p );
static void FiniTarg( void );
static void NormalData( void );
static void KillStatic( array_control *arr );
static void FlushObject( void );
static void EndModule( void );
static void FiniAbsPatches( void );
static void OutByte( byte value );
static void CheckLEDataSize( int max_size, bool need_init );
static void EjectLEData( void );
static import_handle GenImport( sym_handle sym, import_type kind );
static void FlushSelect( void );
static void FlushLineNum( void );
static void OutObjectName( sym_handle sym, array_control *dest );
static void EjectExports( void );
extern void OutSelect( bool starts );
extern void OutRTImportRel( int rtindex, fix_class class, bool rel );
extern void OutDataByte( byte value );
extern void OutDataLong( long value );
static void DoFix( int idx, bool rel, base_type base,
fix_class class, int sidx );
extern void OutDLLExport( uint words, sym_handle sym );
static void CheckImportSwitch( bool next_is_static );
static void InitLineInfo( void );
static void EjectImports( void );
static void OutLEDataStart( bool iterated );
#ifndef _OMF_32
static void OutLongOffset( long_offset value );
#endif
extern seg_id DbgLocals;
extern seg_id DbgTypes;
extern bool Used87;
extern byte OptForSize;
static array_control *Out;
static byte *OutBuff;
static bool GenStaticImports;
static import_handle ImportHdl;
static array_control *Imports;
static array_control *SegInfo;
static abspatch *AbsPatches;
static seg_id CodeSeg = BACKSEGS;
static seg_id BackSeg;
static segdef *SegDefs;
static long_offset CodeSize;
static long_offset DataSize;
static long_offset DbgTypeSize;
static index_rec *CurrSeg;
static int GroupIndex;
static int DGroupIndex;
static int SegmentIndex;
static int PrivateIndexRW;
static int PrivateIndexRO;
static int CodeGroupGIdx;
static int CodeGroupNIdx;
static char CodeGroup[80];
static char DataGroup[80];
static offset SelStart;
static unsigned_16 SelIdx;
static unsigned BackSegIdx = BACKSEGS;
static import_handle FPPatchImp[FPP_NUMBER_OF_TYPES];
static int SegsDefd;
static bool NoDGroup;
static short CurrFNo;
#ifdef _OMF_32
static int FlatGIndex;
static int FlatNIndex;
#endif
static int TLSGIndex;
extern void DoOutObjectName(sym_handle,void(*)(char*,void*),void*,import_type);
typedef struct lname_cache lname_cache;
struct lname_cache {
lname_cache *next;
unsigned idx;
unsigned_8 name[1]; /* var sized, first byte is length */
};
static unsigned NameIndex;
static lname_cache *NameCache;
static lname_cache *NameCacheDumped;
static char *FPPatchName[] = {
NULL,
"FIWRQQ",
"FIDRQQ",
"FIERQQ",
"FICRQQ",
"FISRQQ",
"FIARQQ",
"FIFRQQ",
"FIGRQQ"
};
static char *FPPatchAltName[] = {
NULL,
NULL,
NULL,
NULL,
"FJCRQQ",
"FJSRQQ",
"FJARQQ",
"FJFRQQ",
"FJGRQQ"
};
typedef struct virt_func_ref_list {
struct virt_func_ref_list *next;
void *cookie;
} virt_func_ref_list;
#define _ARRAY( what, type ) (*(type *)((char*)(what)->array + (what)->used))
#define _ARRAYOF( what, type ) ((type *)(what)->array)
#define _CHGTYPE( what, type ) (*(type *)&(what))
extern void InitSegDefs( void ) {
/*****************************/
SegDefs = NULL;
NameCache = NULL;
NameCacheDumped = NULL;
NameIndex = 0;
GroupIndex = 0;
DGroupIndex = 0;
TLSGIndex = 0;
#ifdef _OMF_32
FlatGIndex = 0;
#endif
SegsDefd = 0;
CodeSeg = BACKSEGS; /* just so it doesn't match a FE seg_id */
BackSegIdx = BACKSEGS;
}
static unsigned GetNameIdx( char *name, char *suff, bool alloc )
{
lname_cache **owner;
lname_cache *curr;
unsigned name_len;
unsigned suff_len;
name_len = Length( name );
suff_len = Length( suff );
owner = &NameCache;
for( ;; ) {
curr = *owner;
if( curr == NULL )
break;
if( (name_len + suff_len) == curr->name[0]
&& memcmp( name, &curr->name[1], name_len ) == 0
&& memcmp( suff, &curr->name[name_len+1], suff_len ) == 0 ) {
return( curr->idx );
}
owner = &curr->next;
}
if( !alloc )
return( 0 );
_Alloc( curr, sizeof( *curr ) + name_len + suff_len );
*owner = curr;
curr->next = NULL;
curr->idx = ++NameIndex;
assert(( name_len + suff_len ) < 256 );
curr->name[0] = name_len + suff_len;
memcpy( &curr->name[1], name, name_len );
memcpy( &curr->name[name_len+1], suff, suff_len );
return( NameIndex );
}
static void FlushNames( void )
{
/*
don't want to allocate memory because we might be in a low memory
situation
*/
unsigned_8 buff[512];
unsigned i;
lname_cache *dmp;
i = 0;
dmp = NameCacheDumped != NULL ? NameCacheDumped->next : NameCache;
for( ; dmp != NULL; dmp = dmp->next ) {
if( (i + dmp->name[0]) > (sizeof( buff ) - 1) ) {
PutObjRec( CMD_LNAMES, buff, i );
i = 0;
}
buff[i++] = dmp->name[0];
_CopyTrans( &dmp->name[1], &buff[i], dmp->name[0] );
i += dmp->name[0];
NameCacheDumped = dmp;
}
if( i > 0 ) {
PutObjRec( CMD_LNAMES, buff, i );
}
}
bool FreeObjCache( void )
{
lname_cache *tmp;
if( NameCache == NULL )
return( FALSE );
FlushNames();
while( NameCache != NULL ) {
tmp = NameCache->next;
_Free( NameCache, sizeof( *NameCache ) + NameCache->name[0] );
NameCache = tmp;
}
NameCacheDumped = NULL;
return( TRUE );
}
extern void DefSegment( seg_id id, seg_attr attr, char *str, uint align, bool use_16 ) {
/******************************************************************************************/
segdef *new;
segdef **owner;
seg_id first_code;
_Alloc( new, sizeof( segdef ) );
new->id = id;
new->attr = attr;
new->align = align;
_Alloc( new->str, Length( str ) + 1 );
CopyStr( str, new->str );
owner = &SegDefs;
while( *owner != NULL ) {
owner = &(*owner)->next;
}
first_code = BACKSEGS;
*owner = new;
new->next = NULL;
if( attr & EXEC ) {
if( CodeSeg == BACKSEGS ) {
CodeSeg = id;
first_code = id;
}
if( OptForSize == 0 && new->align < 16 ) {
new->align = 16;
}
}
if( attr & BACK ) {
BackSeg = id;
}
if( NameIndex != 0 ) { /* already dumped out segments*/
DoSegment( new, NULL, NULL, use_16 ); /* don't allow DGROUP after BEStart */
SegDefs = NULL;
}
if( first_code != BACKSEGS && _IsModel( DBG_DF ) ) {
DFBegCCU( first_code, 0 );
}
}
static void DoEmptyQueue( void )
/*******************/
{
EmptyQueue();
TellUnreachLabels();
}
static index_rec *AskSegIndex( seg_id seg ) {
/**************************************************/
index_rec *rec;
int i;
i = 0;
rec = SegInfo->array;
for( ;; ) {
if( ++i > SegInfo->used )
return( NULL );
if( rec->seg == seg )
return( rec );
++rec;
}
}
extern void ObjInit( void ) {
/*************************/
array_control *names; /* for LNAMES*/
array_control *dgroup_def;
array_control *tgroup_def;
void *depend;
#define MODEST_HDR 50
#define INCREMENT_HDR 50
#define MODEST_INFO 5
#define INCREMENT_INFO 5
InitFPPatches();
CodeSize = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?