示例#1
0
static void WriteQNXRelocs( RELOC_INFO *head, unsigned lmf_type, unsigned_16 seg )
/********************************************************************************/
{
    lmf_record          record;
    unsigned_32         pos;
    unsigned_32         size;
    bool                islinear;
    unsigned            adjust;

    adjust = 0;
    record.reserved = record.spare = 0;
    record.rec_type = lmf_type;
    islinear = (lmf_type == LMF_LINEAR_FIXUP_REC);
    if( islinear ) {
        adjust = 2;
    }
    pos = PosLoad();    /* get current position */
    while( head != NULL ) {
        SeekLoad( pos + sizeof(lmf_record) );
        if( islinear ) {
            WriteLoad( &seg, sizeof(unsigned_16) );
        }
        size = DumpMaxRelocList( &head, QNX_MAX_FIXUPS - adjust ) + adjust;
        SeekLoad( pos );
        record.data_nbytes = size;
        WriteLoad( &record, sizeof( lmf_record ) );
        pos += size + sizeof( lmf_record );
    }
    SeekLoad( pos );
}
示例#2
0
void FiniDOSLoadFile( void )
/*********************************/
/* terminate writing of load file */
{
    unsigned_32         hdr_size;
    unsigned_32         mz_hdr_size;
    unsigned_32         temp;
    unsigned_32         min_size;
    unsigned_32         root_size;
    dos_exe_header      exe_head;

    if( FmtData.type & MK_COM ) {
        WriteCOMFile();
        return;
    }
    if( FmtData.u.dos.full_mz_hdr ) {
        mz_hdr_size = 0x40;
    } else {
        mz_hdr_size = sizeof( dos_exe_header ) + sizeof( unsigned_32 );
    }
    SeekLoad( mz_hdr_size );
    root_size = WriteDOSData( mz_hdr_size );
    if( FmtData.type & MK_OVERLAYS ) {
        PadOvlFiles();
    }
    // output debug info into root main output file
    CurrSect = Root;
    DBIWrite();
    hdr_size = MAKE_PARA( (unsigned long)Root->relocs * sizeof( dos_addr )
                                                                 + mz_hdr_size );
    DEBUG((DBG_LOADDOS, "root size %l, hdr size %l", root_size, hdr_size ));
    SeekLoad( 0 );
    _HostU16toTarg( DOS_SIGNATURE, exe_head.signature );
    temp = hdr_size / 16U;
    _HostU16toTarg( temp, exe_head.hdr_size );
    _HostU16toTarg( root_size % 512U, exe_head.mod_size );
    temp = ( root_size + 511U ) / 512U;
    _HostU16toTarg( temp, exe_head.file_size );
    _HostU16toTarg( Root->relocs, exe_head.num_relocs );

    min_size = MemorySize() - ( root_size - hdr_size ) + FmtData.SegMask;
    min_size >>= FmtData.SegShift;
    _HostU16toTarg( min_size, exe_head.min_16 );
    _HostU16toTarg( 0xffff, exe_head.max_16 );
    _HostU16toTarg( StartInfo.addr.off, exe_head.IP );
    _HostU16toTarg( StartInfo.addr.seg, exe_head.CS_offset );
    _HostU16toTarg( StackAddr.seg, exe_head.SS_offset );
    _HostU16toTarg( StackAddr.off, exe_head.SP );
    _HostU16toTarg( 0, exe_head.chk_sum );
    _HostU16toTarg( mz_hdr_size, exe_head.reloc_offset );
    _HostU16toTarg( 0, exe_head.overlay_num );
    WriteLoad( &exe_head, sizeof( dos_exe_header ) );
    WriteLoad( &OvlTabOffset, sizeof( unsigned_32 ) );
}
示例#3
0
static wio_ssize_t res_write( WResFileID dummy, const void *buff, wio_size_t size )
/*********************************************************************************/
/* redirect wres write to writeload */
{
    dummy = dummy;
    DbgAssert( dummy == Root->outfile->handle );
    WriteLoad( (void *)buff, size );
    return( size );
}
示例#4
0
文件: linkutil.c 项目: JWasm/JWlink
static ssize_t ResWrite( int dummy, const void *buff, size_t size )
/*****************************************************************/
/* redirect wres write to writeload */
{
    dummy = dummy;
    DbgAssert( dummy == Root->outfile->handle );
    WriteLoad( (void *) buff, size );
    return( size );
}
示例#5
0
static void WriteLoadRec( void )
/******************************/
{
    lmf_record      record;
    lmf_data        data;

    record.rec_type = LMF_LOAD_REC;
    record.reserved = record.spare = 0;
    if( CurrGroup->size - AmountWritten > QNX_MAX_DATA_SIZE ){
        record.data_nbytes = QNX_MAX_REC_SIZE;
    } else {
        record.data_nbytes = CurrGroup->size - AmountWritten + sizeof(lmf_data);
    }
    WriteLoad( &record, sizeof( lmf_record ) );
    data.segment = QNX_SEL_NUM( CurrGroup->grp_addr.seg );
    data.offset = AmountWritten;
    WriteLoad( &data, sizeof( lmf_data ) );
}
示例#6
0
void FiniELFLoadFile( void )
/*********************************/
{
    ElfHdr      hdr;

    SetHeaders( &hdr );
#if 0
    if( (LinkState & HAVE_PPC_CODE) && (FmtData.type & MK_OS2) ) {
        // Development temporarly on hold
        // BuildOS2Imports(); // Build .got section
    }
#endif

    WriteELFGroups( &hdr ); // Write out all groups
    WriteRelocsSections( &hdr );        // Relocations
    if( INJECT_DEBUG ) {                // Debug info
        hdr.curr_off = DwarfWriteElf( hdr.curr_off, &hdr.secstrtab,
                                hdr.sh+hdr.i.dbgbegin );
    }
    if( ElfSymTab != NULL ) {           // Symbol tables
        WriteElfSymTable( ElfSymTab, &hdr, hdr.i.symhash, hdr.i.symtab,
                          hdr.i.symstr);
        ZapElfSymTable( ElfSymTab );
    }
    if( hdr.i.symstr != 0 ) {           // String sections
        WriteSHStrings( &hdr, hdr.i.symstr, &SymStrTab );
    }
    WriteSHStrings( &hdr, hdr.i.secstr, &hdr.secstrtab );
    hdr.eh.e_shoff = hdr.curr_off;
    WriteLoad( hdr.sh, hdr.sh_size );
    hdr.curr_off += hdr.sh_size;
    if( !INJECT_DEBUG ) {
        DBIWrite();
    }
    SeekLoad( 0 );
    WriteLoad( &hdr.eh, sizeof(Elf32_Ehdr) );
    WriteLoad( hdr.ph, hdr.ph_size );
    _LnkFree( hdr.sh );
    _LnkFree( hdr.ph );
    FiniStringTable( &hdr.secstrtab );
    FiniStringTable( &SymStrTab );
    SeekLoad( hdr.curr_off );
}
示例#7
0
static void WriteQNXData( unsigned_32 * segments )
/************************************************/
{
    group_entry *   grp;
    lmf_record      record;
    bool            first;

    first = true;
    InVerifySegment = false;
    /* write all read/write segment data */
    RWEndRec.signature = 0;
    for( grp = Groups; grp != NULL; grp = grp->next_group ){
        if( grp->u.qnxflags == QNX_READ_WRITE && grp->totalsize != 0 ) {
            if( first && grp->size >= VERIFY_END ) {
                InVerifySegment = true;
                first = false;
            }
            WriteQNXGroup( grp, segments );
        }
        RWEndRec.signature += grp->totalsize;
        RWEndRec.signature <<= 3;
        RWEndRec.signature ^= 0x32476235;
    }
    record.reserved = record.spare = 0;
    record.rec_type = LMF_RW_END_REC;
    record.data_nbytes = sizeof( RWEndRec );
    WriteLoad( &record, sizeof( lmf_record ) );
    RWEndRec.verify ^= (unsigned_16) ~0;
    WriteLoad( &RWEndRec, sizeof( RWEndRec ) );
    /* write all read only segment data */
    for( grp = Groups; grp != NULL; grp = grp->next_group ){
        if( grp->u.qnxflags != QNX_READ_WRITE && grp->totalsize != 0 ) {
            WriteQNXGroup( grp, segments );
        }
        WriteQNXRelocs( grp->g.grp_relocs, LMF_LINEAR_FIXUP_REC,
                        QNX_SEL_NUM(grp->grp_addr.seg) );
    }
}
示例#8
0
static void WritePharSimple( unsigned_32 start )
/**********************************************/
{
    simple_header   header;
    unsigned_32     file_size;
    unsigned_32     header_size;
    unsigned_32     extra;
    unsigned_32     temp;

    if( FmtData.type & MK_PHAR_REX ) {
        SeekLoad( start + sizeof(simple_header) );
        extra = start + sizeof( simple_header ) + WritePharRelocs();
        header_size = MAKE_PARA( extra );
        PadLoad( header_size - extra );
    } else {
        SeekLoad( start + MAKE_PARA( sizeof(simple_header) ) );
        header_size = MAKE_PARA( sizeof(simple_header) );    // para align.
    }
    file_size = header_size + WritePharData( start + header_size );
    DBIWrite();
    if( FmtData.type & MK_PHAR_SIMPLE ) {
        _HostU16toTarg( SIMPLE_SIGNATURE, header.signature );
    } else {
        _HostU16toTarg( REX_SIGNATURE, header.signature );
    }
    _HostU16toTarg( file_size % 512U, header.mod_size );
    _HostU16toTarg( (file_size + 511U) / 512U, header.file_size );
    _HostU16toTarg( Root->relocs, header.num_relocs );
    _HostU16toTarg( header_size / 16, header.hdr_size );
    extra = MemorySize() - file_size + header_size + 0xfff;
    temp = FmtData.u.phar.mindata + extra;
    if( temp < FmtData.u.phar.mindata ) temp = 0xffffffff;
    _HostU16toTarg( temp >> 12, header.min_data );
    temp = FmtData.u.phar.maxdata + extra;
    if( temp < FmtData.u.phar.maxdata ) temp = 0xffffffff;
    _HostU16toTarg( temp >> 12, header.max_data );
    _HostU32toTarg( StackAddr.off, header.ESP );
    _HostU16toTarg( 0, header.checksum );
    _HostU32toTarg( StartInfo.addr.off, header.EIP );
    _HostU16toTarg( 0x1E, header.reloc_offset );
    _HostU16toTarg( 0, header.overlay_num );
    /* allow header size to exceed 1M */
    _HostU16toTarg( (header_size / (16*0x10000ul)) + 1, header.always_one );
    SeekLoad( start );
    WriteLoad( &header, sizeof( simple_header ) );
    if( FmtData.type & MK_PHAR_SIMPLE ) {
        PadLoad( 2 );                   // header occupies a full paragraph.
    }
}
示例#9
0
static unsigned long WriteOS2Relocs( group_entry *group )
/*******************************************************/
/* write all relocs associated with group to the file */
{
    unsigned long relocsize;
    unsigned long relocnum;

    relocsize = RelocSize( group->g.grp_relocs );
    relocnum = relocsize / sizeof( os2_reloc_item );
    if( relocnum == 0 )
        return( 0 );
    WriteLoad( &relocnum, 2 );
    DumpRelocList( group->g.grp_relocs );
    return( relocsize );
}
示例#10
0
static void WriteHeader16( void )
/* write 16-bit device header */
{
    rdos_dev16_header   exe_head;
    unsigned_16         temp16;

    SeekLoad( 0 );
    _HostU16toTarg( RDOS_SIGNATURE_16, exe_head.signature );
    _HostU16toTarg( StartInfo.addr.off, exe_head.IP );
    temp16 = (unsigned_16)CodeSize;
    _HostU16toTarg( temp16, exe_head.code_size );
    temp16 = (unsigned_16)FmtData.u.rdos.code_sel;
    _HostU16toTarg( temp16, exe_head.code_sel );
    temp16 = (unsigned_16)DataSize;
    _HostU16toTarg( temp16, exe_head.data_size );
    temp16 = (unsigned_16)FmtData.u.rdos.data_sel;
    _HostU16toTarg( temp16, exe_head.data_sel );
    WriteLoad( &exe_head, sizeof( rdos_dev16_header ) );
}
示例#11
0
extern void FiniZdosLoadFile( void )
/*************************************/
{
    zdos_exe_header header;
    unsigned_32     position;
    unsigned_32     size;
    unsigned_32     checksum;

    for( position = 0; position < 4; position ++ )
        header.reserved[position] = 0;
    checksum = ZDOS_SIGNATURE;
    _HostU32toTarg( ZDOS_SIGNATURE, header.signature );
    _HostU32toTarg( StartInfo.addr.off, header.EIP );
    checksum += StackAddr.off;
    _HostU32toTarg( StackAddr.off, header.ESP );
    checksum += StackAddr.off;
    _HostU32toTarg( sizeof( zdos_exe_header ), header.hdr_size );
    checksum += sizeof( zdos_exe_header );
    _HostU32toTarg( Root->relocs, header.num_relocs );
    checksum += Root->relocs;
    _HostU32toTarg( sizeof( zdos_exe_header ), header.reloc_offset );
    checksum += sizeof( zdos_exe_header );
    _HostU32toTarg( FmtData.base, header.reloc_base );
    checksum += FmtData.base;
    SeekLoad( sizeof(zdos_exe_header) );
    position = sizeof( zdos_exe_header ) + WriteZdosRelocs();
    _HostU32toTarg( position, header.image_offset );
    checksum += position;
    size = WriteZdosData( position );
    _HostU32toTarg( size, header.image_size );
    checksum += size;
    position += size;
    _HostU32toTarg( position, header.debug_offset );
    checksum += position;
    size = ( StackAddr.off - FmtData.base ) - size;
    _HostU32toTarg( size, header.extra_size );
    checksum += size;
    _HostU32toTarg( size, header.chk_sum );
    DBIWrite();
    SeekLoad( 0 );
    WriteLoad( &header, sizeof( zdos_exe_header ) );
}
示例#12
0
static void WriteMbootHeader( void )
/* write multiboot header */
{
    struct mb_header   mb_head;
    unsigned_32        temp32;
    unsigned_32        linear = MB_BASE;

    SeekLoad( 0 );
    _HostU32toTarg(0x1BADB002, mb_head.mb_magic );
    _HostU32toTarg(0x00010001, mb_head.mb_flags );
    _HostU32toTarg(0xE4514FFD, mb_head.mb_checksum );
    _HostU32toTarg(linear, mb_head.mb_header_addr );
    _HostU32toTarg(linear, mb_head.mb_load_addr );
    linear += CodeSize + sizeof( struct mb_header );
    _HostU32toTarg(linear, mb_head.mb_load_end_addr );
    _HostU32toTarg(linear, mb_head.mb_bss_end_addr );
    temp32 = MB_BASE + StartInfo.addr.off + sizeof( struct mb_header );
    _HostU32toTarg(temp32, mb_head.mb_entry_addr );
    WriteLoad( &mb_head, sizeof( struct mb_header ) );
}
示例#13
0
static void WriteQNXResource( void )
/**********************************/
{
    unsigned long   len;
    lmf_record      rec;
    f_handle        file;
    lmf_resource    resource;
    void *          buf;

    if( FmtData.resource != NULL ) {
        rec.reserved = 0;
        rec.spare = 0;
        rec.rec_type = LMF_RESOURCE_REC;
        memset( &resource, 0, sizeof( lmf_resource ) );
        if( FmtData.res_name_only ) {
            file = QObjOpen( FmtData.resource );
            if( file == NIL_FHANDLE ) {
                PrintIOError( WRN+MSG_CANT_OPEN_NO_REASON, "s",
                                        FmtData.resource );
                return;
            }
            len = QFileSize( file );
            if( len + sizeof(lmf_resource) > QNX_MAX_REC_SIZE ) {
                LnkMsg( WRN+MSG_RESOURCE_TOO_BIG, "s", FmtData.resource );
                return;
            }
            _ChkAlloc( buf, len );
            rec.data_nbytes = len + sizeof( lmf_resource );
            WriteLoad( &rec, sizeof( lmf_record ) );
            WriteLoad( &resource, sizeof( lmf_resource ) );
            QRead( file, buf, len, FmtData.resource );
            WriteLoad( buf, len );
            _LnkFree( buf );
            QClose( file, FmtData.resource );
        } else {
            len = strlen( FmtData.resource );
            FmtData.resource[len] = '\n';
            len++;
            rec.data_nbytes = len + sizeof( lmf_resource );
            WriteLoad( &rec, sizeof( lmf_record ) );
            WriteLoad( &resource, sizeof( lmf_resource ) );
            WriteLoad( FmtData.resource, len );
        }
    }
}
示例#14
0
static unsigned_32 WriteNovImports( fixed_header *header )
/********************************************************/
{
    nov_import *    import;
    unsigned_32     count;
    char *          name;
    unsigned_8      namelen;
    unsigned_32     wrote;
    unsigned_32     refs;
    virt_mem *      vmem_array;
    symbol *        sym;

    wrote = count = 0;
    for( sym = HeadSym; sym != NULL; sym = sym->link ) {
        if( !( IS_SYM_IMPORTED( sym ) ) )
            continue;
        /* so SymFini doesn't try to free it */
        if( sym->p.import == DUMMY_IMPORT_PTR )
            sym->p.import = NULL;
        import = sym->p.import;

        if( import != NULL ) {
            count++;
            name = sym->name;
            namelen = strlen( name );

            /*
            // netware prefix support
            */
            if( sym->prefix ) {
                namelen += ( strlen( sym->prefix ) + 1);
                WriteLoad( &namelen, sizeof( unsigned_8 ) );
                WriteLoad( sym->prefix, strlen( sym->prefix ) );
                WriteLoad( "@", 1 );
                WriteLoad( name, strlen( sym->name ) );
            } else {
                WriteLoad( &namelen, sizeof( unsigned_8 ) );
                WriteLoad( name, namelen );
            }

            wrote += namelen + sizeof( unsigned_8 ) + sizeof( unsigned_32 );
            if( import->contents <= MAX_IMP_INTERNAL ) {
                refs = import->contents;
                WriteLoad( &refs, sizeof( unsigned_32 ) );
                refs *= sizeof( unsigned_32 );
                WriteLoad( &import->num_relocs, refs );
            } else {        // imports are in virtual memory.
                refs = import->num_relocs;
                WriteLoad( &refs, sizeof( unsigned_32 ) );
                vmem_array = import->vm_ptr;
                for( ; refs > IMP_NUM_VIRT; refs -= IMP_NUM_VIRT ) {
                    WriteInfoLoad( *vmem_array, IMP_VIRT_ALLOC_SIZE );
                    vmem_array++;
                }
                WriteInfoLoad( *vmem_array, refs * sizeof( unsigned_32 ) );
                refs = import->num_relocs * sizeof( unsigned_32 );
            }
            wrote += refs;
        }
    }
    header->numberOfExternalReferences = count;
    return( wrote );
}
示例#15
0
WResFileSSize  res_write( WResFileID fid, const void *buf, WResFileSize len )
{
    fid = fid;
    WriteLoad( buf, len );
    return( len );
}
示例#16
0
void FiniQNXLoadFile( void )
/*********************************/
{
    unsigned_32 *   segments;
    unsigned_16     nbytes;
    lmf_record      record;
    lmf_header      header;
    lmf_eof         trailer;
    unsigned        adseg;

    CurrSect = Root;
    if( FmtData.type & MK_QNX_FLAT ) {
        if( FmtData.base < StackSize ) {
            LnkMsg( WRN+MSG_QNX_BASE_LT_STACK, NULL );
        }
    }
    nbytes = NumGroups * sizeof( unsigned_32 );
    segments = (unsigned_32 *) alloca( nbytes );
    SeekLoad( sizeof(lmf_header) + nbytes + sizeof(lmf_record) );
    WriteQNXResource();
    WriteQNXData( segments );
    WriteQNXRelocs( Root->reloclist, LMF_FIXUP_REC, 0 );
    WriteQNXRelocs( FloatFixups, LMF_8087_FIXUP_REC, 0 );
    record.reserved = record.spare = 0;
    record.rec_type = LMF_IMAGE_END_REC;
    record.data_nbytes = sizeof( trailer );
    WriteLoad( &record, sizeof( lmf_record ) );
    memset( &trailer, 0, sizeof( trailer ) );
    WriteLoad( &trailer, sizeof( trailer ) );
    DBIWrite();

    SeekLoad( 0 );
    record.rec_type = LMF_HEADER_REC;
    record.data_nbytes = sizeof( lmf_header ) + nbytes;
    WriteLoad( &record, sizeof( lmf_record ) );
    memset( &header, 0, sizeof( header ) );
    header.version = QNX_VERSION;
    header.cflags = (FmtData.u.qnx.flags | (FmtData.u.qnx.priv_level << QNX_PRIV_SHIFT)) & QNX_FLAG_MASK;
    if( LinkState & FMT_SEEN_32_BIT ) {
        header.cflags |= _TCF_32BIT;
    }
    if( FmtData.type & MK_QNX_FLAT ) {
        header.cflags |= _TCF_FLAT;
    }
    header.fpu = 0;     //NYI: need to set 87, 287, 387
    if( FmtData.cpu_type == 0 ) {        // no model specified, so assume...
        if( LinkState & FMT_SEEN_32_BIT ) {
            header.cpu = 386;
        } else {
            header.cpu = 86;
        }
    } else {
        header.cpu = (FmtData.cpu_type * 100) + 86;
    }
    header.code_index = QNX_SEL_NUM( StartInfo.addr.seg );
    header.stack_index = QNX_SEL_NUM( StackAddr.seg );
    adseg = header.stack_index;
    if( DataGroup != NULL ) {
        adseg = QNX_SEL_NUM( DataGroup->grp_addr.seg );
    }
    header.heap_index = adseg;  // all in DGROUP.
    header.argv_index = adseg;
    header.code_offset = StartInfo.addr.off;
    header.stack_nbytes = StackSize;
    header.heap_nbytes = FmtData.u.qnx.heapsize;
    header.image_base = FmtData.base;
    WriteLoad( &header, sizeof( lmf_header ) );
    WriteLoad( segments, nbytes );
}