i86obj.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,113 行 · 第 1/5 页

C
2,113
字号
        attr = FEAttr( sym );
        if( ( attr & FE_PROC ) == 0 ) {
            if( attr & FE_DLLEXPORT ) {
                OutDLLExport( 0, sym );
            }
        }
        if( attr & FE_COMMON ) {
            ComdatData( lbl, sym );
        } else {
            if( CurrSeg->comdat_label != NULL )
                NormalData();
            if( UseImportForm( attr ) ) {
                OutExport( sym );
            }
        }
        for( curr = CurrSeg->virt_func_refs; curr != NULL; curr = next ) {
            cookie = curr->cookie;
            while( cookie != NULL ) {
                OutVirtFuncRef( FEAuxInfo( cookie, VIRT_FUNC_SYM ) );
                cookie = FEAuxInfo( cookie, VIRT_FUNC_NEXT_REFERENCE );
            }
            next = curr->next;
            _Free( curr, sizeof( virt_func_ref_list ) );
        }
        CurrSeg->virt_func_refs = NULL;
    } else if( CurrSeg->prefix_comdat_state != PCS_OFF ) {
        /*
            We have data coming out before the COMDAT symbol (select table
            before a common procedure). Gen a 'magical' comdat name to
            deal with it.
        */
        if( CurrSeg->prefix_comdat_state == PCS_NEED ) {
            ComdatData( lbl, NULL );
            CurrSeg->prefix_comdat_state = PCS_ACTIVE;
        }
        TellCommonLabel( lbl, CurrSeg->comdat_prefix_import );
    }
    i = SegInfo->used;
    lc = CurrSeg->location;
    TellAddress( lbl, lc );
    while( --i >= 0 ) {
        obj = _ARRAYOF( SegInfo, index_rec )[ i ].obj;
        if( obj != NULL ) { /* twas flushed and not redefined*/
            owner = &obj->patches;
            for(;;) {
                curr_pat = *owner;
                if( curr_pat == NULL )
                    break;
                if( curr_pat->lbl == lbl ) {
                    patptr = &_ARRAYOF( &obj->data, byte )[  curr_pat->pat.where  ];
                    if( curr_pat->pat.attr & ADD_PATCH ) {
                        if( curr_pat->pat.attr & LONG_PATCH ) {
                            _TargetAddL( *(unsigned_32 *)patptr, lc );
                        } else if( curr_pat->pat.attr & WORD_PATCH ) {
                            _TargetAddW( *(unsigned_16 *)patptr, lc );
                        } else {
                            _TargetAddB( *(byte *)patptr, lc );
                        }
                    } else {
                        if( curr_pat->pat.attr & LONG_PATCH ) {
                            *(unsigned_32 *)patptr = _TargetLongInt( lc );
                        } else if( curr_pat->pat.attr & WORD_PATCH ) {
                            *(unsigned_16 *)patptr = _TargetInt( lc );
                        } else {
                            *(byte *)patptr = _TargetInt( lc );
                        }
                    }
                    *owner = curr_pat->link;
                    _Free( curr_pat, sizeof( temp_patch ) );
                } else {
                     owner = &curr_pat->link;
                }
            }
        }
    }
    ctl = AskLblPatch( lbl );
    i = ctl->used;
    pat = ctl->array;
    while( i > 0 ) {
        DoPatch( pat, lc );
        pat++;
        i--;
    }
    KillArray( ctl );
    TellDonePatch( lbl );
}


extern  void    AbsPatch( abspatch *patch, offset lc ) {
/******************************************************/

    if( patch->flags & AP_HAVE_OFFSET ) {
        DoPatch( &patch->pat, lc );
        FreeAbsPatch( patch );
    } else {
        patch->value = lc;
        patch->flags |= AP_HAVE_VALUE;
    }
}


static  void    SetAbsPatches( void ) {
/*******************************/

    abspatch    *patch;
    object      *obj;

    obj = CurrSeg->obj;
    patch = AbsPatches;
    while( patch != NULL ) {
        if( patch->pat.ref == INVALID && patch->obj == obj ) {
            patch->pat.ref = AskObjHandle();
            patch->flags |= AP_HAVE_OFFSET;
        }
        patch = patch->link;
    }
}


static  void    SetPatches( void ) {
/****************************/

    temp_patch          *curr_pat;
    temp_patch          *junk;
    array_control       *ctl;
    patch               *pat;

    curr_pat = CurrSeg->obj->patches;
    while( curr_pat != NULL ) {
        ctl = AskLblPatch( curr_pat->lbl );
        NeedMore( ctl, 1 );
        pat = &_ARRAYOF( ctl, patch )[  ctl->used++  ];
        pat->ref = AskObjHandle();
        pat->where = curr_pat->pat.where;
        pat->attr = curr_pat->pat.attr;
        junk = curr_pat;
        curr_pat = curr_pat->link;
        _Free( junk, sizeof( temp_patch ) );
    }
}


extern  array_control   *InitPatch( void ) {
/************************************/

#define MODEST_PAT 10
#define INCREMENT_PAT 10

    return( InitArray( sizeof( patch ),  MODEST_PAT, INCREMENT_PAT ) );
}


static  void    InitFPPatches( void ) {
/*******************************/

    int i;

    i = FPP_NUMBER_OF_TYPES;
    while( --i >= 0 ) {
        FPPatchImp[  i  ] = NOT_IMPORTED;
    }
}

#define MODEST_IMP BUFFSIZE
#define INCREMENT_IMP 50

extern  void    OutFPPatch( fp_patches i ) {
/******************************************/

    import_handle       idx;

    idx = FPPatchImp[  i  ];
    if( idx == NOT_IMPORTED ) {
        idx = ImportHdl++;
        FPPatchImp[  i  ] = idx;
        if( Imports == NULL ) {
            Imports = InitArray( sizeof( byte ), MODEST_IMP, INCREMENT_IMP );
        }
        if( GenStaticImports ) {
            EjectImports();
            GenStaticImports = FALSE;
        }
        OutName( FPPatchName[ i ], Imports );
        OutIdx( 0, Imports );           /* type index*/
        if( FPPatchAltName[ i ] != NULL ) {
            ImportHdl++;
            OutName( FPPatchAltName[ i ], Imports );
            OutIdx( 0, Imports );           /* type index*/
        }
    }
    CheckLEDataSize( 2*sizeof( offset ), TRUE );
    DoFix( idx, FALSE, BASE_IMP, F_OFFSET, 0 );
    if( FPPatchAltName[ i ] != NULL ) {
        IncLocation( sizeof( byte ) );
        DoFix( idx+1, FALSE, BASE_IMP, F_OFFSET, 0 );
        DecLocation( sizeof( byte ) );
    }
}


extern  void    OutPatch( label_handle lbl, patch_attr attr ) {
/*************************************************************/

    temp_patch  *pat;
    object      *obj;

     /* careful, might be patching offset of seg:off*/
    CheckLEDataSize( 3*sizeof( offset ), TRUE );
    _Alloc( pat, sizeof( temp_patch ));
    obj = CurrSeg->obj;
    pat->link = obj->patches;
    pat->lbl = lbl;
    pat->pat.ref = INVALID;
    pat->pat.where = CurrSeg->location - obj->start + CurrSeg->data_prefix_size;
    pat->pat.attr = attr;
    obj->patches = pat;
}

extern  abspatch        *NewAbsPatch( void ) {
/**************************************/

    abspatch    *new;

    _Alloc( new, sizeof( *new ) );
    memset( new, 0, sizeof( *new ) );
    new->link = AbsPatches;
    AbsPatches = new;
    return( new );
}


extern  void    OutAbsPatch( abspatch *patch, patch_attr attr ) {
/***************************************************************/

    object      *obj;
    long_offset value;

    CheckLEDataSize( 2*sizeof( offset ), TRUE );
    if( patch->flags & AP_HAVE_VALUE ) {
        value = patch->value;
        FreeAbsPatch( patch );
    } else {
        obj = CurrSeg->obj;
        patch->obj = obj;
        patch->pat.ref = INVALID;
        patch->pat.where = CurrSeg->location - obj->start + CurrSeg->data_prefix_size;
        patch->pat.attr = attr;
        value = 0;
    }
    if( attr & LONG_PATCH ) {
        OutDataLong( value );
    } else if( attr & WORD_PATCH ) {
        OutDataInt( value );
    } else {
        OutDataByte( (byte)value );
    }
}


static void DumpImportResolve( sym_handle sym, import_handle idx ) {
/******************************************************************/

    sym_handle          def_resolve;
    import_handle       def_idx;
    array_control       *cmt;
    unsigned            nidx;
    pointer             cond;
    int                 type;

    def_resolve = FEAuxInfo( sym, DEFAULT_IMPORT_RESOLVE );
    if( def_resolve != NULL && def_resolve != sym ) {
        def_idx = GenImport( def_resolve, NORMAL );
        EjectImports();
        cmt = InitArray( sizeof( byte ), MODEST_HDR, INCREMENT_HDR );
        type = (int) FEAuxInfo( sym, IMPORT_TYPE );
        switch( type ) {
        case IMPORT_IS_LAZY:
            NeedMore( cmt, sizeof( unsigned_16 ) );
            _ARRAY( cmt, unsigned_16 ) = _TargetInt( LAZY_EXTRN_COMMENT );
            cmt->used += sizeof( unsigned_16 );
            OutIdx( idx, cmt );
            OutIdx( def_idx, cmt );
            break;
        case IMPORT_IS_WEAK:
            NeedMore( cmt, sizeof( unsigned_16 ) );
            _ARRAY( cmt, unsigned_16 ) = _TargetInt( WEAK_EXTRN_COMMENT );
            cmt->used += sizeof( unsigned_16 );
            OutIdx( idx, cmt );
            OutIdx( def_idx, cmt );
            break;
        case IMPORT_IS_CONDITIONAL_PURE:
            NeedMore( cmt, sizeof( unsigned_16 ) );
            _ARRAY( cmt, unsigned_16 ) = _TargetInt( WEAK_EXTRN_COMMENT );
            cmt->used += sizeof( unsigned_16 );
            OutIdx( idx, cmt );
            OutIdx( def_idx, cmt );
            PutObjRec( CMD_COMENT, cmt->array, cmt->used );
            cmt->used = 0;
            /* fall through */
        case IMPORT_IS_CONDITIONAL:
            NeedMore( cmt, sizeof( unsigned_16 ) );
            _ARRAY( cmt, unsigned_16 ) = _TargetInt( LINKER_COMMENT );
            cmt->used += sizeof( unsigned_16 );
            NeedMore( cmt, sizeof( byte ) );
            if( type == IMPORT_IS_CONDITIONAL ) {
                _ARRAY( cmt, byte ) = LDIR_VF_TABLE_DEF;
            } else {
                _ARRAY( cmt, byte ) = LDIR_VF_PURE_DEF;
            }
            cmt->used += sizeof( byte );
            OutIdx( idx, cmt );
            OutIdx( def_idx, cmt );
            cond = FEAuxInfo( sym, CONDITIONAL_IMPORT );
            while( cond != NULL ) {
                sym = FEAuxInfo( cond, CONDITIONAL_SYMBOL );
                DoOutObjectName( sym, GetSymLName, &nidx, NORMAL );
                OutIdx( nidx, cmt );
                cond = FEAuxInfo( cond, NEXT_CONDITIONAL );
            }
            FlushNames();
            break;
        }
        PutObjRec( CMD_COMENT, cmt->array, cmt->used );
        KillArray( cmt );
    }
}


static  import_handle   GenImport( sym_handle sym, import_type kind ) {
/**********************************************************************/

    import_handle       idx;
    fe_attr             attr;

    idx = AskImportHandle( sym );
    if( idx == NOT_IMPORTED || kind == SPECIAL ) {
        idx = ImportHdl++;
        if( Imports == NULL ) {
            Imports = InitArray( sizeof( byte ), MODEST_IMP, INCREMENT_IMP );
        }
        attr = FEAttr( sym );
        CheckImportSwitch( !( attr & FE_GLOBAL) );
        if( kind != SPECIAL )
            TellImportHandle( sym, idx );
        if( kind == NORMAL ) {
             if( (attr & FE_DLLIMPORT) ) {
                 kind = DLLIMPORT;
             } else if( _IsModel( POSITION_INDEPENDANT ) ) {
                 if( ( attr & FE_THREAD_DATA ) != 0 ) {
                     kind = PIC_RW;
                 }
             }
        }
        DoOutObjectName( sym, OutName, Imports, kind );
        OutIdx( 0, Imports );           /* type index*/
        if( kind != SPECIAL ) {
            DumpImportResolve( sym, idx );
        }
    }
    return( idx );
}


static  void    DoFix( int idx, bool rel, base_type base,
                       fix_class class, int sidx ) {
/**************************************************/

    fixup       *cursor;
    int         where;
    object      *obj;
    index_rec   *rec;
    byte        b;
    fix_class   class_flags;

    b = rel ? LOCAT_REL : LOCAT_ABS;
    if( (class & F_MASK) == F_PTR && CurrSeg->data_in_code ) {
        CurrSeg->data_ptr_in_code = TRUE;
    }
    class_flags = (class & ~F_MASK);
    class &= F_MASK;
#if  _TARGET & _TARG_80386
    if( class_flags & F_FAR16 ) {
        /* want a 16:16 fixup for a __far16 call */
        class = F_PTR;
    } else if( _IsTargetModel( EZ_OMF ) ) {
        switch( class ) {
        case F_OFFSET:
        case F_LDR_OFFSET:
            class = F_PHAR_OFFSET;
            break;
        case F_PTR:
            class = F_PHAR_PTR;
            break;
        default:
            break;
        }
    } else {
        switch( class ) {
        case F_OFFSET:
            class = F_MS_OFFSET_32;
            break;
        case F_LDR_OFFSET:
            class = F_MS_LDR_OFFSET_32;
            break;
        case F_PTR:
            class = F_MS_PTR;
            break;
        default:
            break;
        }
    }
#endif
    obj = CurrSeg->obj;
    NeedMore( &obj->fixes, sizeof( fixup ) );
    cursor = &_ARRAY( &obj->fixes, fixup );
    where = CurrSeg->location - obj->start;
    cursor->locatof = b + ( class << S_LOCAT_LOC ) + ( where >> 8 );
    cursor->fset = where;
    obj->fixes.used += sizeof( fixup );
    if( base != BASE_IMP ) {
        rec = AskIndexRec( s

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?