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 ); } } }
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 ); }
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 ); }
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 ); }
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 ); }
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; } }
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 (); }
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 ); }
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 (); }
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 (); }