i86obj.c

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

C
2,113
字号
                    PrivateIndexRW = GetNameIdx( "FAR_DATA", "", TRUE );
                }
                rec->cidx = PrivateIndexRW;
            }
            SegmentClass( rec );
            rec->base = SegmentIndex;
            rec->btype = BASE_SEG;
            DoASegDef( rec, use_16 );
        } else {
            if( seg->attr & THREAD_LOCAL ) {
                if( TLSGIndex == 0 ) {
                    OutIdx( _NIDX_TLS, tgroup_def );
                }
                OutGroup( rec->sidx, tgroup_def, &TLSGIndex );
                rec->base = TLSGIndex;
                rec->btype = BASE_GRP;
            } else if( NoDGroup || (seg->attr & NOGROUP) ) {
                rec->btype = BASE_SEG;
                rec->base = SegmentIndex;
            } else {
                OutGroup( rec->sidx, dgroup_def, &DGroupIndex );
                rec->base = DGroupIndex;
                rec->btype = BASE_GRP;
            }
            if( seg->attr & THREAD_LOCAL ) {
                rec->cidx = _NIDX_TLS;
            } else if( seg->attr & COMMON ) {
                rec->cidx = _NIDX_DATA;
            } else if( ( seg->attr & ( BACK | INIT ) ) == 0 ) {
                rec->cidx = _NIDX_BSS;
            } else {
                rec->cidx = _NIDX_DATA;
            }
            rec->nidx = GetNameIdx( DataGroup, seg->str, TRUE );
            SegmentClass( rec );
            DoASegDef( rec, use_16 );
        }
    }
    _Free( seg->str, Length( seg->str ) + 1 );
    _Free( seg, sizeof( segdef ) );
}


extern  bool    UseImportForm( fe_attr attr ) {
/*********************************************/

    if( attr & (FE_GLOBAL|FE_IMPORT) )
        return( TRUE );
    if( attr & FE_INTERNAL )
        return( FALSE );
    return( TRUE );
}



extern  bool    AskSegNear( segment_id id ) {
/*******************************************/

    index_rec   *rec;

    if( id < 0 )
        return( FALSE );
    rec = AskSegIndex( id );
    if( rec->btype != BASE_GRP )
        return( FALSE );
    if( rec->base > CodeGroupGIdx )
        return( TRUE );
    return( FALSE );
}


extern        bool    AskSegBlank( segment_id id ) {
/*******************************************/

    index_rec *rec;

    if( id < 0 )
        return( TRUE );
    rec = AskSegIndex( id );
    return( rec->cidx == _NIDX_BSS );
}


extern  bool    AskSegPrivate( segment_id id ) {
/**********************************************/

    index_rec   *rec;

    if( id < 0 )
        return( TRUE );
    rec = AskSegIndex( id );
    return( rec->private || rec->exec );
}


extern  bool    AskSegROM( segment_id id ) {
/******************************************/

    index_rec   *rec;

    if( id < 0 )
        return( FALSE );
    rec = AskSegIndex( id );
    return( rec->rom );
}


extern  seg_id  AskBackSeg( void ) {
/****************************/

    return( BackSeg );
}


extern  seg_id  AskCodeSeg( void ) {
/****************************/

    return( CodeSeg );
}


extern  bool    HaveCodeSeg( void ) {
/*****************************/

    return( CodeSeg != BACKSEGS );
}


extern  seg_id  AskAltCodeSeg( void ) {
/****************************/

    return( CodeSeg );
}

static  seg_id  Code16Seg;

extern  seg_id  AskCode16Seg( void )
/******************************/
{
    if( Code16Seg == 0 ) {
        Code16Seg = --BackSegIdx;
        DefSegment( Code16Seg, EXEC | GIVEN_NAME, "_TEXT16", 16, TRUE );
    }
    return( Code16Seg );
}


static  cmd_omf    PickOMF( cmd_omf cmd )
/***************************************/
{
#ifdef _OMF_32
    if( _IsntTargetModel( EZ_OMF ) )
        ++cmd;
#endif
    return( cmd );
}

extern  void    FlushOP( seg_id id ) {
/************************************/

    seg_id      old;
    index_rec   *rec;

    old = SetOP( id );
    if( id == CodeSeg ) {
        DoEmptyQueue();
    }
    if( _IsModel( DBG_DF ) ) {
        rec = CurrSeg;
        if( rec->exec || rec->cidx == _NIDX_DATA ||rec->cidx == _NIDX_BSS ) {
            if( rec->max_size != 0 ) {
                DFSegRange();
            }
        }
    }
    FiniTarg();
    CurrSeg->obj = NULL;
    SetOP( old );
}

static  void    DoASegDef( index_rec *rec, bool use_16 ) {
/**********************************************************/

#define MODEST_OBJ BUFFSIZE
#define INCREMENT_OBJ 256
#define NOMINAL_FIX 20
#define INCREMENT_FIX 50
#define MODEST_EXP BUFFSIZE
#define INCREMENT_EXP 50

    object      *obj;

    use_16 = use_16;
    _Alloc( obj, sizeof( object ) );
    rec->obj = obj;
    obj->index = rec->sidx;
    obj->start = rec->location;
    obj->patches = NULL;
    obj->gen_static_exports = FALSE;
    obj->pending_line_number = 0;
    Out = &obj->data;
    FillArray( &obj->data, sizeof( byte ), MODEST_OBJ, INCREMENT_OBJ );
    FillArray( &obj->fixes, sizeof( byte ), NOMINAL_FIX, INCREMENT_FIX );
    if( rec->exec ) { /* try to bag all the memory we'll need now*/
        obj->exports = InitArray( sizeof( byte ), MODEST_EXP, INCREMENT_EXP );
    } else {
        obj->exports = NULL;
    }
    obj->lines = NULL;
    obj->line_info = FALSE;
    Out = &obj->data;
    OutBuff = Out->array;
    OutByte( rec->attr );
#ifdef _OMF_32
    OutOffset( 0 );    /* segment size (for now)*/
#else  //SEG32DBG dwarf, codview
    if( rec->attr & SEG_USE_32 ) {
        OutLongOffset( 0 ); /* segment size (for now)*/
    } else {
        OutOffset( 0 );    /* segment size (for now)*/
    }
#endif
    OutIdx( rec->nidx, Out );               /* segment name index*/
    OutIdx( rec->cidx, Out );               /* class name index*/
    OutIdx( _NIDX_NULL, Out );              /* overlay name index*/
#ifdef _OMF_32
    if( _IsTargetModel( EZ_OMF ) ) {
        if( _IsntTargetModel( USE_32 ) || use_16 ) {
            OutByte( 2 ); /* to indicate USE16 EXECUTE/READ */
        }
    }
#endif
    FlushNames();
    obj->segfix = AskObjHandle();
    if( ++SegsDefd > 32000 ) {
        FEMessage( MSG_FATAL, "too many segments" );
    }
#ifdef _OMF_32
    PutObjRec( PickOMF( CMD_SEGDEF ), Out->array, Out->used );
#else //SEG32DBG dwarf, codview
    if(( rec->attr & SEG_USE_32 ) && ( _IsntTargetModel( EZ_OMF ))) {
        PutObjRec( CMD_SEGDEF32, Out->array, Out->used );
    } else {
        PutObjRec( CMD_SEGDEF, Out->array, Out->used );
    }
#endif
    if( rec->exec ) {
        Out->used = 0;
        OutInt( LINKER_COMMENT );
        OutByte( LDIR_OPT_FAR_CALLS );
        OutIdx( rec->sidx, Out );
        PutObjRec( CMD_COMENT, Out->array, Out->used );
    }
    Out->used = 0;
    rec->location = 0;
}


static  void    OutGroup( int sidx, array_control *group_def, int *index_p ) {
/***************************************************************************/

    if( *index_p == 0 ) {
        *index_p = ++GroupIndex;
    }
    NeedMore( group_def, 1 );
    _ARRAYOF( group_def, byte )[ group_def->used++ ] = GRP_SEGIDX;
    OutIdx( sidx, group_def );
}

static  void    OutCGroup( int sidx ) {
/*************************************/

    char        out[ 4 ];
    int         i;

    out[ 0 ] = CodeGroupNIdx;
    out[ 1 ] = GRP_SEGIDX;
    i = 1;
    if( sidx >= 128 ) {
        out[ ++i ] = (sidx >> 8) | 0x80;
    }
    out[ ++i ] = sidx;
    FlushNames();
    PutObjRec( CMD_GRPDEF, out, ++i );
}

static  index_rec       *AskIndexRec( unsigned_16 sidx ) {
/********************************************************/

    index_rec   *rec;
    int         i;

    i = 0;
    rec = SegInfo->array;
    while( ++i <= SegInfo->used ) {
        if( rec->sidx == sidx )
            break;
        rec++;
    }
    return( rec );
}

static void FiniWVTypes( void )
/*****************************/
{
    seg_id       old;
    long_offset  curr;
    struct dbg_seg_info *info;

    WVTypesEof();
    info = &DbgSegs[1];
    old = SetOP( *info->id );
    curr = AskLocation();
    curr += DbgTypeSize;
    *info->id = DbgSegDef( info->seg_name, info->class_name,
                               SEG_COMB_PRIVATE  );
    SetOP( *info->id );
    WVDmpCueInfo( curr );
    SetOP( old );
}

static void DoSegARange( offset *codesize, index_rec *rec )
/*********************************************************/
{
    seg_id  old;

    if( rec->exec || rec->cidx == _NIDX_DATA ||rec->cidx == _NIDX_BSS ) {
        if( rec->max_size != 0 ) {
            old = SetOP( rec->seg );
            if( CurrSeg->comdat_symbol != NULL ) {
                DFSymRange( rec->comdat_symbol, rec->comdat_size );
            }
            NormalData();
            DFSegRange();
            SetOP( old );
        }
        if( rec->exec ) {
            *codesize += rec->max_size + rec->total_comdat_size;
        }
    }
}

extern  void    ObjFini( void )
/*****************************/
{

    index_rec   *rec;
    int         i;
    pointer     auto_import;
    char        *lib;

    if( _IsModel( DBG_DF ) ) {
        if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
            offset  codesize;

            codesize = 0;
            i = 0;
            rec = SegInfo->array;
            while( ++i <= SegInfo->used ) {
                if( rec->obj != NULL ) {
                    DoSegARange( &codesize, rec );
                }
                rec++;
            }
            DFObjFiniDbgInfo( codesize );
#if 0 //save for Jimr
        } else if( _IsModel( NUMBERS ) ) {
            DFObjLineFini( );
#endif
        }
    } else if( _IsModel( DBG_CV ) ) {
        CVObjFiniDbgInfo();
    } else {
        if( _IsModel( DBG_TYPES ) ) {
            FiniWVTypes();
        }
    }
    i = 0;
    rec = SegInfo->array;
    while( ++i <= SegInfo->used ) {
        if( rec->obj != NULL ) {
            CurrSeg = rec;
            FiniTarg();
        }
        rec++;
    }
    if( Imports == NULL ) {
        Imports = InitArray( sizeof( byte ), 20, 20 );
    }
    if( Used87 ) {
        (void)FEAuxInfo( NULL, USED_8087 );
    }
    auto_import = NULL;
    for(;;) {
        auto_import = FEAuxInfo( auto_import, NEXT_IMPORT );
        if( auto_import == NULL )
            break;
        OutName( FEAuxInfo( auto_import, IMPORT_NAME ), Imports );
        OutIdx( 0, Imports );           /* type index*/
        if( Imports->used >= BUFFSIZE - TOLERANCE ) {
            PutObjRec( CMD_EXTDEF, Imports->array, Imports->used );
            Imports->used = 0;
        }
    }
    auto_import = NULL;
    for(;;) {
        auto_import = FEAuxInfo( auto_import, NEXT_IMPORT_S );
        if( auto_import == NULL )
            break;
        OutObjectName( FEAuxInfo( auto_import, IMPORT_NAME_S ), Imports );
        OutIdx( 0, Imports );           /* type index*/
        if( Imports->used >= BUFFSIZE - TOLERANCE ) {
            PutObjRec( CMD_EXTDEF, Imports->array, Imports->used );
            Imports->used = 0;
        }
    }
    if( Imports->used != 0 ) {
        PutObjRec( CMD_EXTDEF, Imports->array, Imports->used );
        Imports->used = 0;
    }
    lib = NULL;
    for( ;; ) {
        lib = FEAuxInfo( lib, NEXT_LIBRARY );

⌨️ 快捷键说明

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