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 ); }
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 ) ); }
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 ); }
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 ); }
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 ) ); }
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 ); }
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) ); } }
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. } }
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 ); }
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 ) ); }
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 ) ); }
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 ) ); }
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 ); } } }
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 ); }
WResFileSSize res_write( WResFileID fid, const void *buf, WResFileSize len ) { fid = fid; WriteLoad( buf, len ); return( len ); }
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 ); }