obj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 495 行 · 第 1/2 页
C
495 行
section_type = OWLTellSectionType( CurrentSection );
if( section_type & OWL_SEC_ATTR_CODE ) {
type = OWL_TYPE_FUNCTION;
} else {
type = OWL_TYPE_OBJECT;
}
doStackNumericLabel( label_num, type, OWL_SYM_STATIC );
}
void ObjFlushLabels( void ) {
//***************************
label_list next_label;
while( labelList ) {
next_label = labelList->next;
if( labelList->is_numeric ) {
AsNumLabelEmit( labelList->label_num,
labelList->section,
OWLTellOffset( labelList->section ),
labelList->sym_type );
//labelList->sym_linkage );
_DBGMSG2( "Numeric label #%d emitted\n", labelList->label_num );
} else {
OWLEmitLabel( labelList->section, labelList->sym_hdl,
labelList->sym_type, labelList->sym_linkage );
_DBGMSG2( "Label '%s' emitted\n", labelList->sym_name );
}
MemFree( labelList );
labelList = next_label;
}
}
void ObjEmitData( owl_section_handle section, void *buffer, int size, bool align ) {
//**********************************************************************************
// Aligns to proper address, emits all pending labels, then emits the data
if( align ) {
(void)ObjAlign( section, CurrAlignment );
}
ObjFlushLabels();
OWLEmitData( section, buffer, size );
// printf( "real data emitted.\n" );
}
void ObjNopPad( owl_section_handle section, uint_8 count ) {
//**********************************************************
// Emits count no-ops
uint_32 nop_opcode = INS_NOP;
while( count-- > 0 ) {
OWLEmitData( section, (char *)&nop_opcode, sizeof( nop_opcode ) );
}
}
void ObjNullPad( owl_section_handle section, uint_8 count ) {
//***********************************************************
// Emits count bytes of zeros
char byte = 0;
while( count-- > 0 ) {
OWLEmitData( section, &byte, sizeof( byte ) );
}
}
owl_offset ObjAlign( owl_section_handle section, uint_8 alignment ) {
//*******************************************************************
// Aligns the offset to 2^alignment boundary. Returns the offset for
// convenience.
owl_offset offset;
offset = OWLTellOffset( section );
if( alignment == 0 ) return( offset ); // alignment disabled
alignment = 1 << alignment;
alignment = ( alignment - ( offset % alignment ) ) % alignment;
if( alignment == 0 ) return( offset );
if( OWLTellSectionType( section ) & OWL_SEC_ATTR_CODE ) {
ObjNopPad( section, alignment / 4 );
_DBGMSG2( "Align: %d nops emitted\n", alignment / 4 );
ObjNullPad( section, alignment % 4 );
_DBGMSG2( "Align: %d nulls emitted\n", alignment % 4 );
} else {
ObjNullPad( section, alignment );
_DBGMSG2( "Align: %d nulls emitted\n", alignment );
}
assert( offset + alignment == OWLTellOffset( section ) );
return( offset + alignment );
}
static void doEmitReloc( owl_section_handle section, owl_offset offset,
void *target, owl_reloc_type type,
bool named_sym ) {
//***************************************************************************************************************************
obj_section_handle ref_section;
sym_handle sym;
int_32 label_num;
if( named_sym ) {
if( ( ref_section = SectionLookup( target ) ) != NULL ) {
// We only handle backward reference to a section
// So we have to define a section before we can refer to it.
OWLEmitMetaReloc( section, offset, SectionOwlHandle( ref_section ), type );
} else {
sym = SymLookup( target );
assert( sym != NULL );
OWLEmitReloc( section, offset, SymObjHandle( sym ), type );
}
} else {
label_num = *(int_32 *)target;
AsNumLabelReloc( section, offset, label_num, type );
}
}
void ObjDirectEmitReloc( owl_section_handle section, owl_offset offset, void *target, owl_reloc_type type, bool named_sym ) {
//***************************************************************************************************************************
// Just emit the reloc. No alignment check, no l^-h^ reloc pairing etc.
doEmitReloc( section, offset, target, type, named_sym );
}
/*
owl_offset ObjTellOffset( owl_section_handle section ) {
//******************************************************
return( OWLTellOffset( section ) );
}
*/
void ObjEmitReloc( owl_section_handle section, 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( section, CurrAlignment );
} else {
offset = OWLTellOffset( section );
}
ObjFlushLabels();
#ifdef AS_PPC
doEmitReloc( section, 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( section, 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 ), section );
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( section, offset_hi, target, OWL_RELOC_HALF_HI, named_sym );
doEmitReloc( section, offset_lo, target, OWL_RELOC_PAIR, named_sym );
doEmitReloc( section, 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 ), section, offset, named_sym );
}
}
}
#endif
}
void ObjRelocsFini( void ) {
//**************************
// If the parse was successful, 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 {
// TODO: actually show the numref (eg. 2f)
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.section, reloc->location.offset,
SymName( sym ), OWL_RELOC_HALF_LO, TRUE );
} else {
numlabel_ref = AsNumLabelGetNum( SymName( sym ) );
doEmitReloc( reloc->location.section, reloc->location.offset,
&numlabel_ref, OWL_RELOC_HALF_LO, FALSE );
}
SymDestroyReloc( sym, reloc );
reloc = SymGetReloc( FALSE, &sym );
}
#ifndef NDEBUG
(void)SymRelocIsClean( TRUE );
#endif
ObjFlushLabels(); // In case there're still pending labels
AsNumLabelFini(); // resolve all numeric label relocs
}
void ObjFini( void ) {
//********************
ObjFlushLabels(); // In case there're still pending labels
OWLFileFini( OwlFile );
close( objFile );
fclose( ErrorFile );
if( ErrorsExceeding( 0 ) || ( _IsOption( WARNING_ERROR ) && WarningsExceeding( 0 ) ) ) {
remove( objName );
ExitStatus = EXIT_FAILURE;
} else if( !WarningsExceeding( 0 ) ) {
remove( errorFilename );
}
OWLFini( OwlHandle );
SectionFini();
}
extern sym_obj_hdl ObjSymbolInit( char *name ) {
//**********************************************
// Called by the symbol table routines to create and destroy the label name
// handles
return( OWLSymbolInit( OwlFile, name ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?