asiobj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 569 行 · 第 1/2 页
C
569 行
CurrAlignment = 0; // alignment disabled
// Here we add a label marking the beginning of the code stream.
// Relocs to this label can be done by ObjEmitMetaReloc().
doStackLabel( SymAdd( ASMCODESTART, SYM_LABEL ) );
}
extern void ObjSetLocation( owl_offset offset ) {
//***********************************************
assert( AsmLastAddress > offset );
AsmCodeAddress = offset;
}
extern bool ObjEmitMetaReloc( owl_reloc_type type, bool align ) {
//***************************************************************
// Emit a reloc to the beginning of code.
// Must be a relative reloc. If not, FALSE is returned.
if( !IS_RELOC_RELATIVE( type ) ) return( FALSE );
ObjEmitReloc( ASMCODESTART, type, align, TRUE );
return( TRUE );
}
extern void ObjEmitRelocAddend( owl_reloc_type type, uint_32 addend ) {
//*********************************************************************
uint_32 bit_mask;
uint_32 *pdata;
bit_mask = relocMasks[ type ];
pdata = (uint_32 *)&AsmCodeBuffer[ AsmCodeAddress ];
*pdata = (*pdata&~bit_mask)|(((addend&bit_mask)+(*pdata&bit_mask))&bit_mask);
}
static bool findLabel( label_list labels, char *label_name ) {
//************************************************************
label_list curr_label;
curr_label = labels;
while( curr_label ) {
if( strcmp( SymName( curr_label->sym ), label_name ) == 0 ) {
return( TRUE );
}
curr_label = curr_label->next;
}
return( FALSE );
}
extern bool ObjLabelDefined( sym_handle sym ) {
//*********************************************
enum sym_state state;
char *sym_name;
// Check if it's been emitted by us
if( sym && SymLocationKnown( sym ) ) return( TRUE );
// See if it's defined outside
sym_name = SymName( sym );
state = AsmQueryExternal( sym_name );
if( state != SYM_UNDEFINED ) {
return( TRUE );
}
// Still need to check the labelList
if( findLabel( labelList, sym_name ) ) return( TRUE );
return( FALSE );
}
static void doStackNumericLabel( uint_32 label_num ) {
//****************************************************
// Numeric labels have label_num going from 1 to 10 (corresponds to 0: - 9:)
label_list new_label;
new_label = MemAlloc( sizeof( struct asm_label ) );
new_label->sym = NULL;
new_label->next = labelList;
new_label->is_numeric = 1;
new_label->label_num = label_num;
labelList = new_label;
}
extern void ObjEmitLabel( sym_handle sym ) {
//******************************************
// Stacks up the label in the list for ObjEmitData to emit
if( ObjLabelDefined( sym ) ) {
Error( SYM_ALREADY_DEFINED, SymName( sym ) );
return;
}
doStackLabel( sym );
}
extern void ObjEmitNumericLabel( uint_32 label_num ) {
//****************************************************
doStackNumericLabel( label_num );
}
extern void ObjFlushLabels( void ) {
//**********************************
label_list curr_label, next_label;
curr_label = labelList;
while( curr_label ) {
next_label = curr_label->next;
doEmitLabel( curr_label );
MemFree( curr_label );
curr_label = next_label;
}
}
extern void ObjEmitData( void *buffer, int size, bool align ) {
//*************************************************************
// Aligns to proper address, emits all pending labels, then emits the data
if( align ) {
(void)ObjAlign( CurrAlignment );
}
ObjFlushLabels();
doEmitData( buffer, size );
}
extern void ObjDirectEmitData( void *buffer, int size ) {
//*******************************************************
doEmitData( buffer, size );
}
extern void ObjNopPad( uint_8 count ) {
//*************************************
// Emits count no-ops
uint_32 nop_opcode = INS_NOP;
while( count-- > 0 ) {
doEmitData( (char *)&nop_opcode, sizeof( nop_opcode ) );
}
}
extern void ObjNullPad( uint_8 count ) {
//**************************************
// Emits count bytes of zeros
char byte = 0;
while( count-- > 0 ) {
doEmitData( &byte, sizeof( byte ) );
}
}
extern owl_offset ObjAlign( uint_8 alignment ) {
//**********************************************
// Aligns the offset to 2^alignment boundary. Returns the offset for
// convenience.
owl_offset offset;
offset = tellOffset();
if( alignment == 0 ) return( offset ); // alignment disabled
alignment = 1 << alignment;
alignment = ( alignment - ( offset % alignment ) ) % alignment;
if( alignment == 0 ) return( offset );
ObjNopPad( alignment / 4 );
ObjNullPad( alignment % 4 );
assert( offset + alignment == tellOffset() );
return( offset + alignment );
}
/*
extern owl_offset ObjTellOffset( void ) {
//***************************************
return( tellOffset() );
}
*/
extern void ObjDirectEmitReloc( owl_offset offset, void *target, owl_reloc_type type, bool named_sym ) {
//******************************************************************************************************
doEmitReloc( offset, target, type, named_sym );
}
extern void ObjEmitReloc( void *target, owl_reloc_type type, bool align, bool named_sym ) {
//*****************************************************************************************
// Should be called before emitting the data that has the reloc.
// (named_sym == TRUE) iff the target is a named label
owl_offset offset;
if( align ) { // If data is aligned, we should also align this reloc offset!
offset = ObjAlign( CurrAlignment );
} else {
offset = tellOffset();
}
ObjFlushLabels();
#ifdef AS_PPC // ?
doEmitReloc( offset, target, type, named_sym );
#else
{
sym_reloc reloc;
bool match_high;
owl_offset offset_hi, offset_lo;
sym_handle (*lookup_func)( void * );
if( type != OWL_RELOC_HALF_HI && type != OWL_RELOC_HALF_LO ) {
doEmitReloc( offset, target, type, named_sym );
} else {
lookup_func = named_sym ?
(sym_handle (*)( void * ))SymLookup :
(sym_handle (*)( void * ))AsNumLabelSymLookup;
match_high = ( type == OWL_RELOC_HALF_LO ); // hi match lo etc.
reloc = SymMatchReloc( match_high, lookup_func( target ), NULL );
if( reloc ) { // got a match
if( match_high ) {
offset_hi = reloc->location.offset;
offset_lo = offset;
} else {
offset_hi = offset;
offset_lo = reloc->location.offset;
}
doEmitReloc( offset_hi, target, OWL_RELOC_HALF_HI, named_sym );
doEmitReloc( offset_lo, target, OWL_RELOC_PAIR, named_sym );
doEmitReloc( offset_lo, target, OWL_RELOC_HALF_LO, named_sym );
SymDestroyReloc( lookup_func( target ), reloc );
} else { // no match; stack it up with the (aligned) offset!
SymStackReloc( !match_high, lookup_func( target ), NULL, offset, named_sym );
}
}
}
#endif
}
extern void ObjRelocsFini( void ) {
//*********************************
// After all lines have been parsed, we need to check whether there're any
// unmatched relocs still hanging around. If there're unmatched h^relocs,
// we issue an error. If there're unmatched l^relocs, we should be able
// to emit them.
sym_reloc reloc;
sym_handle sym;
int_32 numlabel_ref;
reloc = SymGetReloc( TRUE, &sym );
while( reloc != NULL ) {
if( reloc->named ) {
Error( UNMATCHED_HIGH_RELOC, SymName( sym ) );
} else {
Error( UNMATCHED_HIGH_RELOC, "<numeric reference>" );
}
SymDestroyReloc( sym, reloc );
reloc = SymGetReloc( TRUE, &sym );
}
reloc = SymGetReloc( FALSE, &sym );
while( reloc != NULL ) {
if( reloc->named ) {
doEmitReloc( reloc->location.offset,
SymName( sym ), OWL_RELOC_HALF_LO, TRUE );
} else {
numlabel_ref = AsNumLabelGetNum( SymName( sym ) );
doEmitReloc( reloc->location.offset,
&numlabel_ref, OWL_RELOC_HALF_LO, FALSE );
}
SymDestroyReloc( sym, reloc );
reloc = SymGetReloc( FALSE, &sym );
}
#ifndef NDEBUG
(void)SymRelocIsClean( TRUE );
#endif
AsNumLabelFini(); // resolve all numeric label relocs
resolveRelativeRelocs();
}
extern void ObjFini( void ) {
//********************
ObjFlushLabels(); // In case there're still pending labels
ObjRelocsFini();
AsmCodeAddress = AsmLastAddress; // points to end of code
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?