rscobj.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,178 行 · 第 1/3 页
C
1,178 行
case OWL_SECTION_COMDAT_DATA:
case OWL_SECTION_COMDAT_BSS:
old = SetOP( id );
DFSegRange();
SetOP( old );
break;
}
}
OWLSectionFini( sect->owl_handle );
}
extern bool NeedBaseSet( void )
/*********************************/
{
bool need;
if( currSection->is_start ){
need = TRUE;
currSection->is_start = FALSE;
}else{
need = FALSE;
}
return( need );
}
extern offset AskLocation( void )
/*********************************/
{
assert( currSection != NULL );
return( OWLTellOffset( currSection->owl_handle ) );
}
extern long_offset AskBigLocation( void )
/*****************************************/
{
assert( currSection != NULL );
return( OWLTellOffset( currSection->owl_handle ) );
}
extern offset AskMaxSize( void )
/********************************/
{
assert( currSection != NULL );
return( OWLTellSize( currSection->owl_handle ) );
}
extern long_offset AskBigMaxSize( void )
/****************************************/
{
assert( currSection != NULL );
return( OWLTellSize( currSection->owl_handle ) );
}
extern void SetLocation( offset loc )
/***************************************/
{
OWLSetLocation( currSection->owl_handle, loc );
}
extern void SetBigLocation( long_offset loc )
/***********************************************/
{
OWLSetLocation( currSection->owl_handle, loc );
}
static void DumpImportResolve( code_lbl *label )
/**********************************************/
{
sym_handle def_resolve;
sym_handle sym;
pointer cond;
int type;
bck_info *bck;
if( AskIfRTLabel( label ) ) return;
sym = AskForLblSym( label );
if( sym != NULL ){
def_resolve = FEAuxInfo( sym, DEFAULT_IMPORT_RESOLVE );
if( def_resolve != NULL && def_resolve != sym ) {
bck = FEBack( def_resolve);
type = (int) FEAuxInfo( sym, IMPORT_TYPE );
switch( type ) {
case IMPORT_IS_LAZY:
OWLWeakExt( owlFile, labelOwlSym( label ), labelOwlSym( bck->lbl ), TRUE );
break;
case IMPORT_IS_WEAK:
OWLWeakExt( owlFile, labelOwlSym( label ), labelOwlSym( bck->lbl ), FALSE );
break;
case IMPORT_IS_CONDITIONAL_PURE:
/* fall through */
case IMPORT_IS_CONDITIONAL:
cond = FEAuxInfo( sym, CONDITIONAL_IMPORT );
while( cond != NULL ) {
sym = FEAuxInfo( cond, CONDITIONAL_SYMBOL );
cond = FEAuxInfo( cond, NEXT_CONDITIONAL );
}
assert( 0 ); // not implemented
break;
}
}
}
}
extern void OutReloc( code_lbl *label, owl_reloc_type tipe, unsigned offset )
/***************************************************************************************/
{
DumpImportResolve( label );
offset = offset;
OWLEmitReloc( currSection->owl_handle,
OWLTellOffset( currSection->owl_handle ),
labelOwlSym( label ), tipe );
}
extern void OutSegReloc( code_lbl *label, seg_id seg )
/****************************************************************/
{
section_def *sect;
label = label;
sect = FindSection( seg );
OWLEmitMetaReloc( currSection->owl_handle,
OWLTellOffset( currSection->owl_handle ),
sect->owl_handle, OWL_RELOC_SECTION_INDEX );
}
extern owl_sym_linkage labelLinkage( label_handle label )
/********************************************************/
{
sym_handle sym;
owl_sym_linkage linkage;
fe_attr attr;
linkage = OWL_SYM_STATIC;
sym = AskForLblSym( label );
if( sym != NULL ) {
attr = FEAttr( sym );
if( attr & FE_GLOBAL ) {
linkage = OWL_SYM_GLOBAL;
}
}
return( linkage );
}
extern void OutLabel( label_handle label )
/****************************************************/
{
sym_handle sym;
fe_attr attr;
owl_sym_type tipe;
assert( currSection != NULL );
tipe = OWL_TYPE_OBJECT;
sym = AskForLblSym( label );
if( sym != NULL ) {
attr = FEAttr( sym );
if( attr & FE_PROC ) {
label = GetWeirdPPCDotDotLabel( (code_lbl *)label );
tipe = OWL_TYPE_FUNCTION;
}
}
OWLEmitLabel( currSection->owl_handle, labelOwlSym( label ), tipe, labelLinkage( label ) );
TellAddress( label, OWLTellLocation( currSection->owl_handle ) );
if( sym != NULL ) {
if( SymIsExported( sym ) ) {
OWLEmitExport( owlFile, labelOwlSym( label ) );
}
}
}
static long const Zero = 0;
#if _TARGET & _TARG_PPC
extern void OutTOCRec( code_lbl *label )
/**************************************/
{
code_lbl *dot_lbl;
code_lbl *toc_lbl;
if( owlTocSect == NULL ) {
owlTocSect = OWLSectionInit( owlFile, ".reldata", OWL_SEC_ATTR_DATA|OWL_SEC_ATTR_PERM_READ|OWL_SEC_ATTR_PERM_WRITE, 8 );
}
dot_lbl = GetWeirdPPCDotDotLabel( label );
toc_lbl = RTLabel( RT_TOC_NAME );
OWLEmitLabel( owlTocSect, labelOwlSym( label ), OWL_TYPE_OBJECT, labelLinkage( label ) );
OWLEmitReloc( owlTocSect, OWLTellOffset( owlTocSect ), labelOwlSym( dot_lbl ), OWL_RELOC_WORD );
OWLEmitData( owlTocSect, (char *)&Zero, 4 );
OWLEmitReloc( owlTocSect, OWLTellOffset( owlTocSect ), labelOwlSym( toc_lbl ), OWL_RELOC_WORD );
OWLEmitData( owlTocSect, (char *)&Zero, 4 );
}
#endif
static owl_section_handle getPData( code_lbl *label )
/***************************************************/
{
sym_handle sym;
owl_section_handle pdata;
sym = AskForLblSym( label );
if( sym != NULL ) {
if( FEAttr( sym ) & FE_COMMON ) {
pdata = OWLSectionInit( owlFile, ".pdata", OWL_SECTION_COMDAT_PDATA, 4 );
OWLComdatDep( pdata, currSection->owl_handle );
return( pdata );
}
}
if( globalPdata == NULL ) {
globalPdata = OWLSectionInit( owlFile, ".pdata", OWL_SECTION_PDATA, 4 );
}
return( globalPdata );
}
extern void OutPDataRec( code_lbl *label, offset proc_size, offset pro_size )
/***************************************************************************/
{
owl_section_handle owl_pdata;
sym_handle sym;
sym_handle curr;
code_lbl *lbl;
owl_pdata = getPData( label );
label = GetWeirdPPCDotDotLabel( label );
sym = AskForLblSym( label );
OWLEmitReloc( owl_pdata, OWLTellOffset( owl_pdata ), labelOwlSym( label ), OWL_RELOC_WORD );
OWLEmitData( owl_pdata, (char *)&Zero, 4 );
OWLEmitReloc( owl_pdata,OWLTellOffset( owl_pdata ), labelOwlSym( label ), OWL_RELOC_WORD );
OWLEmitData( owl_pdata, (char *)&proc_size, 4 );
if( sym != NULL ) { // put out exception handler stuff
curr = FEAuxInfo( sym, EXCEPTION_HANDLER );
if( curr != NULL ) {
lbl = AskForSymLabel( curr, CG_FE );
OWLEmitReloc( owl_pdata, OWLTellOffset( owl_pdata ), labelOwlSym( lbl ), OWL_RELOC_WORD );
} else if( _IsTargetModel( EXCEPT_FILTER_USED ) ) {
lbl = RTLabel( RT_EXCEPT_RTN );
OWLEmitReloc( owl_pdata, OWLTellOffset( owl_pdata ), labelOwlSym( lbl ), OWL_RELOC_WORD );
}
OWLEmitData( owl_pdata, (char *)&Zero, 4 );
curr = FEAuxInfo( sym, EXCEPTION_DATA );
if( curr != NULL ) {
lbl = AskForSymLabel( curr, CG_FE );
OWLEmitReloc( owl_pdata, OWLTellOffset( owl_pdata ), labelOwlSym( lbl ), OWL_RELOC_WORD );
}
OWLEmitData( owl_pdata, (char *)&Zero, 4 );
} else {
OWLEmitData( owl_pdata, (char *)&Zero, 4 );
OWLEmitData( owl_pdata, (char *)&Zero, 4 );
}
OWLEmitReloc( owl_pdata,OWLTellOffset( owl_pdata ), labelOwlSym( label ), OWL_RELOC_WORD );
OWLEmitData( owl_pdata, (char *)&pro_size, 4 );
}
extern void *InitPatch( void )
/****************************************/
{
return( NULL );
}
extern void AbsPatch( void * patch, offset lc )
/*************************************************/
{
patch = patch;
lc = lc;
}
extern void DoEmptyQueue( void )
/******************************/
{
EmptyQueue();
TellUnreachLabels();
}
extern void TellObjNewProc( sym_handle proc )
/***********************************************/
{
segment_id proc_id;
segment_id old;
old = SetOP( codeSection );
proc_id = FESegID( proc );
if( codeSection != proc_id ) {
DoEmptyQueue();
codeSection = proc_id;
SetOP( codeSection );
currSection->is_start = TRUE;
}
if( FEAttr( proc ) & FE_COMMON ) {
if( _IsModel( DBG_CV ) ) { // set the $debug for comdat
CVDefSymComdat( currSection->owl_handle );
}
}else{
if( _IsModel( DBG_CV ) ) {
CVDefSymNormal(); // reset to normal $debug section
}
}
SetOP( old );
}
extern void IncLocation( offset by )
/**************************************/
{
/* This should only be used for bumping up our location in a BSS section */
OWLEmitData( currSection->owl_handle, NULL, by );
}
extern bool AskNameROM( name *n )
/***********************************/
{
n = n;
return( FALSE );
}
extern unsigned DepthAlign( unsigned depth )
/*******************************************/
{
depth = depth;
return( 4 );
}
extern bool CodeHasAbsPatch( oc_entry *code )
/***********************************************/
{
code = code;
return( FALSE ); // NYI
}
static bool relocBefore( void *_p1, void *_p2 )
/*************************************************/
{
byte_seq_reloc *p1 = _p1;
byte_seq_reloc *p2 = _p2;
if( p1->off == p2->off ) {
/*
* Only thing which can have multiple relocs to same address
* should be an OWL_RELOC_HI and OWL_RELOC_PAIR sequence and we
* want to make sure the HI comes first.
*/
return( p1->type < p2->type );
}
return( p1->off < p2->off );
}
extern void ObjEmitSeq( risc_byte_seq *code )
/***********************************************/
{
byte_seq_reloc *curr;
bck_info *back;
type_length loc;
unsigned i;
axp_ins *code_ptr;
axp_ins opcode;
pointer reloc_sym;
owl_reloc_type reloc_type;
assert( code->length % 4 == 0 );
curr = SortList( code->relocs, offsetof( byte_seq_reloc, next ), relocBefore );
code_ptr = (axp_ins *)&code->data[ 0 ];
for( i = 0; i < code->length; i += 4 ) {
opcode = *code_ptr++;
reloc_type = 0;
reloc_sym = NULL;
while( curr != NULL && curr->off == i ) {
back = (bck_info *)SymBack( curr->sym );
switch( curr->type ) {
case OWL_RELOC_FP_OFFSET:
loc = TempLocation( (name *)back );
if( loc > 32767 ) {
FEMessage( MSG_ERROR, "auto variable out of range for reference within inline assembly sequence" );
}
opcode |= _SignedImmed( loc );
break;
case OWL_RELOC_PAIR:
break;
default:
reloc_type = curr->type;
reloc_sym = back->lbl;
}
curr = curr->next;
}
EmitInsReloc( opcode, reloc_sym, reloc_type );
}
}
extern void DoAlignment( int align )
/**************************************/
{
// NYI
align = align;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?