i86obj.c

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

C
2,113
字号
    DataSize = 0;
    CurrFNo = 0;
    OpenObj();
    names = InitArray( sizeof( byte ), MODEST_HDR, INCREMENT_HDR );
    OutName( FEAuxInfo( NULL, SOURCE_NAME ), names );
    PutObjRec( CMD_THEADR, names->array, names->used );
#ifdef _OMF_32
    if( _IsTargetModel( EZ_OMF ) || _IsTargetModel( FLAT_MODEL ) ) {
        names->used = 0;
        NeedMore( names, sizeof( unsigned_16 ) );
        _ARRAY( names, unsigned_16 ) = _TargetInt( PHAR_LAP_COMMENT );
        names->used += sizeof( unsigned_16 );
        if( _IsntTargetModel( EZ_OMF ) ) {
            OutString( "OS220", names );
        } else {
            OutString( "80386", names );
        }
        PutObjRec( CMD_COMENT, names->array, names->used );
    }
#endif
#ifndef _OMF_32
    names->used = 0;
    NeedMore( names, sizeof( unsigned_16 ) );
    _ARRAY( names, unsigned_16 ) = _TargetInt( DEBUG_COMMENT );
    names->used += sizeof( unsigned_16 );
    PutObjRec( CMD_COMENT, names->array, names->used );
#endif

    names->used = 0;
    NeedMore( names, sizeof( unsigned_16 ) );
    _ARRAY( names, unsigned_16 ) = _TargetInt( MODEL_COMMENT );
    names->used += sizeof( unsigned_16 );
    OutModel( names );
    PutObjRec( CMD_COMENT, names->array, names->used );
    if( _IsTargetModel( FLAT_MODEL ) && _IsModel( DBG_DF ) ) {
        names->used = 0;
        NeedMore( names, sizeof( unsigned_16 ) );
        _ARRAY( names, unsigned_16 ) = _TargetInt( LINKER_COMMENT );
        names->used += sizeof( unsigned_16 );
        NeedMore( names, sizeof( char ) );
        _ARRAY( names, char ) = LDIR_FLAT_ADDRS;
        names->used++;
        PutObjRec( CMD_COMENT, names->array, names->used );
    }
    if( _IsntModel( DBG_DF | DBG_CV ) ) {
        names->used = 0;
        NeedMore( names, sizeof( unsigned_16 ) );
        _ARRAY( names, unsigned_16 ) = _TargetInt( LINKER_COMMENT );
        names->used += sizeof( unsigned_16 );
        NeedMore( names, sizeof( char ) );
        _ARRAY( names, char ) = LDIR_SOURCE_LANGUAGE;
        names->used++;
        NeedMore( names, sizeof( char ) );
        _ARRAY( names, char ) = DEBUG_MAJOR_VERSION;
        names->used++;
        NeedMore( names, sizeof( char ) );
        if( _IsModel( DBG_TYPES | DBG_LOCALS ) ) {
            _ARRAY( names, char ) = DEBUG_MINOR_VERSION;
        } else {
            _ARRAY( names, char ) = 0;
        }
        names->used++;
        OutString( FEAuxInfo( NULL, SOURCE_LANGUAGE ), names );
        PutObjRec( CMD_COMENT, names->array, names->used );
    }
    names->used = 0;
    depend = NULL;
    for( ;; ) {
        depend = FEAuxInfo( depend, NEXT_DEPENDENCY );
        if( depend == NULL )
            break;
        NeedMore( names, sizeof( unsigned_16 ) );
        _ARRAY( names, unsigned_16 ) = _TargetInt( DEPENDENCY_COMMENT );
        names->used += sizeof( unsigned_16 );
        NeedMore( names, sizeof( unsigned_32 ) );
        _ARRAY( names, unsigned_32 ) = _TargetLongInt(
                *(unsigned_32 *)FEAuxInfo( depend, DEPENDENCY_TIMESTAMP )
                          );
        names->used += sizeof( unsigned_32 );
        OutName( FEAuxInfo( depend, DEPENDENCY_NAME ), names );
        PutObjRec( CMD_COMENT, names->array, names->used );
        names->used = 0;
    }
    /* mark end of dependancy list */
    NeedMore( names, sizeof( unsigned_16 ) );
    _ARRAY( names, unsigned_16 ) = _TargetInt( DEPENDENCY_COMMENT );
    names->used += sizeof( unsigned_16 );
    PutObjRec( CMD_COMENT, names->array, names->used );
    names->used = 0;

    dgroup_def = InitArray( sizeof( byte ), MODEST_INFO, INCREMENT_INFO );
    tgroup_def = InitArray( sizeof( byte ), MODEST_INFO, INCREMENT_INFO );
    CurrSeg = NULL;
    DoSegGrpNames( dgroup_def, tgroup_def );
    if( dgroup_def->used >= 1 ) {
        FlushNames();
        PutObjRec( CMD_GRPDEF, dgroup_def->array, dgroup_def->used );
    }
    if( tgroup_def->used >= 1 ) {
        FlushNames();
        PutObjRec( CMD_GRPDEF, tgroup_def->array, tgroup_def->used );
    }
    KillArray( tgroup_def );
#ifdef _OMF_32
    dgroup_def->used = 0;
    if( _IsTargetModel( FLAT_MODEL ) && _IsntTargetModel( EZ_OMF ) ) {
        FlatGIndex = ++GroupIndex;
        OutIdx( FlatNIndex, dgroup_def );
        FlushNames();
        PutObjRec( CMD_GRPDEF, dgroup_def->array, dgroup_def->used );
        dgroup_def->used = 0;
    }
#endif
    KillArray( dgroup_def );
    CurrSeg = AskSegIndex( CodeSeg );
    KillArray( names );
    ImportHdl = IMPORT_BASE;
    Imports = NULL;
    GenStaticImports = FALSE;
    AbsPatches = NULL;
    if( _IsModel( DBG_DF ) ) {
        if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
            DFObjInitInfo();
#if 0 // save for JimR and linker
        } else if( _IsModel( NUMBERS ) ) {
            DFObjLineInitInfo();
#endif
        }
    } else if( _IsModel( DBG_CV ) ) {
        CVObjInitInfo();
    } else {
        WVObjInitInfo();
    }
}


extern seg_id DbgSegDef( char *seg_name, char *seg_class,
                                int            seg_modifier )
/****************************************************/
{
    index_rec   *rec;

    NeedMore( SegInfo, 1 );
    rec = &_ARRAYOF( SegInfo, index_rec )[ SegInfo->used++ ];
    rec->sidx = ++SegmentIndex;
    rec->cidx = GetNameIdx( seg_class, "", TRUE );
    rec->nidx = GetNameIdx( seg_name, "", TRUE );
    rec->location = 0;
    rec->big = 0;
    rec->need_base_set = 1;
    rec->data_ptr_in_code = FALSE;
    rec->data_in_code = FALSE;
    rec->start_data_in_code = FALSE;
    rec->private = TRUE;
    rec->exec = FALSE;
    rec->rom = FALSE;
    rec->prefix_comdat_state = PCS_OFF;
    rec->max_written = 0;
    rec->max_size = 0;
    rec->comdat_label = NULL;
    rec->comdat_symbol = NULL;
    rec->total_comdat_size = 0;
    rec->comdat_nidx = 0;
    rec->comdat_size = 0;
    rec->virt_func_refs = NULL;
    rec->seg = --BackSegIdx;
    rec->attr = SEG_ALGN_BYTE | seg_modifier;
    rec->data_prefix_size = 0;
    rec->comdat_prefix_import = 0;
    rec->base = rec->sidx;
    rec->btype = BASE_SEG;
    DoASegDef( rec, TRUE );
    return( rec->seg );
}

struct dbg_seg_info {
    seg_id      *id;
    char        *seg_name;
    char        *class_name;
};

static struct dbg_seg_info DbgSegs[] = {
    { &DbgLocals, "$$SYMBOLS", "DEBSYM" },
    { &DbgTypes,  "$$TYPES",   "DEBTYP" },
};

extern void ChkDbgSegSize( offset max, bool typing )
/**************************************************/
{
    struct dbg_seg_info *info;
    seg_id              old;
    long_offset         curr;

    info = &DbgSegs[ typing ? 1 : 0 ];
    old = SetOP( *info->id );
    curr = AskLocation();
    if( curr >= max ) {
        if( typing ) {
            DbgTypeSize += curr;
        }
        *info->id = DbgSegDef( info->seg_name, info->class_name,
                               SEG_COMB_PRIVATE  );
    }
    SetOP( old );
}


static  void    DoSegGrpNames( array_control *dgroup_def,
                                array_control *tgroup_def ) {
/**********************************************************/

    segdef      *seg;
    segdef      *next;
    char        *dgroup;
    unsigned    dgroup_idx;

    GetNameIdx( "", "", TRUE );
#define _NIDX_NULL 1
    GetNameIdx( "CODE", "", TRUE );
#define _NIDX_CODE 2
    GetNameIdx( "DATA", "", TRUE );
#define _NIDX_DATA 3
    GetNameIdx( "BSS", "", TRUE );
#define _NIDX_BSS 4
    GetNameIdx( "TLS", "", TRUE );
#define _NIDX_TLS 5

#ifdef _OMF_32
    if( _IsTargetModel( FLAT_MODEL ) && _IsntTargetModel( EZ_OMF ) ) {
        FlatNIndex = GetNameIdx( "FLAT", "", TRUE );
    }
#endif
    SegmentIndex = 0;
    PrivateIndexRO = 0;
    PrivateIndexRW = 0;
    CopyStr( FEAuxInfo( NULL, CODE_GROUP ), CodeGroup );
    if( CodeGroup[ 0 ] == NULLCHAR ) {
        CodeGroupGIdx = 0;
    } else {
        CodeGroupNIdx = GetNameIdx( CodeGroup, "", TRUE );
        CodeGroupGIdx = ++GroupIndex;
    }
    dgroup = FEAuxInfo( NULL, DATA_GROUP );
    if( dgroup == NULL ) {
        NoDGroup = TRUE;
    } else {
        CopyStr( dgroup, DataGroup );
    }
    if( DataGroup[ 0 ] != NULLCHAR ) {
        TargetModel |= FLOATING_SS;
        dgroup_idx = GetNameIdx( DataGroup, "_GROUP", TRUE );
    } else {
        dgroup_idx = GetNameIdx( "DGROUP", "", TRUE );
    }
    OutIdx( dgroup_idx, dgroup_def );
    seg = SegDefs;
    SegInfo = InitArray( sizeof( index_rec ), MODEST_INFO, INCREMENT_INFO );
    while( seg != NULL ) {
        next = seg->next;
        DoSegment( seg, dgroup_def, tgroup_def, FALSE );
        seg = next;
    }
    SegDefs = NULL;
    if( _IsModel( DBG_DF ) ) {
        if( _IsModel( DBG_LOCALS | DBG_TYPES ) ) {
            DFDefSegs();
        }
    } else if( _IsModel( DBG_CV ) ) {
        CVDefSegs();
    } else {
        DbgTypeSize = 0;
        if( _IsModel( DBG_LOCALS ) ) {
            DbgLocals = DbgSegDef( DbgSegs[0].seg_name, DbgSegs[0].class_name,
                                   SEG_COMB_PRIVATE );
        }
        if( _IsModel( DBG_TYPES ) ) {
            DbgTypes = DbgSegDef( DbgSegs[1].seg_name, DbgSegs[1].class_name,
                                  SEG_COMB_PRIVATE );
        }
    }
}


static  void    SegmentClass( index_rec *rec ) {
/**********************************************/

    char        *class_name;

    class_name = FEAuxInfo( (pointer)(size_t)rec->seg, CLASS_NAME );
    if( class_name == NULL )
        return;
    rec->cidx = GetNameIdx( class_name, "", TRUE );
}

static  byte    SegmentAttr( byte align, seg_attr tipe, bool use_16 ) {
/*********************************************************************/

    byte        attr;

    use_16 = use_16;
    if( align <= 1 ) {
        attr = SEG_ALGN_BYTE;
    } else if( align <= 2 ) {
        attr = SEG_ALGN_WORD;
#ifdef _OMF_32
    } else if( align <= 4 ) {
        attr = SEG_ALGN_DWORD;
#endif
    } else if( align <= 16 ) {
        attr = SEG_ALGN_PARA;
    } else {
        attr = SEG_ALGN_PAGE;
#if 0
    // align is a byte - how can it be bigger than 4k - BBB
  #ifdef _OMF_32
        if( _IsTargetModel( EZ_OMF ) ) {
            if( align > 256 ) {
                attr = SEG_ALGN_4K;
            }
        }
  #endif
#endif
    }
    if( tipe & COMMON ) {
        attr |= SEG_COMB_COMMON;
    } else if( ( tipe & PRIVATE ) != 0 && ( tipe & GLOBAL ) == 0 ) {
        attr |= SEG_COMB_PRIVATE;
    } else { /* normal or a kludge for wsl front end ( PRIVATE | GLOBAL )*/
        attr |= SEG_COMB_NORMAL;
    }
#ifdef _OMF_32
    if( _IsntTargetModel( EZ_OMF ) ) {
        if( _IsTargetModel( USE_32 ) ) {
            if( use_16 == FALSE ) {
                attr |= SEG_USE_32;
            }
        }
    }
#endif
    return( attr );
}

static  void    DoSegment( segdef *seg, array_control *dgroup_def,
                                array_control *tgroup_def, bool use_16 ) {
/******************************************************************************************************/

    index_rec   *rec;
    seg_id      old = 0;

    rec = AskSegIndex( seg->id );
    if( rec == NULL ) {
        if( CurrSeg != NULL ) {
            old = CurrSeg->seg;
        }
        NeedMore( SegInfo, 1 );
        rec = &_ARRAYOF( SegInfo, index_rec )[ SegInfo->used++ ];
        if( CurrSeg != NULL ) {
            // CurrSeg might have moved on us
            CurrSeg = AskSegIndex( old );
        }
    }
    if( seg->attr & PRIVATE ) {
        rec->private = TRUE;
    } else {
        rec->private = FALSE;
    }
    rec->location = 0;
    rec->big = 0;
    rec->rom = 0;
    rec->need_base_set = 1;
    rec->data_in_code = FALSE;
    rec->start_data_in_code = FALSE;
    rec->data_ptr_in_code = FALSE;
    rec->prefix_comdat_state = PCS_OFF;
    rec->max_written = 0;
    rec->max_size = 0;
    rec->comdat_label = NULL;
    rec->comdat_symbol = NULL;
    rec->total_comdat_size = 0;
    rec->comdat_size = 0;
    rec->virt_func_refs = NULL;
    rec->data_prefix_size = 0;
    rec->comdat_prefix_import = 0;
    rec->sidx = ++SegmentIndex;
    rec->seg = seg->id;
    rec->attr = SegmentAttr( seg->align, seg->attr, use_16 );
    if( seg->attr & EXEC ) {
        rec->exec = TRUE;
        rec->rom = TRUE;   /* code is alway ROM */
        rec->cidx = _NIDX_CODE;
        if( seg->attr & GIVEN_NAME ) {
            rec->nidx = GetNameIdx( seg->str, "", TRUE );
        } else if( CodeGroupGIdx != 0 ) {
            rec->nidx = GetNameIdx( CodeGroup, seg->str, TRUE );
        } else if( _IsTargetModel( BIG_CODE ) ) {
            rec->nidx = GetNameIdx( FEModuleName(), seg->str, TRUE );
        } else {
            rec->nidx = GetNameIdx( seg->str, "", TRUE );
        }
        SegmentClass( rec );
        if( CodeGroupGIdx != 0 ) {
            rec->base = CodeGroupGIdx;
            rec->btype = BASE_GRP;
            DoASegDef( rec, use_16 );
            OutCGroup( rec->sidx );
        } else {
            rec->base = SegmentIndex;
            rec->btype = BASE_SEG;
            DoASegDef( rec, use_16 );
        }
    } else {
        rec->exec = FALSE;
        if( seg->attr & ROM )
            rec->rom = TRUE;
        if( seg->attr & PRIVATE ) {
            rec->nidx = GetNameIdx( seg->str, "", TRUE );
            if( seg->attr & ROM ) {
                if( PrivateIndexRO == 0 ) {
                    PrivateIndexRO = GetNameIdx( "FAR_CONST", "", TRUE );
                }
                rec->cidx = PrivateIndexRO;
            } else {
                if( PrivateIndexRW == 0 ) {

⌨️ 快捷键说明

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