📄 exelxobj.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: LX objects and object table manipulation routines.
*
****************************************************************************/
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "watcom.h"
#include "exepe.h"
#include "rcmem.h"
#include "errors.h"
#include "pass2.h"
#include "exeutil.h"
#include "global.h"
#include "exeobj.h"
#include "iortns.h"
static int readObjectAndPageTable( ExeFileInfo *exe )
/***************************************************/
{
RcStatus error;
size_t table_size;
table_size = exe->u.LXInfo.OS2Head.num_objects * sizeof( object_record );
exe->u.LXInfo.Objects = RcMemMalloc( table_size );
error = SeekRead( exe->Handle,
exe->WinHeadOffset + exe->u.LXInfo.OS2Head.objtab_off,
exe->u.LXInfo.Objects, table_size );
if( error == RS_OK ) {
table_size = exe->u.LXInfo.OS2Head.num_pages * sizeof( lx_map_entry );
exe->u.LXInfo.Pages = RcMemMalloc( table_size );
error = SeekRead( exe->Handle,
exe->WinHeadOffset + exe->u.LXInfo.OS2Head.objmap_off,
exe->u.LXInfo.Pages, table_size );
}
switch( error ) {
case RS_OK:
break;
case RS_READ_ERROR:
RcError( ERR_READING_EXE, exe->name, strerror( errno ) );
break;
case RS_READ_INCMPLT:
RcError( ERR_UNEXPECTED_EOF, exe->name );
break;
default:
RcError( ERR_INTERNAL, INTERR_UNKNOWN_RCSTATUS );
break;
}
CheckDebugOffset( exe );
return( error != RS_OK );
}
static int copyObjectAndPageTable( ExeFileInfo *old, ExeFileInfo *new )
/*********************************************************************/
/* Copies the object/page table from old to new sans resource objects */
{
uint_32 old_obj_size;
uint_32 new_obj_size;
uint_32 old_page_size;
uint_32 new_page_size;
uint_32 align;
int_32 new_off;
object_record *old_obj;
object_record *new_obj;
lx_map_entry *old_page;
lx_map_entry *new_page;
int obj_index;
int old_obj_index;
int old_num_objects;
int page_index;
int old_num_pages;
int i;
old_obj = old->u.LXInfo.Objects;
old_page = old->u.LXInfo.Pages;
old_num_objects = old_num_pages = 0;
/* Figure out number of old objects/pages */
for( obj_index = 0; obj_index < old->u.LXInfo.OS2Head.num_objects; obj_index++ ) {
/* Simply skip any existing resource objects */
if( !(old_obj[ obj_index ].flags & OBJ_RESOURCE) ) {
++old_num_objects;
old_num_pages += old_obj[ obj_index ].mapsize;
}
}
if( CmdLineParms.NoResFile ) {
new->u.LXInfo.OS2Head.num_objects = old_num_objects;
new->u.LXInfo.OS2Head.num_pages = old_num_pages;
} else {
new->u.LXInfo.OS2Head.num_objects = old_num_objects
+ new->u.LXInfo.Res.num_objects;
new->u.LXInfo.OS2Head.num_pages = old_num_pages
+ new->u.LXInfo.Res.num_pages;
}
new_obj_size = new->u.LXInfo.OS2Head.num_objects * sizeof( object_record );
old_obj_size = old->u.LXInfo.OS2Head.num_objects * sizeof( object_record );
new_page_size = new->u.LXInfo.OS2Head.num_pages * sizeof( lx_map_entry );
old_page_size = old->u.LXInfo.OS2Head.num_pages * sizeof( lx_map_entry );
/* Calculate new offset of data pages */
new_off = new_obj_size + new_page_size - old_obj_size - old_page_size
+ new->u.LXInfo.OS2Head.num_rsrcs * sizeof( flat_res_table )
- old->u.LXInfo.OS2Head.num_rsrcs * sizeof( flat_res_table )
+ new->u.LXInfo.OS2Head.num_pages * sizeof( uint_32 )
- old->u.LXInfo.OS2Head.num_pages * sizeof( uint_32 );
new_off += old->u.LXInfo.OS2Head.page_off;
align = 1 << old->u.LXInfo.OS2Head.l.page_shift;
new_off = (new_off + align - 1) & ~(align - 1);
new->u.LXInfo.OS2Head.page_off = new_off;
/* Allocate new object/page table */
new_obj = RcMemMalloc( new_obj_size );
new_page = RcMemMalloc( new_page_size );
new->u.LXInfo.Objects = new_obj;
new->u.LXInfo.Pages = new_page;
old_obj_index = page_index = 0;
/* Copy object and page records from old executable to new */
for( obj_index = 0; obj_index < old->u.LXInfo.OS2Head.num_objects; obj_index++ ) {
if( !(old_obj[ obj_index ].flags & OBJ_RESOURCE) ) {
new_obj[ obj_index ] = old_obj[ old_obj_index ];
new_obj[ obj_index ].mapidx = page_index + 1;
for( i = 0; i < old_obj[ old_obj_index ].mapsize; ++i ) {
new_page[ page_index ] = old_page[ old_obj[ old_obj_index ].mapidx + i - 1 ];
++page_index;
}
++old_obj_index;
}
}
/* Mark the start of resource objects/pages */
new->u.LXInfo.FirstResObj = old_obj_index;
new->u.LXInfo.FirstResPage = page_index;
return( old_num_objects );
}
/*
* copyOneObject
* if an error occurs this function MUST return without altering errno
*/
static RcStatus copyOneObject( ExeFileInfo *old, object_record *old_obj,
ExeFileInfo *new, object_record *new_obj )
/***********************************************************************/
{
int seek_rc;
int copy_rc;
lx_map_entry *old_map;
lx_map_entry *new_map;
uint_32 old_offset;
uint_32 new_offset;
int i;
for( i = 0; i < old_obj->mapsize; ++i ) {
old_map = &old->u.LXInfo.Pages[ old_obj->mapidx + i - 1 ];
new_map = &new->u.LXInfo.Pages[ new_obj->mapidx + i - 1 ];
// NB - page_offset is relative to start of executable, not to LX header!
old_offset = (old_map->page_offset << old->u.LXInfo.OS2Head.l.page_shift)
+ old->u.LXInfo.OS2Head.page_off;
new_offset = (new_map->page_offset << new->u.LXInfo.OS2Head.l.page_shift)
+ new->u.LXInfo.OS2Head.page_off;
seek_rc = RcSeek( old->Handle, old_offset, SEEK_SET );
if( seek_rc == -1 )
return( RS_READ_ERROR );
seek_rc = RcSeek( new->Handle, new_offset, SEEK_SET );
if( seek_rc == -1 )
return( RS_WRITE_ERROR );
copy_rc = CopyExeData( old->Handle, new->Handle, old_map->data_size );
if( copy_rc != RS_OK )
return( copy_rc );
}
return( RS_OK );
}
/*
* copyHeaderSections
* if an error occurs this function MUST return without altering errno
*/
static int copyHeaderSections( ExeFileInfo *old, ExeFileInfo *new )
/*****************************************************************/
/* Copies parts of header and loader/fixup sections that won't be changing */
{
int seek_rc;
int ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -