⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 exelxobj.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*
*                            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 + -