asmfixup.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 549 行 · 第 1/2 页
C
549 行
/*
this routine marks the correct target offset and data record address for
FIXUPP record;
*/
{
struct asmfixup *fixup;
fixup = InsFixups[index];
if( fixup != NULL ) {
fixup->fixup_loc = AsmCodeAddress;
#if defined( _STANDALONE_ )
// fixup->offset = Code->data[index];
// Code->data[index] = 0; // fixme
if( fixup->fixup_type != FIX_SEG ) {
Code->data[index] += fixup->offset;
}
/*
20-Aug-92: put the offset in the location instead of attaching it
to the fixup
*/
#else
fixup->offset = Code->data[index];
Code->data[index] = 0;
#endif
switch( determinant ) {
case OP_I16:
case OP_J32:
switch( fixup->fixup_type ) {
case FIX_OFF32:
fixup->fixup_type = FIX_OFF16;
break;
case FIX_PTR32:
fixup->fixup_type = FIX_PTR16;
break;
}
break;
case OP_I32:
case OP_J48:
switch( fixup->fixup_type ) {
case FIX_OFF16:
fixup->fixup_type = FIX_OFF32;
break;
case FIX_PTR16:
fixup->fixup_type = FIX_PTR32;
break;
}
break;
}
}
}
#if defined( _STANDALONE_ )
struct fixup *CreateFixupRec( int index )
/***************************************/
/* Create a fixup record for WOMP;
Note that if Modend is TRUE, it means the fixup is the starting address
for the module.
*/
{
struct asmfixup *fixup; // fixup structure from WASM
struct fixup *fixnode; // fixup structure from WOMP
struct asm_sym *sym;
fixup = InsFixups[index];
if( fixup == NULL )
return( NULL );
fixnode = FixNew();
fixnode->next = NULL;
fixnode->self_relative = FALSE;
fixnode->lr.target_offset = 0;
if( !Modend ) {
fixnode->lr.is_secondary = TRUE;
} else {
fixnode->lr.is_secondary = FALSE;
fixnode->lr.target_offset = fixup->offset;
}
if( !Modend ) {
switch( fixup->fixup_type ) {
case FIX_LOBYTE:
fixnode->loc_method = FIX_LO_BYTE;
break;
case FIX_RELOFF8:
fixnode->self_relative = TRUE;
fixnode->loc_method = FIX_LO_BYTE;
break;
case FIX_RELOFF16:
fixnode->self_relative = TRUE;
case FIX_OFF16:
fixnode->loc_method = FIX_OFFSET;
break;
case FIX_RELOFF32:
fixnode->self_relative = TRUE;
case FIX_OFF32:
fixnode->loc_method = FIX_OFFSET386;
break;
case FIX_SEG:
fixnode->loc_method = FIX_BASE;
break;
case FIX_PTR16:
fixnode->loc_method = FIX_POINTER;
break;
case FIX_PTR32:
fixnode->loc_method = FIX_POINTER386;
break;
}
}
sym = fixup->sym;
if( sym == NULL )
return( NULL );
fixnode->loader_resolved = FALSE;
fixnode->loc_offset = AsmCodeAddress - GetCurrSegStart();
/*------------------------------------*/
/* Determine the Target and the Frame */
/*------------------------------------*/
if( sym->state == SYM_UNDEFINED ) {
AsmErr( SYMBOL_NOT_DEFINED, sym->name );
return( NULL );
} else if( sym->state == SYM_GRP ) {
if( Modend ) {
AsmError( INVALID_START_ADDRESS );
return( NULL );
}
fixnode->lr.target = TARGET_GRP;
fixnode->lr.target_datum = GetGrpIdx( sym );
if( fixup->frame != EMPTY ) {
fixnode->lr.frame = fixup->frame;
fixnode->lr.frame_datum = fixup->frame_datum;
} else {
fixnode->lr.frame = FRAME_GRP;
fixnode->lr.frame_datum = fixnode->lr.target_datum;
}
} else if( sym->state == SYM_SEG ) {
if( Modend ) {
AsmError( INVALID_START_ADDRESS );
return( NULL );
}
fixnode->lr.target = TARGET_SEG;
fixnode->lr.target_datum = GetSegIdx( sym );
if( fixup->frame != EMPTY ) {
fixnode->lr.frame = fixup->frame;
fixnode->lr.frame_datum = fixup->frame_datum;
} else {
fixnode->lr.frame = FRAME_SEG;
fixnode->lr.frame_datum = fixnode->lr.target_datum;
}
} else {
/* symbol is a label */
if( sym->state == SYM_EXTERNAL ) {
if( Modend ) {
if( sym->mem_type == MT_BYTE ||
sym->mem_type == MT_SBYTE ||
sym->mem_type == MT_WORD ||
sym->mem_type == MT_SWORD ||
sym->mem_type == MT_DWORD ||
sym->mem_type == MT_SDWORD ||
sym->mem_type == MT_FWORD ||
sym->mem_type == MT_QWORD ||
sym->mem_type == MT_TBYTE ||
sym->mem_type == MT_OWORD ||
sym->mem_type == MT_ABS ) {
AsmError( MUST_BE_ASSOCIATED_WITH_CODE );
return( NULL );
}
fixnode->lr.target = TARGET_EXT & TARGET_WITH_DISPL;
} else {
fixnode->lr.target = TARGET_EXT;
}
fixnode->lr.target_datum = GetExtIdx( sym );
if( fixup->frame == FRAME_GRP && fixup->frame_datum == 0 ) {
/* set the frame to the frame of the corresponding segment */
fixup->frame_datum = GetGrpIdx( sym );
}
} else {
/**/myassert( sym->segment != NULL );
if( Modend ) {
fixnode->lr.target = TARGET_SEG & TARGET_WITH_DISPL;
fixup->frame = FRAME_TARG;
} else {
fixnode->lr.target = TARGET_SEG;
}
fixnode->lr.target_datum = GetSegIdx( sym->segment );
}
/* HMMM .... what if fixup->frame is say -2 .... ie empty?
* what should really be going on here?
*/
// fixnode->lr.frame = (uint_8)fixup->frame;
// fixnode->lr.frame_datum = fixup->frame_datum;
if( fixup->frame != EMPTY ) {
fixnode->lr.frame = (uint_8)fixup->frame;
} else {
fixnode->lr.frame = FRAME_TARG;
}
fixnode->lr.frame_datum = fixup->frame_datum;
if( Modend )
return( fixnode );
}
/*--------------------*/
/* Optimize the fixup */
/*--------------------*/
if( fixnode->lr.frame == ( fixnode->lr.target - TARGET_SEG ) ) {
fixnode->lr.frame = FRAME_TARG;
}
return( fixnode );
}
int store_fixup( int index )
/**************************/
/* Store the fixup information in a WOMP fixup record */
{
struct fixup *fixnode;
if( Parse_Pass == PASS_1 )
return( NOT_ERROR );
if( InsFixups[index] == NULL )
return( NOT_ERROR );
fixnode = CreateFixupRec( index );
if( fixnode == NULL )
return( ERROR );
if( FixupListHead == NULL ) {
FixupListTail = FixupListHead = fixnode;
} else {
FixupListTail->next = fixnode;
FixupListTail = fixnode;
}
return( NOT_ERROR );
}
int MakeFpFixup( struct asm_sym *sym )
/*************************************/
{
int old_count;
int_8 old_frame;
old_count = Opnd_Count;
old_frame = Frame;
Opnd_Count = 2;
Frame = FRAME_LOC;
AddFixup( sym, FIX_OFF16, OPTJ_NONE );
Frame = old_frame;
Opnd_Count = old_count;
if( store_fixup( 2 ) == ERROR )
return( ERROR ); // extra entry in insfixups
return( NOT_ERROR );
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?