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

📄 exeseg.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:  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 + -