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

📄 exeseg.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
        }
        if (!error) {
            align_amount = AlignAmount( out_offset, new_shift_count );
            iorc = RcSeek( outexe->Handle, align_amount, SEEK_CUR );
            if( iorc == -1 ) {
                error = TRUE;
                RcError( ERR_WRITTING_FILE, outexe->name, strerror( errno ) );
            }
            out_offset += align_amount;
        }

        /* move in the in file to the start of the segment */
        if (!error) {
            /* convert the address to a long before shifting it */
            iorc = RcSeek( inexe->Handle,
                        (long) inseg->address << old_shift_count, SEEK_SET );
            if( iorc == -1 ) {
                error = TRUE;
                RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
            }
        }

        if (!error) {
            if (inseg->size == 0) {
                seg_len = 0x10000L;
            } else {
                seg_len = inseg->size;
            }
            error = myCopyExeData( inexe, outexe, seg_len );
        }

        if (inseg->info & SEG_RELOC && !error) {
            /* read the number of relocation items */
            iorc = RcRead( inexe->Handle, &numrelocs, sizeof(uint_16) );
            if( iorc != sizeof( uint_16 ) ) {
                error = TRUE;
                if( iorc == -1 ) {
                    RcError( ERR_READING_EXE, inexe->name, strerror( errno ) );
                } else {
                    RcError( ERR_UNEXPECTED_EOF, inexe->name );
                }
            } else {
                iorc = RcWrite( outexe->Handle, &numrelocs, sizeof(uint_16) );
                if( iorc != sizeof( uint_16 ) ) {
                    error = TRUE;
                    RcError( ERR_WRITTING_FILE, outexe->name,
                                strerror( errno ) );
                }
            }
            /* copy the relocation information */
            if (!error) {
                error = myCopyExeData( inexe, outexe,
                            numrelocs * OS_RELOC_ITEM_SIZE );
            }
            if (numrelocs * OS_RELOC_ITEM_SIZE + seg_len > 0x10000L) {
                ret = CPSEG_SEG_TOO_BIG;
            }
        }

        if (pad_end && ret != CPSEG_SEG_TOO_BIG && !error) {
            align_amount = AlignAmount( RcTell( outexe->Handle ),
                                        new_shift_count );
            /* make sure there is room for the memory arena header */
            if (align_amount < 16) {
                align_amount += 16;
            }
            iorc = RcSeek( outexe->Handle, align_amount - 1, SEEK_CUR );
            if( iorc == -1 ) {
                error = TRUE;
                RcError( ERR_WRITTING_FILE, outexe->name );
            } else {
                /* write something out so if we have just seeked past the
                 * end of the file the file's size will be adjusted
                 * appropriately */
                iorc = RcWrite( outexe->Handle, &dum, 1 );
                if( iorc != 1 ) {
                    error = TRUE;
                    RcError( ERR_WRITTING_FILE, outexe->name );
                }
            }
        }
    } else {
        out_offset = 0;
    }

    /* copy the segment record to outseg */
    if (!error) {
        outseg->size = inseg->size;
        outseg->info = inseg->info;
        outseg->min = inseg->min;
        outseg->address = out_offset >> new_shift_count;
    }

    if (error) {
        ret = CPSEG_ERROR;
    }

    return( ret );
} /* copyOneSegment */


extern CpSegRc CopySegments( uint_16 sect2mask, uint_16 sect2bits, bool sect2 )
/*****************************************************************************/
/* Note: sect2 must be either 1 (do section 2) or 0 (do section 1) */
/* CopySegments should be called twice, once with sect2 false, and once with */
/* it true. The values of sect2mask and sect2bits should be the same for both */
/* calls. The segment table for the temporary file will not be properly */
/* filled in until after the second call */
{
    segment_record *    oldseg;
    segment_record *    tmpseg;
    bool                padend;
    int                 num_segs;
    ExeFileInfo         *old_exe_info;
    ExeFileInfo         *tmp_exe_info;
    int                 old_shift_count;
    int                 new_shift_count;
    int                 currseg;
    CpSegRc             cponeret;
    CpSegRc             ret;

    oldseg = Pass2Info.OldFile.u.NEInfo.Seg.Segments;
    tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments;
    num_segs = Pass2Info.OldFile.u.NEInfo.Seg.NumSegs;
    old_exe_info = &Pass2Info.OldFile;
    tmp_exe_info = &Pass2Info.TmpFile;
    old_shift_count = Pass2Info.OldFile.u.NEInfo.WinHead.align;
    new_shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align;

    ret = CPSEG_OK;
    cponeret = CPSEG_OK;
    padend = !sect2;

    currseg = 0;
    while (currseg < num_segs) {
        /* if the bits are unequal and this is section 1 --> copy segment */
        /* if the bits are equal and this is section 2   --> copy segment */
        /* otherwise                                     --> do nothing */
        if (ARE_BITS_EQUAL( sect2mask, sect2bits, oldseg->info ) == sect2) {
            cponeret = copyOneSegment( oldseg, tmpseg, old_exe_info,
                                        tmp_exe_info, old_shift_count,
                                        new_shift_count, padend );
            if (cponeret == CPSEG_SEG_TOO_BIG) {
                padend = FALSE;
                ret = CPSEG_SEG_TOO_BIG;
            }
            CheckDebugOffset( &(Pass2Info.OldFile) );
            CheckDebugOffset( &(Pass2Info.TmpFile) );
        }
        if (cponeret == CPSEG_ERROR) break;
        /* mark section 1 segments as preload */
        if (!sect2) {
            tmpseg->info |= SEG_PRELOAD;
        }
        currseg++;
        oldseg++;
        tmpseg++;
    }

    if (cponeret == CPSEG_ERROR) {
        ret = CPSEG_ERROR;
        Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs = 0;
    } else {
        Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs =
                        Pass2Info.OldFile.u.NEInfo.Seg.NumSegs;
    }

    return( ret );

} /* CopySegments */

extern CpSegRc CopyOS2Segments( void )
/*************************************
 * Akin to CopySegments() only much, much simpler - just copies all segments
 * without messing with them in any way. Only called once. Won't copy
 * resource segments.
 */
{
    segment_record      *oldseg;
    segment_record      *tmpseg;
    int                 num_segs;
    SegTable            *old_seg_tbl;
    ExeFileInfo         *old_exe_info;
    ExeFileInfo         *tmp_exe_info;
    int                 old_shift_count;
    int                 new_shift_count;
    int                 currseg;
    CpSegRc             cponeret;
    CpSegRc             ret;

    old_seg_tbl = &Pass2Info.TmpFile.u.NEInfo.Seg;
    oldseg = old_seg_tbl->Segments;
    tmpseg = Pass2Info.TmpFile.u.NEInfo.Seg.Segments;
    num_segs = old_seg_tbl->NumSegs - old_seg_tbl->NumOS2ResSegs;
    old_exe_info = &Pass2Info.OldFile;
    tmp_exe_info = &Pass2Info.TmpFile;
    old_shift_count = Pass2Info.OldFile.u.NEInfo.WinHead.align;
    new_shift_count = Pass2Info.TmpFile.u.NEInfo.WinHead.align;

    ret = CPSEG_OK;
    cponeret = CPSEG_OK;

    currseg = 0;
    while( currseg < num_segs ) {
        cponeret = copyOneSegment( oldseg, tmpseg, old_exe_info,
                                    tmp_exe_info, old_shift_count,
                                    new_shift_count, FALSE );
        if( cponeret == CPSEG_SEG_TOO_BIG ) {
            ret = CPSEG_SEG_TOO_BIG;
        }
        CheckDebugOffset( &(Pass2Info.OldFile) );
        CheckDebugOffset( &(Pass2Info.TmpFile) );
        if( cponeret == CPSEG_ERROR ) {
            break;
        }
        currseg++;
        oldseg++;
        tmpseg++;
    }

    if( cponeret == CPSEG_ERROR ) {
        ret = CPSEG_ERROR;
        Pass2Info.TmpFile.u.NEInfo.Seg.NumSegs = 0;
    } else if( old_seg_tbl->NumOS2ResSegs ) {
        uint_32     end_offset;
        int         iorc;

        /* Must seek past the last segment in old file */
        oldseg += old_seg_tbl->NumOS2ResSegs - 1;
        end_offset = (uint_32)oldseg->address << old_shift_count;
        if( oldseg->size == 0 )
            end_offset += 0x10000;
        else
            end_offset += oldseg->size;

        iorc = RcSeek( old_exe_info->Handle, end_offset, SEEK_SET );
        if( iorc == -1 ) {
            ret = CPSEG_ERROR;
            RcError( ERR_READING_EXE, old_exe_info->name, strerror( errno ) );
        }
        CheckDebugOffset( &(Pass2Info.OldFile) );
    }

    return( ret );
} /* CopyOS2Segments */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -