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 + -
显示快捷键?