Ejemplo n.º 1
0
STATIC void id32Block( obj_rec *objr, OBJ_WFILE *out, int_16 *delta,
                       uint_16 first_block_offset ) {
    /*
        Since LIDATAs are different under PharLap and MicroSoft 386 formats,
        we have to do some magic.
    */
    uint_16 rpt_count;
    uint_16 blk_count;
    uint_8  data_count;
    uint_8  *ptr;

    rpt_count = ObjGet16( objr );
    ObjWrite32( out, rpt_count );
    *delta += 2;    /* ok, everything from here on will be at +2 offset */
    LifixAdd( &lifList, ObjRTell( objr ) - first_block_offset, *delta );
    blk_count = ObjGet16( objr );
    ObjWrite16( out, blk_count );
    if( blk_count == 0 ) {
        data_count = ObjGet8( objr );
        ObjWrite8( out, data_count );
        ptr = ObjGet( objr, data_count );
        ObjWrite( out, ptr, data_count );
    } else {
        for( ; blk_count != 0; --blk_count ) {
            id32Block( objr, out, delta, first_block_offset );
        }
    }
}
Ejemplo n.º 2
0
STATIC int writeLedata( obj_rec *objr, pobj_state *state ) {

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

    /**/myassert( objr != NULL );
    /**/myassert( objr->command == CMD_LEDATA );
    /**/myassert( state != NULL );
    /**/myassert( state->pass == POBJ_WRITE_PASS );
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    LifixDestroy( &lifList );
    LifixInit( &lifList );
#endif
    out = state->file_out;
    is32 = objr->is_32 || objr->is_phar;
    ObjWBegRec( out, is32 ? CMD_LEDA32 : CMD_LEDATA );
    ObjWriteIndex( out, objr->d.ledata.idx );
    if( is32 ) {
        ObjWrite32( out, objr->d.ledata.offset );
    } else {
        ObjWrite16( out, (uint_16)objr->d.ledata.offset );
    }
    save = ObjRTell( objr );
    len = ObjRemain( objr );
    ptr = ObjGet( objr, len );
    /**/myassert( len <= 1024 );
    ObjWrite( out, ptr, len );
    ObjWEndRec( out );
    ObjRSeek( objr, save );
    return( 0 );
}
Ejemplo n.º 3
0
STATIC int writeComdat( obj_rec *objr, pobj_state *state ) {

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

    /**/myassert( objr != NULL );
    /**/myassert( objr->command == CMD_COMDAT );
    /**/myassert( state != NULL );
    /**/myassert( state->pass == POBJ_WRITE_PASS );
    save = ObjRTell( objr );
    is32 = objr->is_32 || objr->is_phar;
    if( is32 ) {
        objr->command |= 1;
    }
    out = state->file_out;
    ObjWBegRec( out, objr->command );
    ObjWrite8( out, objr->d.comdat.flags );
    ObjWrite8( out, objr->d.comdat.attributes );
    ObjWrite8( out, objr->d.comdat.align );
    if( is32 ) {
        ObjWrite32( out, objr->d.comdat.offset );
    } else {
        ObjWrite16( out, (uint_16)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 );
}
Ejemplo n.º 4
0
STATIC int writeLidata( obj_rec *objr, pobj_state *state ) {

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

    /**/myassert( objr != NULL );
    /**/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, (uint_16)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 );
}
Ejemplo n.º 5
0
STATIC int writePubdef( obj_rec *objr, pobj_state *state ) {

    int         is32;
    OBJ_WFILE   *out;
    const char  *name;
    size_t       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;
    if( is32 ) {
        objr->command |= 1;
    }
    out = state->file_out;
    ObjWBegRec( out, objr->command );
    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 );
            if( name_len > 255 )
                name_len = 255;
            ObjWrite8( out, (uint_8)name_len );
            ObjWrite( out, (uint_8 *)name, (uint_16)name_len );
            if( is32 ) {
                ObjWrite32( out, pubdata->offset );
            } else {
                ObjWrite16( out, (uint_16)pubdata->offset );
            }
            ObjWriteIndex( out, pubdata->type.idx );
            ++pubdata;
        }
    }
    ObjWEndRec( out );
    return( 0 );
}
Ejemplo n.º 6
0
STATIC void writeLinnumData( obj_rec *objr, OBJ_WFILE *out ) {

    int  is32;
    linnum_data *cur;
    linnum_data *stop;

    /**/myassert( objr != NULL );
    /**/myassert( out != NULL );
    is32 = objr->is_32 || objr->is_phar;
    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 {
            /**/        myassert( ( cur->offset & 0xffff0000 ) == 0 );
            ObjWrite16( out, (uint_16)cur->offset );
        }
        ++cur;
    }
}
Ejemplo n.º 7
0
void WriteFiles (void)
/* Write the list of input files to the object file */
{
    unsigned I;

    /* Tell the obj file module that we're about to start the file list */
    ObjStartFiles ();

    /* Write the file count */
    ObjWriteVar (CollCount (&FileTab));

    /* Write the file data */
    for (I = 0; I < CollCount (&FileTab); ++I) {
        /* Get a pointer to the entry */
        const FileEntry* F = CollConstAt (&FileTab, I);
        /* Write the fields */
        ObjWriteVar (F->Name);
        ObjWrite32 (F->MTime);
        ObjWriteVar (F->Size);
    }

    /* Done writing files */
    ObjEndFiles ();
}
Ejemplo n.º 8
0
STATIC int writeSegdef( obj_rec *objr, pobj_state *state ) {

    OBJ_WFILE   *out;
    int         is32;
    uint_8      acbp;
    uint_8      align;
#if ( _WOMP_OPT & _WOMP_NASM )
    obj_offset  patch;
#endif

    /**/myassert( objr != NULL );
    /**/myassert( objr->command == CMD_SEGDEF );
    /**/myassert( state != NULL );
    /**/myassert( state->pass == POBJ_WRITE_PASS );
    out = state->file_out;
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    is32 = objr->d.segdef.use_32 != 0;
#else
#ifdef _WOMP_WATFOR_8086
    is32 = 0;
#else
    is32 = 1;
#endif
#endif
    ObjWBegRec( out, is32 ? CMD_SEGD32 : CMD_SEGDEF );
    acbp = objr->d.segdef.combine << 2;
    if( is32 ) {
        acbp |= 1;
    }
    align = objr->d.segdef.align;
    switch( align ) {
    case SEGDEF_ALIGN_ABS:
        acbp |= ALIGN_ABS << 5;
        break;
    case SEGDEF_ALIGN_BYTE:
        acbp |= ALIGN_BYTE << 5;
        break;
    case SEGDEF_ALIGN_WORD:
        acbp |= ALIGN_WORD << 5;
        break;
    case SEGDEF_ALIGN_PARA:
        acbp |= ALIGN_PARA << 5;
        break;
    case SEGDEF_ALIGN_PAGE:
        acbp |= ALIGN_PAGE << 5;
        break;
    case SEGDEF_ALIGN_DWORD:
        acbp |= ALIGN_DWORD << 5;
        break;
    case SEGDEF_ALIGN_4KPAGE:
        acbp |= ALIGN_PAGE;
#if _WOMP_OPT & _WOMP_EXTRAS
        PrtMsg( WRN|MSG_MS386_NO_4KPAGE );
#endif
        break;
    default:
        /**/
        never_reach();
    }
    if( !is32 && objr->d.segdef.seg_length == 0x10000 ) {
        acbp |= 0x02;   /* BIG bit */ /* FIXME no support for 2**32 */
    }
    ObjWrite8( out, acbp );
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    if( align == SEGDEF_ALIGN_ABS ) {
        // absolut segment has frame=word and offset=byte
        // it isn't fixupp physical reference
        // and don't depend on segment size (16/32bit)
        ObjWrite16( out, objr->d.segdef.abs.frame );
        ObjWrite8( out, (uint_8)objr->d.segdef.abs.offset );
    }
#endif
    if( is32 ) {
#if ( _WOMP_OPT & _WOMP_NASM )
        patch = ObjWSkip32( out );
#else
        ObjWrite32( out, objr->d.segdef.seg_length );
#endif
    } else {
#if ( _WOMP_OPT & _WOMP_NASM )
        patch = ObjWSkip16( out );
#else
        ObjWrite16( out, (uint_16)objr->d.segdef.seg_length );
#endif
    }
#if ( _WOMP_OPT & _WOMP_NASM )
    /**/myassert( objr->data != NULL );
    memcpy( objr->data, &patch, sizeof patch);
#endif
    ObjWriteIndex( out, objr->d.segdef.seg_name_idx );
    ObjWriteIndex( out, objr->d.segdef.class_name_idx );
#if ( _WOMP_OPT & _WOMP_WATFOR ) == 0
    ObjWriteIndex( out, objr->d.segdef.ovl_name_idx );
#if ( _WOMP_OPT & _WOMP_EXTRAS )
    if( objr->d.segdef.access_valid ) {
        PrtMsg( MSG_MS386_NO_ACCESS );
    }
#endif
#else
    ObjWriteIndex( out, 1 );
#endif
    ObjWEndRec( out );
    return( 0 );
}
Ejemplo n.º 9
0
void WriteDbgSyms (void)
/* Write a list of all symbols to the object file */
{
    unsigned Count;
    SymEntry* S;

    /* Tell the object file module that we're about to start the debug info */
    ObjStartDbgSyms ();

    /* Check if debug info is requested */
    if (DbgSyms) {

        /* Walk through the list, give each symbol an id and count them */
        Count = 0;
        S = SymList;
        while (S) {
            if (IsDbgSym (S)) {
                S->DebugSymId = Count++;
            }
            S = S->List;
        }

        /* Write the symbol count to the list */
        ObjWriteVar (Count);

        /* Walk through list and write all symbols to the file. Ignore size
        ** symbols.
        */
        S = SymList;
        while (S) {
            if (IsDbgSym (S)) {

                /* Get the expression bits and the value */
                long ConstVal;
                unsigned SymFlags = GetSymInfoFlags (S, &ConstVal);

                /* Check if this symbol has a size. If so, remember it in the
                ** flags.
                */
                long Size;
                SymEntry* SizeSym = FindSizeOfSymbol (S);
                if (SizeSym != 0 && SymIsConst (SizeSym, &Size)) {
                    SymFlags |= SYM_SIZE;
                }

                /* Write the type */
                ObjWriteVar (SymFlags);

                /* Write the address size */
                ObjWrite8 (S->AddrSize);

                /* Write the id of the parent. For normal symbols, this is a
                ** scope (symbol table), for cheap locals, it's a symbol.
                */
                if (SYM_IS_STD (SymFlags)) {
                    ObjWriteVar (S->Sym.Tab->Id);
                } else {
                    ObjWriteVar (S->Sym.Entry->DebugSymId);
                }

                /* Write the name */
                ObjWriteVar (S->Name);

                /* Write the value */
                if (SYM_IS_CONST (SymFlags)) {
                    /* Constant value */
                    ObjWrite32 (ConstVal);
                } else {
                    /* Expression involved */
                    WriteExpr (S->Expr);
                }

                /* If the symbol has a size, write it to the file */
                if (SYM_HAS_SIZE (SymFlags)) {
                    ObjWriteVar (Size);
                }

                /* If the symbol is an im- or export, write out the ids */
                if (SYM_IS_IMPORT (SymFlags)) {
                    ObjWriteVar (GetSymImportId (S));
                }
                if (SYM_IS_EXPORT (SymFlags)) {
                    ObjWriteVar (GetSymExportId (S));
                }

                /* Write the line infos */
                WriteLineInfo (&S->DefLines);
                WriteLineInfo (&S->RefLines);
            }
            S = S->List;
        }

    } else {

        /* No debug symbols */
        ObjWriteVar (0);

    }

    /* Write the high level symbols */
    WriteHLLDbgSyms ();

    /* Done writing debug symbols */
    ObjEndDbgSyms ();
}
Ejemplo n.º 10
0
void WriteExports (void)
/* Write the exports list to the object file */
{
    SymEntry* S;
    unsigned Type;

    /* Tell the object file module that we're about to start the exports */
    ObjStartExports ();

    /* Write the export count to the list */
    ObjWriteVar (ExportCount);

    /* Walk throught list and write all exports to the file */
    S = SymList;
    while (S) {
        if ((S->Flags & (SF_UNUSED | SF_EXPORT)) == SF_EXPORT) {

            /* Get the expression bits and the value */
            long ConstVal;
            unsigned SymFlags = GetSymInfoFlags (S, &ConstVal);

            /* Check if this symbol has a size. If so, remember it in the
            ** flags.
            */
            long Size;
            SymEntry* SizeSym = FindSizeOfSymbol (S);
            if (SizeSym != 0 && SymIsConst (SizeSym, &Size)) {
                SymFlags |= SYM_SIZE;
            }

            /* Count the number of ConDes types */
            for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
                if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
                    SYM_INC_CONDES_COUNT (SymFlags);
                }
            }

            /* Write the type and the export size */
            ObjWriteVar (SymFlags);
            ObjWrite8 (S->ExportSize);

            /* Write any ConDes declarations */
            if (SYM_GET_CONDES_COUNT (SymFlags) > 0) {
                for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
                    unsigned char Prio = S->ConDesPrio[Type];
                    if (Prio != CD_PRIO_NONE) {
                        ObjWrite8 (CD_BUILD (Type, Prio));
                    }
                }
            }

            /* Write the name */
            ObjWriteVar (S->Name);

            /* Write the value */
            if (SYM_IS_CONST (SymFlags)) {
                /* Constant value */
                ObjWrite32 (ConstVal);
            } else {
                /* Expression involved */
                WriteExpr (S->Expr);
            }

            /* If the symbol has a size, write it to the file */
            if (SYM_HAS_SIZE (SymFlags)) {
                ObjWriteVar (Size);
            }

            /* Write the line infos */
            WriteLineInfo (&S->DefLines);
            WriteLineInfo (&S->RefLines);
        }
        S = S->List;
    }

    /* Done writing exports */
    ObjEndExports ();
}