genmsomf.c

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

C
681
字号
/**/myassert( objr->command == CMD_LIDATA );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    LifixDestroy( &lifList );
    LifixInit( &lifList );
    out = state->file_out;
    save = ObjRTell( objr );
    is32 = objr->is_32 || objr->is_phar;
    ObjWBegRec( out, is32 ? CMD_LIDA32 : CMD_LIDATA );
    ObjWriteIndex( out, objr->d.lidata.idx );
    if( is32 ) {
        ObjWrite32( out, objr->d.lidata.offset );
    } else {
        ObjWrite16( out, objr->d.lidata.offset );
    }
    if( objr->is_phar == 0 ) {
        /* ok, already in our format */
        len = ObjRemain( objr );
        ptr = ObjGet( objr, len );
        ObjWrite( out, ptr, len );
    } else {
        int_16 delta;
        uint_16 first_block_offset;

        delta = 0;  /* id32Block needs to play with this */
        first_block_offset = ObjRTell( objr );
        while( !ObjEOR( objr ) ) {
            id32Block( objr, out, &delta, first_block_offset );
        }
    }
    ObjWEndRec( out );
    ObjRSeek( objr, save );
    return( 0 );
}

#endif

STATIC int writeTheadr( obj_rec *objr, pobj_state *state ) {

/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_THEADR );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
        /* here's our initialization code */
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    LifixInit( &lifList );
#endif

    return( writeMisc( objr, state ) );
}

STATIC int writeModend( obj_rec *objr, pobj_state *state ) {

    size_t  len;
    char    is32;
#if _WOMP_OPT & _WOMP_WATFOR
    char    buf[ 1 ];
#else
    char    buf[ 1 + FIX_GEN_MAX ];
    char    is_log;
#endif

/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_MODEND );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    is32 = ( objr->is_32 || objr->is_phar );
    len = 1;
    buf[0]  = objr->d.modend.main_module ? 0x80 : 0;
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    if( objr->d.modend.start_addrs ) {
        is_log = objr->d.modend.is_logical ? 1 : 0;
#if _WOMP_OPT & _WOMP_WOMP
        if( is_log && Can2MsOS2Flat() ) {
            switch( objr->d.modend.ref.log.frame ) {
            case FRAME_SEG:
            case FRAME_GRP:
            case FRAME_TARG:
                objr->d.modend.ref.log.frame = FRAME_GRP;
                objr->d.modend.ref.log.frame_datum = ObjFLATIndex;
                break;
            }
        }
#endif
        buf[0] |= 0x40 | is_log;
        len += FixGenRef( &objr->d.modend.ref, is_log, buf + 1,
            is32 ? FIX_GEN_MS386 : FIX_GEN_INTEL );
    }
#endif
    if( buf[0] == 0 ) {
        is32 = 0;       /* no need for MODE32 in this case */
    }
    ObjWriteRec( state->file_out, is32 ? CMD_MODE32 : CMD_MODEND,
        len, buf );

        /* here's our fini code */
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    LifixDestroy( &lifList );
#endif

    return( 0 );
}

#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0

STATIC void writeBase( obj_rec *objr, OBJ_WFILE *out ) {

    uint_16 grp_idx;
    uint_16 seg_idx;

    grp_idx = objr->d.base.grp_idx;
    seg_idx = objr->d.base.seg_idx;
    ObjWriteIndex( out, grp_idx );
    ObjWriteIndex( out, seg_idx );
    if( grp_idx == 0 && seg_idx == 0 ) {
        ObjWrite16( out, objr->d.base.frame );
    }
}

STATIC int writeComdat( obj_rec *objr, pobj_state *state ) {

    OBJ_WFILE   *out;
    uint_8      *ptr;
    uint_16     len;
    uint_16     save;
    int         is_32;

/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_COMDAT );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    save = ObjRTell( objr );
    is_32 = objr->is_32 || objr->is_phar;
    out = state->file_out;
    ObjWBegRec( out, objr->command | ( is_32 ? 1 : 0 ) );
    ObjWrite8( out, objr->d.comdat.flags );
    ObjWrite8( out, objr->d.comdat.attributes );
    ObjWrite8( out, objr->d.comdat.align );
    if( is_32 ) {
        ObjWrite32( out, objr->d.comdat.offset );
    } else {
        ObjWrite16( out, objr->d.comdat.offset );
    }
    ObjWriteIndex( out, objr->d.comdat.type_idx );
    if( ( objr->d.comdat.attributes & COMDAT_ALLOC_MASK ) == COMDAT_EXPLICIT ) {
        writeBase( objr, out );
    }
    ObjWriteIndex( out, objr->d.comdat.public_name_idx );
    if( ( objr->d.comdat.flags & COMDAT_ITERATED ) == 0 || objr->is_phar == 0 ){
        /* record is already in ms omf format */
        len = ObjRemain( objr );
        ptr = ObjGet( objr, len );
/**/    myassert( len <= 1024 );
        ObjWrite( out, ptr, len );
    } else {
        int_16 delta;
        uint_16 first_block_offset;

        delta = 0;  /* id32Block needs to play with this */
        first_block_offset = ObjRTell( objr );
        while( !ObjEOR( objr ) ) {
            id32Block( objr, out, &delta, first_block_offset );
        }
    }
    ObjWEndRec( out );
    ObjRSeek( objr, save );
    return( 0 );
}

STATIC int writePubdef( obj_rec *objr, pobj_state *state ) {

    int         is32;
    OBJ_WFILE   *out;
    const char  *name;
    uint_8      name_len;
    pubdef_data *pubdata;
    pubdef_data *pubstop;

/**/myassert( objr != NULL );
/**/myassert(   objr->command == CMD_PUBDEF ||
                objr->command == CMD_STATIC_PUBDEF );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    is32 = objr->is_32 || objr->is_phar;
    out = state->file_out;
    ObjWBegRec( out, objr->command | ( is32 ? 1 : 0 ) );
    writeBase( objr, out );
    pubdata = objr->d.pubdef.pubs;
    if( pubdata != NULL ) {
        pubstop = pubdata + objr->d.pubdef.num_pubs;
        while( pubdata < pubstop ) {
            name = NameGet( pubdata->name );
            name_len = strlen( name );
            ObjWrite8( out, name_len );
            ObjWrite( out, name, (size_t)name_len );
            if( is32 ) {
                ObjWrite32( out, pubdata->offset );
            } else {
                ObjWrite16( out, pubdata->offset );
            }
            ObjWriteIndex( out, pubdata->type.idx );
            ++pubdata;
        }
    }
    ObjWEndRec( out );
    return( 0 );
}

STATIC void writeLinnumData( obj_rec *objr, OBJ_WFILE *out ) {

    int is32;

/**/myassert( objr != NULL );
/**/myassert( out != NULL );
    is32 = objr->is_32 || objr->is_phar;
#if defined( __BIG_ENDIAN__ )
    {
        linnum_data *cur;
        linnum_data *stop;

        cur = objr->d.linnum.lines;
        stop = cur + objr->d.linnum.num_lines;
        while( cur < stop ) {
            ObjWrite16( out, cur->number );
            if( is32 ) {
                ObjWrite32( out, cur->offset );
            } else {
                ObjWrite16( out, (uint_16)cur->offset );
            }
            ++cur;
        }
    }
#else
    if( is32 ) {
        ObjWrite( out, (char *)objr->d.linnum.lines,
            6 * objr->d.linnum.num_lines );
/**/    myassert( sizeof( linnum_data ) == 6 );
    } else {
        linnum_data *cur;
        linnum_data *stop;

        cur = objr->d.linnum.lines;
        stop = cur + objr->d.linnum.num_lines;
        while( cur < stop ) {
            ObjWrite16( out, cur->number );
/**/        myassert( ( cur->offset & 0xffff0000 ) == 0 );
            ObjWrite16( out, (uint_16)cur->offset );
            ++cur;
        }
    }
#endif
}

STATIC int writeLinnum( obj_rec *objr, pobj_state *state ) {

    int         is32;
    OBJ_WFILE   *out;

/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LINNUM );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    out = state->file_out;
    is32 = objr->is_32 || objr->is_phar;
    ObjWBegRec( out, is32 ? CMD_LINN32 : CMD_LINNUM );
    writeBase( objr, out );
    writeLinnumData(objr, out );
    ObjWEndRec( out );
    return( 0 );
}

STATIC int writeLinsym( obj_rec *objr, pobj_state *state ) {

    int         is32;
    OBJ_WFILE   *out;

/**/myassert( objr != NULL );
/**/myassert( objr->command == CMD_LINSYM );
/**/myassert( state != NULL );
/**/myassert( state->pass == POBJ_WRITE_PASS );
    out = state->file_out;
    is32 = objr->is_32 || objr->is_phar;
    ObjWBegRec( out, is32 ? CMD_LINS32 : CMD_LINSYM );
    ObjWrite8( out, objr->d.linsym.d.linsym.flags );
    ObjWriteIndex( out, objr->d.linsym.d.linsym.public_name_idx );
    writeLinnumData( objr, out );
    ObjWEndRec( out );
    return( 0 );
}

#endif

STATIC const pobj_list myFuncs[] = {
    { CMD_THEADR,       POBJ_WRITE_PASS, writeTheadr },
    { CMD_COMENT,       POBJ_WRITE_PASS, writeComent },
    { CMD_MODEND,       POBJ_WRITE_PASS, writeModend },
    { CMD_EXTDEF,       POBJ_WRITE_PASS, writeMisc },
    { CMD_LNAMES,       POBJ_WRITE_PASS, writeMisc },
    { CMD_SEGDEF,       POBJ_WRITE_PASS, writeSegdef },
    { CMD_GRPDEF,       POBJ_WRITE_PASS, writeMisc },
    { CMD_LEDATA,       POBJ_WRITE_PASS, writeLedata },
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    { CMD_FIXUP,        POBJ_WRITE_PASS, writeFixup },
    { CMD_PUBDEF,       POBJ_WRITE_PASS, writePubdef },
    { CMD_TYPDEF,       POBJ_WRITE_PASS, writeMisc },
    { CMD_LINNUM,       POBJ_WRITE_PASS, writeLinnum },
    { CMD_LIDATA,       POBJ_WRITE_PASS, writeLidata },
    { CMD_COMDEF,       POBJ_WRITE_PASS, writeMisc },
    { CMD_CEXTDF,       POBJ_WRITE_PASS, writeMisc },
    { CMD_STATIC_EXTDEF,POBJ_WRITE_PASS, writeMisc32 },
    { CMD_STATIC_PUBDEF,POBJ_WRITE_PASS, writePubdef },
    { CMD_STATIC_COMDEF,POBJ_WRITE_PASS, writeMisc },
    { CMD_BAKPAT,       POBJ_WRITE_PASS, writeMisc32 },
    { CMD_COMDAT,       POBJ_WRITE_PASS, writeComdat },
    { CMD_LINSYM,       POBJ_WRITE_PASS, writeLinsym },
    { CMD_ALIAS,        POBJ_WRITE_PASS, writeMisc },
    { CMD_NBKPAT,       POBJ_WRITE_PASS, writeMisc32 },
    { CMD_LLNAMES,      POBJ_WRITE_PASS, writeMisc }
#else
  #ifdef _WOMP_WATFOR_8086
    { CMD_FIXUP,        POBJ_WRITE_PASS, writeMisc },
    { CMD_PUBDEF,       POBJ_WRITE_PASS, writeMisc }
  #else
    { CMD_FIXUP,        POBJ_WRITE_PASS, writeMisc32 },
    { CMD_PUBDEF,       POBJ_WRITE_PASS, writeMisc32 }
  #endif
#endif
};
#define NUM_FUNCS   ( sizeof( myFuncs ) / sizeof( pobj_list ) )

void GenMSOmfInit( void ) {
/***********************/
    PObjRegList( myFuncs, NUM_FUNCS );
}

void GenMSOmfFini( void ) {
/***********************/
    PObjUnRegList( myFuncs, NUM_FUNCS );
}

⌨️ 快捷键说明

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