i86obj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,113 行 · 第 1/5 页
C
2,113 行
attr = FEAttr( sym );
if( ( attr & FE_PROC ) == 0 ) {
if( attr & FE_DLLEXPORT ) {
OutDLLExport( 0, sym );
}
}
if( attr & FE_COMMON ) {
ComdatData( lbl, sym );
} else {
if( CurrSeg->comdat_label != NULL )
NormalData();
if( UseImportForm( attr ) ) {
OutExport( sym );
}
}
for( curr = CurrSeg->virt_func_refs; curr != NULL; curr = next ) {
cookie = curr->cookie;
while( cookie != NULL ) {
OutVirtFuncRef( FEAuxInfo( cookie, VIRT_FUNC_SYM ) );
cookie = FEAuxInfo( cookie, VIRT_FUNC_NEXT_REFERENCE );
}
next = curr->next;
_Free( curr, sizeof( virt_func_ref_list ) );
}
CurrSeg->virt_func_refs = NULL;
} else if( CurrSeg->prefix_comdat_state != PCS_OFF ) {
/*
We have data coming out before the COMDAT symbol (select table
before a common procedure). Gen a 'magical' comdat name to
deal with it.
*/
if( CurrSeg->prefix_comdat_state == PCS_NEED ) {
ComdatData( lbl, NULL );
CurrSeg->prefix_comdat_state = PCS_ACTIVE;
}
TellCommonLabel( lbl, CurrSeg->comdat_prefix_import );
}
i = SegInfo->used;
lc = CurrSeg->location;
TellAddress( lbl, lc );
while( --i >= 0 ) {
obj = _ARRAYOF( SegInfo, index_rec )[ i ].obj;
if( obj != NULL ) { /* twas flushed and not redefined*/
owner = &obj->patches;
for(;;) {
curr_pat = *owner;
if( curr_pat == NULL )
break;
if( curr_pat->lbl == lbl ) {
patptr = &_ARRAYOF( &obj->data, byte )[ curr_pat->pat.where ];
if( curr_pat->pat.attr & ADD_PATCH ) {
if( curr_pat->pat.attr & LONG_PATCH ) {
_TargetAddL( *(unsigned_32 *)patptr, lc );
} else if( curr_pat->pat.attr & WORD_PATCH ) {
_TargetAddW( *(unsigned_16 *)patptr, lc );
} else {
_TargetAddB( *(byte *)patptr, lc );
}
} else {
if( curr_pat->pat.attr & LONG_PATCH ) {
*(unsigned_32 *)patptr = _TargetLongInt( lc );
} else if( curr_pat->pat.attr & WORD_PATCH ) {
*(unsigned_16 *)patptr = _TargetInt( lc );
} else {
*(byte *)patptr = _TargetInt( lc );
}
}
*owner = curr_pat->link;
_Free( curr_pat, sizeof( temp_patch ) );
} else {
owner = &curr_pat->link;
}
}
}
}
ctl = AskLblPatch( lbl );
i = ctl->used;
pat = ctl->array;
while( i > 0 ) {
DoPatch( pat, lc );
pat++;
i--;
}
KillArray( ctl );
TellDonePatch( lbl );
}
extern void AbsPatch( abspatch *patch, offset lc ) {
/******************************************************/
if( patch->flags & AP_HAVE_OFFSET ) {
DoPatch( &patch->pat, lc );
FreeAbsPatch( patch );
} else {
patch->value = lc;
patch->flags |= AP_HAVE_VALUE;
}
}
static void SetAbsPatches( void ) {
/*******************************/
abspatch *patch;
object *obj;
obj = CurrSeg->obj;
patch = AbsPatches;
while( patch != NULL ) {
if( patch->pat.ref == INVALID && patch->obj == obj ) {
patch->pat.ref = AskObjHandle();
patch->flags |= AP_HAVE_OFFSET;
}
patch = patch->link;
}
}
static void SetPatches( void ) {
/****************************/
temp_patch *curr_pat;
temp_patch *junk;
array_control *ctl;
patch *pat;
curr_pat = CurrSeg->obj->patches;
while( curr_pat != NULL ) {
ctl = AskLblPatch( curr_pat->lbl );
NeedMore( ctl, 1 );
pat = &_ARRAYOF( ctl, patch )[ ctl->used++ ];
pat->ref = AskObjHandle();
pat->where = curr_pat->pat.where;
pat->attr = curr_pat->pat.attr;
junk = curr_pat;
curr_pat = curr_pat->link;
_Free( junk, sizeof( temp_patch ) );
}
}
extern array_control *InitPatch( void ) {
/************************************/
#define MODEST_PAT 10
#define INCREMENT_PAT 10
return( InitArray( sizeof( patch ), MODEST_PAT, INCREMENT_PAT ) );
}
static void InitFPPatches( void ) {
/*******************************/
int i;
i = FPP_NUMBER_OF_TYPES;
while( --i >= 0 ) {
FPPatchImp[ i ] = NOT_IMPORTED;
}
}
#define MODEST_IMP BUFFSIZE
#define INCREMENT_IMP 50
extern void OutFPPatch( fp_patches i ) {
/******************************************/
import_handle idx;
idx = FPPatchImp[ i ];
if( idx == NOT_IMPORTED ) {
idx = ImportHdl++;
FPPatchImp[ i ] = idx;
if( Imports == NULL ) {
Imports = InitArray( sizeof( byte ), MODEST_IMP, INCREMENT_IMP );
}
if( GenStaticImports ) {
EjectImports();
GenStaticImports = FALSE;
}
OutName( FPPatchName[ i ], Imports );
OutIdx( 0, Imports ); /* type index*/
if( FPPatchAltName[ i ] != NULL ) {
ImportHdl++;
OutName( FPPatchAltName[ i ], Imports );
OutIdx( 0, Imports ); /* type index*/
}
}
CheckLEDataSize( 2*sizeof( offset ), TRUE );
DoFix( idx, FALSE, BASE_IMP, F_OFFSET, 0 );
if( FPPatchAltName[ i ] != NULL ) {
IncLocation( sizeof( byte ) );
DoFix( idx+1, FALSE, BASE_IMP, F_OFFSET, 0 );
DecLocation( sizeof( byte ) );
}
}
extern void OutPatch( label_handle lbl, patch_attr attr ) {
/*************************************************************/
temp_patch *pat;
object *obj;
/* careful, might be patching offset of seg:off*/
CheckLEDataSize( 3*sizeof( offset ), TRUE );
_Alloc( pat, sizeof( temp_patch ));
obj = CurrSeg->obj;
pat->link = obj->patches;
pat->lbl = lbl;
pat->pat.ref = INVALID;
pat->pat.where = CurrSeg->location - obj->start + CurrSeg->data_prefix_size;
pat->pat.attr = attr;
obj->patches = pat;
}
extern abspatch *NewAbsPatch( void ) {
/**************************************/
abspatch *new;
_Alloc( new, sizeof( *new ) );
memset( new, 0, sizeof( *new ) );
new->link = AbsPatches;
AbsPatches = new;
return( new );
}
extern void OutAbsPatch( abspatch *patch, patch_attr attr ) {
/***************************************************************/
object *obj;
long_offset value;
CheckLEDataSize( 2*sizeof( offset ), TRUE );
if( patch->flags & AP_HAVE_VALUE ) {
value = patch->value;
FreeAbsPatch( patch );
} else {
obj = CurrSeg->obj;
patch->obj = obj;
patch->pat.ref = INVALID;
patch->pat.where = CurrSeg->location - obj->start + CurrSeg->data_prefix_size;
patch->pat.attr = attr;
value = 0;
}
if( attr & LONG_PATCH ) {
OutDataLong( value );
} else if( attr & WORD_PATCH ) {
OutDataInt( value );
} else {
OutDataByte( (byte)value );
}
}
static void DumpImportResolve( sym_handle sym, import_handle idx ) {
/******************************************************************/
sym_handle def_resolve;
import_handle def_idx;
array_control *cmt;
unsigned nidx;
pointer cond;
int type;
def_resolve = FEAuxInfo( sym, DEFAULT_IMPORT_RESOLVE );
if( def_resolve != NULL && def_resolve != sym ) {
def_idx = GenImport( def_resolve, NORMAL );
EjectImports();
cmt = InitArray( sizeof( byte ), MODEST_HDR, INCREMENT_HDR );
type = (int) FEAuxInfo( sym, IMPORT_TYPE );
switch( type ) {
case IMPORT_IS_LAZY:
NeedMore( cmt, sizeof( unsigned_16 ) );
_ARRAY( cmt, unsigned_16 ) = _TargetInt( LAZY_EXTRN_COMMENT );
cmt->used += sizeof( unsigned_16 );
OutIdx( idx, cmt );
OutIdx( def_idx, cmt );
break;
case IMPORT_IS_WEAK:
NeedMore( cmt, sizeof( unsigned_16 ) );
_ARRAY( cmt, unsigned_16 ) = _TargetInt( WEAK_EXTRN_COMMENT );
cmt->used += sizeof( unsigned_16 );
OutIdx( idx, cmt );
OutIdx( def_idx, cmt );
break;
case IMPORT_IS_CONDITIONAL_PURE:
NeedMore( cmt, sizeof( unsigned_16 ) );
_ARRAY( cmt, unsigned_16 ) = _TargetInt( WEAK_EXTRN_COMMENT );
cmt->used += sizeof( unsigned_16 );
OutIdx( idx, cmt );
OutIdx( def_idx, cmt );
PutObjRec( CMD_COMENT, cmt->array, cmt->used );
cmt->used = 0;
/* fall through */
case IMPORT_IS_CONDITIONAL:
NeedMore( cmt, sizeof( unsigned_16 ) );
_ARRAY( cmt, unsigned_16 ) = _TargetInt( LINKER_COMMENT );
cmt->used += sizeof( unsigned_16 );
NeedMore( cmt, sizeof( byte ) );
if( type == IMPORT_IS_CONDITIONAL ) {
_ARRAY( cmt, byte ) = LDIR_VF_TABLE_DEF;
} else {
_ARRAY( cmt, byte ) = LDIR_VF_PURE_DEF;
}
cmt->used += sizeof( byte );
OutIdx( idx, cmt );
OutIdx( def_idx, cmt );
cond = FEAuxInfo( sym, CONDITIONAL_IMPORT );
while( cond != NULL ) {
sym = FEAuxInfo( cond, CONDITIONAL_SYMBOL );
DoOutObjectName( sym, GetSymLName, &nidx, NORMAL );
OutIdx( nidx, cmt );
cond = FEAuxInfo( cond, NEXT_CONDITIONAL );
}
FlushNames();
break;
}
PutObjRec( CMD_COMENT, cmt->array, cmt->used );
KillArray( cmt );
}
}
static import_handle GenImport( sym_handle sym, import_type kind ) {
/**********************************************************************/
import_handle idx;
fe_attr attr;
idx = AskImportHandle( sym );
if( idx == NOT_IMPORTED || kind == SPECIAL ) {
idx = ImportHdl++;
if( Imports == NULL ) {
Imports = InitArray( sizeof( byte ), MODEST_IMP, INCREMENT_IMP );
}
attr = FEAttr( sym );
CheckImportSwitch( !( attr & FE_GLOBAL) );
if( kind != SPECIAL )
TellImportHandle( sym, idx );
if( kind == NORMAL ) {
if( (attr & FE_DLLIMPORT) ) {
kind = DLLIMPORT;
} else if( _IsModel( POSITION_INDEPENDANT ) ) {
if( ( attr & FE_THREAD_DATA ) != 0 ) {
kind = PIC_RW;
}
}
}
DoOutObjectName( sym, OutName, Imports, kind );
OutIdx( 0, Imports ); /* type index*/
if( kind != SPECIAL ) {
DumpImportResolve( sym, idx );
}
}
return( idx );
}
static void DoFix( int idx, bool rel, base_type base,
fix_class class, int sidx ) {
/**************************************************/
fixup *cursor;
int where;
object *obj;
index_rec *rec;
byte b;
fix_class class_flags;
b = rel ? LOCAT_REL : LOCAT_ABS;
if( (class & F_MASK) == F_PTR && CurrSeg->data_in_code ) {
CurrSeg->data_ptr_in_code = TRUE;
}
class_flags = (class & ~F_MASK);
class &= F_MASK;
#if _TARGET & _TARG_80386
if( class_flags & F_FAR16 ) {
/* want a 16:16 fixup for a __far16 call */
class = F_PTR;
} else if( _IsTargetModel( EZ_OMF ) ) {
switch( class ) {
case F_OFFSET:
case F_LDR_OFFSET:
class = F_PHAR_OFFSET;
break;
case F_PTR:
class = F_PHAR_PTR;
break;
default:
break;
}
} else {
switch( class ) {
case F_OFFSET:
class = F_MS_OFFSET_32;
break;
case F_LDR_OFFSET:
class = F_MS_LDR_OFFSET_32;
break;
case F_PTR:
class = F_MS_PTR;
break;
default:
break;
}
}
#endif
obj = CurrSeg->obj;
NeedMore( &obj->fixes, sizeof( fixup ) );
cursor = &_ARRAY( &obj->fixes, fixup );
where = CurrSeg->location - obj->start;
cursor->locatof = b + ( class << S_LOCAT_LOC ) + ( where >> 8 );
cursor->fset = where;
obj->fixes.used += sizeof( fixup );
if( base != BASE_IMP ) {
rec = AskIndexRec( s
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?