📄 exeseg.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: NE segment processing functions.
*
****************************************************************************/
#include <unistd.h>
#include <string.h>
#include "watcom.h"
#include "exeos2.h"
#include "rcmem.h"
#include "global.h"
#include "errors.h"
#include "pass2.h"
#include "exeutil.h"
#include "exeseg.h"
#include "iortns.h"
static RcStatus allocSegTable( SegTable *seg, int *err_code )
{
int tablesize;
tablesize = seg->NumSegs * sizeof(segment_record);
seg->Segments = RcMemMalloc( tablesize );
if( seg->Segments == NULL ) {
*err_code = errno;
return( RS_NO_MEM );
} else {
return( RS_OK );
}
} /* allocSegTable */
/*
* readSegTable
* NB when an error occurs this function must return without altering errno
*/
static RcStatus readSegTable( int handle, uint_32 offset, SegTable * seg )
{
int tablesize;
int numread;
long seek_rc;
tablesize = seg->NumSegs * sizeof(segment_record);
seek_rc = RcSeek( handle, offset, SEEK_SET );
if( seek_rc == -1 ) return( RS_READ_ERROR );
numread = RcRead( handle, seg->Segments, tablesize );
if( numread != tablesize ) {
if( numread == -1 ) {
return( RS_READ_ERROR );
} else {
return( RS_READ_INCMPLT );
}
}
return( RS_OK );
} /* readSegTable */
extern int AllocAndReadSegTables( int *err_code )
{
int error;
int oldhandle;
uint_32 head_offset;
SegTable *oldseg;
SegTable *tmpseg;
os2_exe_header *head;
oldseg = &(Pass2Info.OldFile.u.NEInfo.Seg);
oldhandle = Pass2Info.OldFile.Handle;
tmpseg = &(Pass2Info.TmpFile.u.NEInfo.Seg);
head = &(Pass2Info.OldFile.u.NEInfo.WinHead);
head_offset = Pass2Info.OldFile.WinHeadOffset;
oldseg->NumSegs = head->segments;
tmpseg->NumSegs = head->segments;
error = allocSegTable( oldseg, err_code );
if( error != RS_OK ) return( error );
error = allocSegTable( tmpseg, err_code );
if( error != RS_OK ) return( error );
error = readSegTable( oldhandle, head_offset + head->segment_off,
oldseg );
if( error != RS_OK ){
*err_code = errno;
return( error );
}
error = readSegTable( oldhandle, head_offset + head->segment_off,
tmpseg );
*err_code = errno;
return( error );
} /* AllocAndReadSegTables */
extern int AllocAndReadOS2SegTables( int *err_code )
{
int error;
int oldhandle;
int oldres;
int newres;
uint_32 head_offset;
SegTable *oldseg;
SegTable *tmpseg;
os2_exe_header *head;
oldres = Pass2Info.OldFile.u.NEInfo.WinHead.resource;
oldseg = &(Pass2Info.OldFile.u.NEInfo.Seg);
oldhandle = Pass2Info.OldFile.Handle;
tmpseg = &(Pass2Info.TmpFile.u.NEInfo.Seg);
newres = ComputeOS2ResSegCount( Pass2Info.ResFiles->Dir );
head = &(Pass2Info.OldFile.u.NEInfo.WinHead);
head_offset = Pass2Info.OldFile.WinHeadOffset;
if( (int_32)head->segments - oldres < 0 )
return( RS_BAD_FILE_FMT );
oldseg->NumSegs = head->segments;
tmpseg->NumSegs = oldseg->NumSegs - oldres + newres;
oldseg->NumOS2ResSegs = oldres;
tmpseg->NumOS2ResSegs = newres;
error = allocSegTable( oldseg, err_code );
if( error != RS_OK )
return( error );
error = allocSegTable( tmpseg, err_code );
if( error != RS_OK )
return( error );
error = readSegTable( oldhandle, head_offset + head->segment_off, oldseg );
if( error != RS_OK ) {
*err_code = errno;
return( error );
}
error = readSegTable( oldhandle, head_offset + head->segment_off, tmpseg );
*err_code = errno;
return( error );
} /* AllocAndReadOS2SegTables */
/********* WARNING *********/
/* Hard coded constant. The value of sizeof(os2_reloc_item) is to hard */
/* to get from wl because of the other files that would have to be included */
/* in order to get that structure */
#define OS_RELOC_ITEM_SIZE 8
extern uint_32 ComputeSegmentSize( int handle, SegTable * segs,
int shift_count )
{
segment_record * currseg;
segment_record * afterlast;
uint_32 length;
uint_32 io_rc;
uint_16 num_relocs;
length = 0;
for (currseg = segs->Segments, afterlast = segs->Segments + segs->NumSegs;
currseg < afterlast; currseg++) {
length += currseg->size;
if (currseg->info & SEG_RELOC) {
io_rc = RcSeek( handle, (((long) currseg->address) << (long) shift_count) +
currseg->size, SEEK_SET );
if (io_rc == -1) return( 0 );
io_rc = RcRead( handle, &num_relocs, sizeof(uint_16) );
if (io_rc != sizeof(uint_16)) return( 0 );
length += (unsigned_32) num_relocs * (unsigned_32) OS_RELOC_ITEM_SIZE;
}
}
return( length );
} /* ComputeSegmentSize */
static int myCopyExeData( ExeFileInfo *inexe, ExeFileInfo *outexe,
uint_32 length )
{
switch( CopyExeData( inexe->Handle, outexe->Handle, length ) ) {
case RS_OK:
case RS_PARAM_ERROR:
return( FALSE );
case RS_READ_ERROR:
RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
break;
case RS_READ_INCMPLT:
RcError( ERR_UNEXPECTED_EOF, inexe->name );
break;
case RS_WRITE_ERROR:
RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
break;
default:
RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
break;
}
return( TRUE );
}
static CpSegRc copyOneSegment( const segment_record * inseg,
segment_record * outseg, ExeFileInfo *inexe, ExeFileInfo *outexe,
int old_shift_count, int new_shift_count, bool pad_end )
{
CpSegRc ret;
int error;
int iorc;
uint_16 numrelocs;
uint_32 out_offset;
uint_32 align_amount;
uint_32 seg_len = 0L;
char dum;
dum = 0;
error = FALSE;
ret = CPSEG_OK;
/* check if this is a segment that has no image in the exe file */
if (inseg->address != 0) {
/* align in the out file so that shift_count will be valid */
out_offset = RcTell( outexe->Handle );
if( out_offset == -1 ) {
error = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -