i86obj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,113 行 · 第 1/5 页
C
2,113 行
if( lib == NULL )
break;
NeedMore( Imports, sizeof( unsigned_16 ) );
_ARRAY( Imports, unsigned_16 ) = _TargetInt( LIBNAME_COMMENT );
Imports->used += sizeof( unsigned_16 );
OutString( ( (char*)FEAuxInfo( lib, LIBRARY_NAME ) ) + 1, Imports );
PutObjRec( CMD_COMENT, Imports->array, Imports->used );
Imports->used = 0;
}
KillArray( Imports );
Imports = NULL;
KillArray( SegInfo );
FiniAbsPatches();
EndModule();
CloseObj();
FEMessage( MSG_CODE_SIZE, (pointer)CodeSize );
FEMessage( MSG_DATA_SIZE, (pointer)DataSize );
}
static void FiniTarg( void )
/******************************/
{
union{
offset s;
long_offset l;
}size;
byte attr;
index_rec *rec;
object *obj;
FlushObject();
obj = CurrSeg->obj;
if( obj->exports != NULL ) {
KillArray( obj->exports );
obj->exports = NULL;
}
rec = AskIndexRec( obj->index );
#ifdef _OMF_32
size.s = _TargetInt( rec->max_size );
#else //SEG32DBG dwarf, codview
if( rec->attr & SEG_USE_32 ) {
size.l = _TargetLongInt( rec->max_size );
} else {
size.s = _TargetInt( rec->max_size );
}
#endif
if( rec->exec ) {
CodeSize += rec->max_size + rec->total_comdat_size;
} else if( rec->cidx == _NIDX_DATA ) {
DataSize += rec->max_size + rec->total_comdat_size;
}
if( rec->big ) {
attr = rec->attr | SEG_BIG;
PatchObj( obj->segfix, SEGDEF_ATTR, &attr, sizeof( byte ) );
} else {
#ifdef _OMF_32
PatchObj( obj->segfix, SEGDEF_SIZE, (byte *)&size.s, sizeof( offset ) );
#else //SEG32DBG dwarf, codview
if( rec->attr & SEG_USE_32 ) {
PatchObj( obj->segfix, SEGDEF_SIZE, (byte *)&size.l, sizeof( long_offset ) );
} else {
PatchObj( obj->segfix, SEGDEF_SIZE, (byte *)&size.s, sizeof( offset ) );
}
#endif
}
if( obj->exports != NULL ) {
KillArray( obj->exports );
}
KillStatic( &obj->data );
KillStatic( &obj->fixes );
_Free( obj, sizeof( object ) );
}
static void DoPatch( patch *pat, offset lc ) {
/************************************************/
unsigned_32 lword;
unsigned_16 word;
byte bite;
if( pat->attr & LONG_PATCH ) {
if( pat->attr & ADD_PATCH ) {
GetFromObj( pat->ref, pat->where,
(byte *)&lword, sizeof( long_offset ) );
_TargetAddL( lword, lc );
} else {
lword = _TargetLongInt( lc );
}
PatchObj( pat->ref, pat->where, (byte *)&lword, sizeof( long_offset ) );
} else if( pat->attr & WORD_PATCH ) {
if( pat->attr & ADD_PATCH ) {
GetFromObj( pat->ref, pat->where, (byte *)&word, sizeof( short_offset ) );
_TargetAddW( word, lc );
} else {
word = _TargetInt( lc );
}
PatchObj( pat->ref, pat->where, (byte *)&word, sizeof( short_offset ) );
} else {
if( pat->attr & ADD_PATCH ) {
GetFromObj( pat->ref, pat->where, &bite, sizeof( byte ) );
_TargetAddB( bite, lc );
} else {
bite = _TargetInt( lc );
}
PatchObj( pat->ref, pat->where, &bite, sizeof( byte ) );
}
}
static void FreeAbsPatch( abspatch *patch ) {
/***********************************************/
abspatch **owner;
owner = &AbsPatches;
while( *owner != patch ) {
owner = &(*owner)->link;
}
*owner = (*owner)->link;
_Free( patch, sizeof( abspatch ) );
}
static void FiniAbsPatches( void ) {
/********************************/
abspatch *patch;
abspatch *junk;
patch = AbsPatches;
while( patch != NULL ) {
DoPatch( &patch->pat, patch->value );
junk = patch;
patch = patch->link;
_Free( junk, sizeof( abspatch ) );
}
}
/*%% Code Burst Routines*/
extern void SetUpObj( bool is_data ) {
/****************************************/
object *obj;
bool old_data;
obj = CurrSeg->obj;
if( obj == NULL )
return;
Out = &obj->data;
OutBuff = obj->data.array;
if( obj->fixes.used >= BUFFSIZE - TOLERANCE ) {
EjectLEData();
return;
}
if( (Imports != NULL) && (Imports->used >= BUFFSIZE - TOLERANCE) ) {
EjectLEData();
return;
}
/* so that a call will always fit */
CheckLEDataSize( 4*sizeof( offset ), FALSE );
if( CurrSeg->exec ) {
old_data = CurrSeg->data_in_code;
CurrSeg->data_in_code = is_data;
if( is_data != old_data ) {
if( is_data ) {
CurrSeg->start_data_in_code = TRUE;
} else {
OutSelect( FALSE );
SetUpObj( FALSE );
}
}
}
}
static void OutExport( sym_handle sym ) {
/*******************************************/
array_control *exp;
object *obj;
fe_attr attr;
obj = CurrSeg->obj;
exp = obj->exports;
if( exp == NULL ) {
exp = InitArray( sizeof( byte ), MODEST_EXP, INCREMENT_EXP );
obj->exports = exp;
}
if( obj->exports->used >= BUFFSIZE - TOLERANCE ) {
EjectExports();
}
attr = FEAttr( sym );
/* are we switching from global to statics or vis-versa */
if( obj->gen_static_exports ) {
if( attr & FE_GLOBAL ) {
EjectExports();
obj->gen_static_exports = FALSE;
}
} else {
if( !(attr & FE_GLOBAL) ) {
EjectExports();
obj->gen_static_exports = TRUE;
}
}
if( obj->exports->used == 0 ) {
if( CurrSeg->btype == BASE_GRP ) {
OutIdx( CurrSeg->base, exp ); /* group index*/
} else {
#ifdef _OMF_32
OutIdx( FlatGIndex, exp ); // will be 0 if we have none
#else
OutIdx( 0, exp );
#endif
}
OutIdx( obj->index, exp ); /* segment index*/
}
OutObjectName( sym, exp );
NeedMore( exp, sizeof( offset ) );
_ARRAY( exp, offset ) = _TargetOffset( CurrSeg->location );
exp->used += sizeof( offset );
OutIdx( 0, exp ); /* type index*/
}
static void GenComdef( void ) {
/****************************/
array_control *comdef;
unsigned count;
unsigned_8 type;
unsigned_8 ind;
unsigned long size;
sym_handle sym;
unsigned rec;
if( CurrSeg->comdat_label != NULL &&
CurrSeg->max_written < CurrSeg->comdat_size ) {
if( CurrSeg->max_written != 0 ) {
Zoiks( ZOIKS_080 );
}
/* have to eject any pending imports here or the ordering
gets messed up */
EjectImports();
size = CurrSeg->comdat_size - CurrSeg->max_written;
comdef = InitArray( sizeof( byte ), MODEST_EXP, INCREMENT_EXP );
sym = CurrSeg->comdat_symbol;
OutObjectName( sym, comdef );
NeedMore( comdef, 4 );
_ARRAY( comdef, unsigned_8 ) = 0; /* type index */
comdef->used += sizeof( unsigned_8 );
if( CurrSeg->btype == BASE_GRP && CurrSeg->base == DGroupIndex ) {
type = COMDEF_NEAR;
} else {
type = COMDEF_FAR;
}
_ARRAY( comdef, unsigned_8 ) = type; /* common type */
comdef->used += sizeof( unsigned_8 );
if( type == COMDEF_FAR ) {
_ARRAY( comdef, unsigned_8 ) = 1; /* number of elements */
comdef->used += sizeof( unsigned_8 );
}
/*
Strictly speaking, this should be <= 0x80. However a number
of tools (including our own!) have problems with doing a
128 byte COMDEF size in 1 byte, so we'll waste some space
and use 2 bytes, but sleep much sounder at night.
*/
if( size < 0x80 ) {
count = 1;
ind = 0;
} else if( size < 0x1000 ) {
count = 2;
ind = COMDEF_LEAF_2;
} else if( size < 0x100000 ) {
count = 3;
ind = COMDEF_LEAF_3;
} else {
count = 4;
ind = COMDEF_LEAF_4;
}
if( ind != 0 ) {
/* multi-byte indicator */
_ARRAY( comdef, unsigned_8 ) = ind;
comdef->used += sizeof( unsigned_8 );
}
NeedMore( comdef, count );
do {
/* element size */
_ARRAY( comdef, unsigned_8 ) = size & 0xff;
comdef->used += sizeof( unsigned_8 );
size >>= 8;
--count;
} while( count != 0 );
if( FEAttr( sym ) & FE_GLOBAL ) {
rec = CMD_COMDEF;
} else {
rec = CMD_LCOMDEF;
}
PutObjRec( rec, comdef->array, comdef->used );
KillArray( comdef );
TellImportHandle( sym, ImportHdl++ );
}
}
static void GetSymLName( char *name, void *nidx )
{
*(unsigned *)nidx = GetNameIdx( name, "", TRUE );
}
static unsigned NeedComdatNidx( import_type kind ) {
/***************************************************/
if( CurrSeg->comdat_nidx == 0 ) {
DoOutObjectName( CurrSeg->comdat_symbol, GetSymLName,
&CurrSeg->comdat_nidx, kind );
FlushNames();
}
return( CurrSeg->comdat_nidx );
}
static void NormalData( void ) {
/****************************/
GenComdef();
CurrSeg->total_comdat_size += CurrSeg->comdat_size;
EjectLEData();
FlushLineNum();
FlushSelect();
CurrSeg->location = CurrSeg->max_written = CurrSeg->max_size;
CurrSeg->comdat_size = 0;
CurrSeg->comdat_label = NULL;
CurrSeg->comdat_symbol = NULL;
CurrSeg->need_base_set = TRUE;
CurrSeg->prefix_comdat_state = PCS_OFF;
KillLblRedirects();
}
static void ComdatData( label_handle lbl, sym_handle sym ) {
/**************************************************************/
GenComdef();
CurrSeg->total_comdat_size += CurrSeg->comdat_size;
EjectLEData();
FlushLineNum();
FlushSelect();
CurrSeg->obj->lines_generated = FALSE;
CurrSeg->location = CurrSeg->max_written = 0;
CurrSeg->comdat_size = 0;
CurrSeg->comdat_nidx = 0;
CurrSeg->comdat_label = lbl;
if( sym != NULL ) {
CurrSeg->comdat_symbol = sym;
} else {
NeedComdatNidx( SPECIAL );
CurrSeg->comdat_prefix_import =
GenImport( CurrSeg->comdat_symbol, SPECIAL );
TellCommonLabel( lbl, CurrSeg->comdat_prefix_import );
}
CurrSeg->need_base_set = TRUE;
CurrSeg->prefix_comdat_state = PCS_OFF;
KillLblRedirects();
}
static void OutVirtFuncRef( sym_handle virt ) {
/*************************************************/
object *obj;
unsigned extdef;
if( virt == NULL ) {
extdef = 0;
} else {
extdef = GenImport( virt, NORMAL );
}
EjectLEData();
obj = CurrSeg->obj;
Out = &obj->data;
OutBuff = obj->data.array;
Out->used = 0;
NeedMore( Out, sizeof( unsigned_16 ) );
_ARRAY( Out, unsigned_16 ) = _TargetInt( LINKER_COMMENT );
Out->used += sizeof( unsigned_16 );
OutByte( LDIR_VF_REFERENCE );
OutIdx( extdef, Out );
if( CurrSeg->comdat_symbol != NULL ) {
OutIdx( 0, Out );
OutIdx( NeedComdatNidx( NORMAL ), Out );
} else {
OutIdx( CurrSeg->sidx, Out );
}
PutObjRec( CMD_COMENT, Out->array, Out->used );
Out->used = 0;
}
extern void OutLabel( label_handle lbl ) {
/********************************************/
temp_patch **owner;
temp_patch *curr_pat;
array_control *ctl;
patch *pat;
int i;
pointer patptr;
object *obj;
offset lc;
sym_handle sym;
fe_attr attr;
void *cookie;
virt_func_ref_list *curr;
virt_func_ref_list *next;
sym = AskForLblSym( lbl );
if( sym != NULL ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?