📄 pass2.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Resource Compiler pass 2.
*
****************************************************************************/
#include <unistd.h>
#include <string.h>
#include "watcom.h"
#include "exeos2.h"
#include "global.h"
#include "errors.h"
#include "rcmem.h"
#include "rcstr.h"
#include "exeseg.h"
#include "exeres.h"
#include "exeobj.h"
#include "exelxobj.h"
#include "exerespe.h"
#include "exereslx.h"
#include "exeutil.h"
#include "pass2.h"
#include "iortns.h"
/*
* copyStubFile - copy from the begining of the file to the start of
* the win exe header
*/
static int copyStubFile( int *err_code )
{
RcStatus error;
error = CopyExeData( Pass2Info.OldFile.Handle, Pass2Info.TmpFile.Handle,
Pass2Info.OldFile.WinHeadOffset );
*err_code = errno;
return( error );
} /* copyStubFile */
static RcStatus seekPastResTable( int *err_code )
{
int winheadoffset;
int seekamount;
ExeFileInfo *tmpexe;
uint_16 res_tbl_size;
tmpexe = &(Pass2Info.TmpFile);
if( Pass2Info.OldFile.u.NEInfo.WinHead.target == TARGET_OS2 )
res_tbl_size = tmpexe->u.NEInfo.OS2Res.table_size;
else
res_tbl_size = tmpexe->u.NEInfo.Res.Dir.TableSize;
seekamount = sizeof(os2_exe_header) +
tmpexe->u.NEInfo.Seg.NumSegs * sizeof(segment_record) +
res_tbl_size +
tmpexe->u.NEInfo.Res.Str.StringBlockSize;
winheadoffset = RcSeek( tmpexe->Handle, seekamount, SEEK_CUR );
if( winheadoffset == -1 ) {
*err_code = errno;
return( RS_READ_ERROR );
} else {
tmpexe->WinHeadOffset = winheadoffset;
return( RS_OK );
}
} /* seekPastResTable */
static int copyOtherTables( int *err_code )
{
int tablelen;
os2_exe_header * oldhead;
uint_32 oldoffset;
int oldhdl;
int seek_rc;
RcStatus ret;
oldhead = &(Pass2Info.OldFile.u.NEInfo.WinHead);
oldoffset = Pass2Info.OldFile.WinHeadOffset;
oldhdl = Pass2Info.OldFile.Handle;
/* the other tables start at the resident names table and end at the end */
/* of the non-resident names table */
tablelen = (oldhead->nonres_off + oldhead->nonres_size) -
(oldhead->resident_off + oldoffset);
seek_rc = RcSeek( oldhdl, oldhead->resident_off + oldoffset, SEEK_SET );
if( seek_rc == -1) {
*err_code = errno;
return( RS_READ_ERROR );
}
ret = CopyExeData( Pass2Info.OldFile.Handle, Pass2Info.TmpFile.Handle,
tablelen );
*err_code = errno;
return( ret );
} /* copyOtherTables */
static int computeShiftCount( void )
{
NEExeInfo * old;
NEExeInfo * tmp;
uint_32 filelen;
int num_segs;
int shift_count;
old = &Pass2Info.OldFile.u.NEInfo;
tmp = &Pass2Info.TmpFile.u.NEInfo;
filelen = old->WinHead.nonres_off +
old->WinHead.nonres_size +
tmp->Res.Dir.TableSize +
tmp->Res.Str.StringBlockSize;
filelen += ComputeSegmentSize( Pass2Info.OldFile.Handle,
&(tmp->Seg), old->WinHead.align );
if( ! CmdLineParms.NoResFile ) {
filelen += ComputeResourceSize( Pass2Info.ResFiles->Dir );
}
num_segs = old->WinHead.segments;
if( ! CmdLineParms.NoResFile ) {
num_segs += WResGetNumResources( Pass2Info.ResFiles->Dir );
}
shift_count = FindShiftCount( filelen, num_segs );
if( shift_count == 0 ) {
shift_count = 1; /* MS thinks 0 == 9 for shift count */
}
if( shift_count > old->WinHead.align ) {
return( shift_count );
} else {
return( old->WinHead.align );
}
} /* computeShiftCount */
static void checkShiftCount( void )
{
Pass2Info.TmpFile.u.NEInfo.WinHead.align = computeShiftCount();
Pass2Info.TmpFile.u.NEInfo.Res.Dir.ResShiftCount =
Pass2Info.TmpFile.u.NEInfo.WinHead.align;
} /* checkShiftCount */
static int copyBody( void )
{
NEExeInfo * tmp;
uint_16 sect2mask = 0;
uint_16 sect2bits = 0;
uint_16 shift_count;
uint_32 gangloadstart;
uint_32 gangloadlen;
CpSegRc copy_segs_ret;
bool use_gangload = FALSE;
int error;
tmp = &Pass2Info.TmpFile.u.NEInfo;
switch (CmdLineParms.SegmentSorting) {
case SEG_SORT_NONE: /* all segments in section 2 */
sect2mask = 0;
sect2bits = 0;
use_gangload = FALSE;
Pass2Info.TmpFile.u.NEInfo.WinHead.align =
Pass2Info.OldFile.u.NEInfo.WinHead.align;
tmp->Res.Dir.ResShiftCount = computeShiftCount();
break;
case SEG_SORT_PRELOAD_ONLY: /* all load on call segments in section 2 */
sect2mask = SEG_PRELOAD;
sect2bits = 0;
use_gangload = TRUE;
checkShiftCount();
break;
case SEG_SORT_MANY: /* only load on call, discardable, code segments */
/* in section 2 */
sect2mask = SEG_DATA | SEG_PRELOAD | SEG_DISCARD;
sect2bits = SEG_DISCARD;
/* set the entry segment to be preload */
{
segment_record * seg; /* these two are here because a */
uint_16 entry_seg; /* 71 character field reference */
/* is hard to read */
seg = Pass2Info.OldFile.u.NEInfo.Seg.Segments;
entry_seg = Pass2Info.OldFile.u.NEInfo.WinHead.entrynum;
seg[ entry_seg ].info |= SEG_PRELOAD;
}
use_gangload = TRUE;
checkShiftCount();
break;
default:
break;
}
/* third arg to Copy???? is FALSE --> copy section one */
gangloadstart = RcTell( Pass2Info.TmpFile.Handle );
gangloadstart += AlignAmount( gangloadstart, tmp->Res.Dir.ResShiftCount );
copy_segs_ret = CopySegments( sect2mask, sect2bits, FALSE );
switch (copy_segs_ret) {
case CPSEG_SEG_TOO_BIG:
if( use_gangload ) {
RcWarning( ERR_NO_GANGLOAD );
use_gangload = FALSE;
}
break;
case CPSEG_ERROR:
return( TRUE );
case CPSEG_OK:
default:
break;
}
if( ! CmdLineParms.NoResFile ) {
error = CopyResources( sect2mask, sect2bits, FALSE );
if( error) return( TRUE );
}
gangloadlen = RcTell( Pass2Info.TmpFile.Handle ) - gangloadstart;
/* third arg to Copy???? is TRUE --> copy section two */
copy_segs_ret = CopySegments( sect2mask, sect2bits, TRUE );
if( copy_segs_ret == CPSEG_ERROR) {
return( TRUE );
}
if( !CmdLineParms.NoResFile ) {
error = CopyResources( sect2mask, sect2bits, TRUE );
if( error) return( TRUE );
}
if( use_gangload ) {
shift_count = tmp->WinHead.align;
tmp->WinHead.gangstart = gangloadstart >> shift_count;
tmp->WinHead.ganglength = gangloadlen >> shift_count;
tmp->WinHead.otherflags |= WIN_GANGLOAD_PRESENT;
} else {
tmp->WinHead.gangstart = 0;
tmp->WinHead.ganglength = 0;
tmp->WinHead.otherflags &= ~WIN_GANGLOAD_PRESENT;
}
return( FALSE );
} /* copyBody */
static int copyOS2Body( void )
{
NEExeInfo *tmp;
CpSegRc copy_segs_ret;
int error;
unsigned_16 align;
tmp = &Pass2Info.TmpFile.u.NEInfo;
/* OS/2 does not use separate alignment for resources */
align = Pass2Info.OldFile.u.NEInfo.WinHead.align;
Pass2Info.TmpFile.u.NEInfo.WinHead.align = align;
tmp->Res.Dir.ResShiftCount = align;
copy_segs_ret = CopyOS2Segments();
if( copy_segs_ret == CPSEG_ERROR ) {
return( TRUE );
}
if( !CmdLineParms.NoResFile ) {
error = CopyOS2Resources();
if( error )
return( TRUE );
}
return( FALSE );
} /* copyOS2Body */
/*
* copyDebugInfo
* NB when an error occurs this function must return without altering errno
*/
static RcStatus copyDebugInfo( void )
{
long seek_rc;
ExeFileInfo * old;
ExeFileInfo * tmp;
old = &(Pass2Info.OldFile);
tmp = &(Pass2Info.TmpFile);
seek_rc = RcSeek( old->Handle, old->DebugOffset, SEEK_SET );
if( seek_rc == -1) return( RS_READ_ERROR );
seek_rc = RcSeek( tmp->Handle, tmp->DebugOffset, SEEK_SET );
if( seek_rc == -1) return( RS_WRITE_ERROR );
return( CopyExeDataTilEOF( old->Handle, tmp->Handle ) );
} /* copyDebugInfo */
static int writeHeadAndTables( int *err_code )
{
ExeFileInfo * oldfile;
ExeFileInfo * tmpfile;
NEExeInfo * oldne;
NEExeInfo * tmpne;
uint_16 tableshift; /* amount the tables are shifted in the */
/* tmp file */
uint_16 info; /* os2_exe_header.info */
long seekrc;
int numwrote;
int error;
oldfile = &(Pass2Info.OldFile);
oldne = &oldfile->u.NEInfo;
tmpfile = &(Pass2Info.TmpFile);
tmpne = &tmpfile->u.NEInfo;
/* set the info flag for the new executable from the one flag and */
/* the command line options given */
info = oldne->WinHead.info;
if( CmdLineParms.PrivateDLL ) {
info |= WIN_PRIVATE_DLL;
}
if( CmdLineParms.GlobalMemEMS ) {
info |= WIN_EMS_GLOBAL_MEM;
}
if( CmdLineParms.EMSInstance ) {
info |= WIN_EMS_BANK_INSTANCE;
}
if( CmdLineParms.EMSDirect ) {
info |= WIN_USES_EMS_DIRECT;
}
if( CmdLineParms.ProtModeOnly ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -