pharexe.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 405 行
C
405 行
/****************************************************************************
*
* 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: PharLap executable dumping routines.
*
****************************************************************************/
#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include "wdglb.h"
#include "wdfunc.h"
static char *phar_exe_msg[] = {
"2file size mod 512 = ",
"2file size in blocks = ",
"2number of relocation items = ",
"2size of header in paragraphs = ",
"2minimum data in 4k pages = ",
"2maximum data in 4k pages = ",
"4initial ESP = ",
"2checksum = ",
"4initial EIP = ",
"2offset of first relocation item = ",
"2overlay number = ",
"2always one = ",
NULL
};
static char *phar_ext_msg[] = {
"2file format level (1==flat, 2==multi-seg) = ",
"2header size in bytes = ",
"4file size in bytes = ",
"216-bit checksum = ",
"4offset of run-time parameter block = ",
"4size of run-time parameter block = ",
"4offset of relocation table = ",
"4size of relocation table = ",
"4offset of segment information table = ",
"4size of segment information table = ",
"2size of a seg info table entry = ",
"4offset of program load image = ",
"4size of program load image = ",
"4offset of symbol table = ",
"4size of symbol table = ",
"4offset of program GDT in load image = ",
"4size of program GDT in load image = ",
"4offset of program LDT in load image = ",
"4size of program LDT in load image = ",
"4offset of program IDT in load image = ",
"4size of program IDT in load image = ",
"4offset of program TSS in load image = ",
"4size of program TSS in load image = ",
"4minmum number of extra bytes to allocate = ",
"4maxmum number of extra bytes to allocate = ",
"4base offset of program image = ",
"4initial ESP = ",
"2initial SS = ",
"4initial EIP = ",
"2initial CS = ",
"2initial LDT = ",
"2initial TSS = ",
"2load image flags = ",
"4load image memory requirement = ",
NULL
};
static char *rtp_blk_msg[] = {
"2-MINREAL switch value = ",
"2-MAXREAL switch value = ",
"2-MINIBUF switch value = ",
"2-MAXIBUF switch value = ",
"2-NISTACK switch value = ",
"2-ISTKSIZE switch value = ",
"4-REALBREAK switch value = ",
"2-CALLBUFS switch value = ",
"2386 DOS extender flags = ",
"2unpriviledged flag = ",
NULL
};
static char *tss_msg[] = {
"2 LINK TO PREV TSS = ",
"2 zero = ",
"4 ESP0 = ",
"2 SS0 = ",
"2 zero = ",
"4 ESP1 = ",
"2 SS1 = ",
"2 zero = ",
"4 ESP2 = ",
"2 SS2 = ",
"2 zero = ",
"4 CR3 = ",
"4 EIP = ",
"4 EFLAGS = ",
"4 EAX = ",
"4 ECX = ",
"4 EDX = ",
"4 EBX = ",
"4 ESP = ",
"4 EBP = ",
"4 ESI = ",
"4 EDI = ",
"2 ES = ",
"2 zero = ",
"2 CS = ",
"2 zero = ",
"2 SS = ",
"2 zero = ",
"2 DS = ",
"2 zero = ",
"2 FS = ",
"2 zero = ",
"2 GS = ",
"2 zero = ",
"2 LDT = ",
"2 zero = ",
"2 debug trap bit = ",
"2 I/O map base = ",
NULL
};
typedef struct {
unsigned_16 seg_sel;
unsigned_16 flags;
unsigned_32 base_off;
unsigned_32 min_extra;
} seg_info_rec;
/*
* Dump the rex relocation table.
*/
static void dmp_rex_reloc( void )
/*******************************/
{
unsigned_32 offset;
unsigned_16 i;
if( Options_dmp & FIX_DMP ) {
Wdputslc( "\n" );
Wlseek( Phar_head.reloc_offset );
Banner( "Offset Relocation Table" );
Wdputslc( "80000000H = 32-bits wide quantity to be fixed up\n" );
Wdputslc( " else 16-bits wide quantity to be fixed up\n" );
for( i = 0; i < Phar_head.num_relocs; i++ ) {
Wread( &offset, sizeof( unsigned_32 ) );
if( i != 0 ) {
if( (i) % 6 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
Puthex( offset, 8 );
}
Wdputslc( "\n" );
}
}
/*
* Dump the run-time parameter block.
*/
static void dmp_rtp_tbl( void )
/*****************************/
{
rtpblock rtp_blk;
Wdputslc( "\n" );
Wlseek( Phar_ext_head.rtp_offset );
Wread( &rtp_blk, sizeof( rtpblock ) );
if( rtp_blk.signature == RTP_SIGNATURE ) {
Banner( "Run-time Parameter Block" );
Dump_header( (char *)&rtp_blk.minreal, rtp_blk_msg );
Wdputslc( "\n" );
}
}
/*
* Dump the run-time parameter block.
*/
static void dmp_seg_info_tbl( void )
/**********************************/
{
seg_info_rec seg_info;
unsigned i;
if( Phar_ext_head.sit_size ) {
Wlseek( Phar_ext_head.sit_offset );
Banner( "Segment Information Table" );
Wdputslc( "segment selector flags base offset min extra bytes\n" );
Wdputslc( " ===== ===== ========= =========\n" );
for( i = 0; i < Phar_ext_head.sit_size; i += sizeof( seg_info_rec ) ) {
Wread( &seg_info, sizeof( seg_info_rec ) );
Wdputs( " " );
Puthex( seg_info.seg_sel, 4 );
Wdputs( "H " );
Puthex( seg_info.flags, 4 );
Wdputs( "H " );
Puthex( seg_info.base_off, 8 );
Wdputs( "H " );
Puthex( seg_info.min_extra, 8 );
Wdputslc( "H\n" );
}
}
}
/*
* Dump the run-time parameter block.
*/
static void dmp_reloc_tbl( void )
/*******************************/
{
unsigned_32 offset;
unsigned_16 segment;
unsigned_32 i;
if( (Options_dmp & FIX_DMP) && Phar_ext_head.reloc_size ) {
Wlseek( Phar_ext_head.reloc_offset );
Banner( "Program Relocation Table" );
i = 0;
while( i < Phar_ext_head.reloc_size ) {
Wread( &offset, sizeof( unsigned_32 ) );
Wread( &segment, sizeof( unsigned_16 ) );
if( i != 0 ) {
if( i % 30 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
Puthex( segment, 4 );
Wdputc( ':' );
Puthex( offset, 8 );
i += sizeof( unsigned_32 ) + sizeof(unsigned_16);
}
}
}
/*
* Dump the tss.
*/
static void dmp_tss( void )
/*************************/
{
TSS task_ss;
unsigned_32 image;
if( Phar_ext_head.tss_size ) {
Wdputslc( "\n" );
Wlseek( Phar_ext_head.tss_offset + Phar_ext_head.load_offset );
Wread( &task_ss, sizeof( TSS ) );
Banner( "Task State Segment" );
Dump_header( (char *)&task_ss.backlink, tss_msg );
}
if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) {
image = Phar_ext_head.gdt_size + Phar_ext_head.ldt_size +
Phar_ext_head.tss_size;
Wdputslc( "\n" );
Banner( "Segments" );
Dmp_seg_data( Phar_ext_head.load_offset + image,
Phar_ext_head.load_size - image );
}
}
/*
* Dump the gdt, ldt, idt.
*/
static void dmp_descriptor( unsigned_32 size )
/********************************************/
{
descriptor desc;
unsigned_32 value;
unsigned_32 limit;
unsigned_32 base;
unsigned i;
Wdputslc( " seg base seg limit seg flg1 seg flg2\n" );
Wdputslc( " ======== ========= ======== ========\n" );
for( i = 0; i < size; i += sizeof( descriptor ) ) {
Wread( &desc, sizeof( descriptor ) );
value = desc.bits2 & DESC_LIMIT_HIGH_MASK;
limit = desc.limitlow | value << 16;
value = desc.basemid;
base = desc.baselow | value << 16;
value = desc.basehigh;
base = base | value << 24;
Wdputs( " " );
Puthex( base, 8 );
Wdputs( "H " );
Puthex( limit, 8 );
Wdputs( "H " );
Puthex( desc.bits1, 2 );
Wdputs( "H " );
Puthex( desc.bits2 >> 4, 1 );
Wdputslc( "H\n" );
}
}
/*
* Dump the gdt, ldt, idt.
*/
static void dmp_dts( void )
/*************************/
{
unsigned_32 size;
size = Phar_ext_head.gdt_size;
if( size ) {
Wdputslc( "\n" );
Banner( "GDT table" );
Wlseek( Phar_ext_head.gdt_offset + Phar_ext_head.load_offset );
dmp_descriptor( size );
}
size = Phar_ext_head.ldt_size;
if( size ) {
Wdputslc( "\n" );
Banner( "LDT table" );
Wlseek( Phar_ext_head.ldt_offset + Phar_ext_head.load_offset );
dmp_descriptor( size );
}
size = Phar_ext_head.idt_size;
if( size ) {
Wdputslc( "\n" );
Banner( "IDT table" );
Wlseek( Phar_ext_head.idt_offset + Phar_ext_head.load_offset );
dmp_descriptor( size );
}
}
/*
* Dump the Pharlap Executable Header, if any.
*/
bool Dmp_phar_head( void )
/************************/
{
unsigned_32 offset;
Wlseek( 0 );
Wread( &Phar_head, sizeof( simple_header ) );
if( Phar_head.signature == SIMPLE_SIGNATURE ) {
Banner( "Pharlap EXE Header" );
Dump_header( (char *)&Phar_head.mod_size, phar_exe_msg );
}
if( Phar_head.signature == REX_SIGNATURE ) {
Banner( "Pharlap REX Header" );
Dump_header( (char *)&Phar_head.mod_size, phar_exe_msg );
dmp_rex_reloc();
}
if( Phar_head.signature == SIMPLE_SIGNATURE ||
Phar_head.signature == REX_SIGNATURE ) {
if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) {
offset = Phar_head.reloc_offset + Phar_head.num_relocs *
sizeof( unsigned_32 );
Wdputslc( "\n" );
Banner( "Segments" );
Dmp_seg_data( offset, Phar_head.mod_size + 512 *
(Phar_head.file_size-1) - offset );
}
return( 1 );
}
Wlseek( 0 );
Wread( &Phar_ext_head, sizeof( Phar_ext_head.signature ) );
if( Phar_ext_head.signature == EXTENDED_SIGNATURE ) {
Wread( (char *)&Phar_ext_head + sizeof( Phar_ext_head.signature ),
sizeof( extended_header ) - sizeof( Phar_ext_head.signature ) );
Banner( "Pharlap EXE Extended Header" );
Dump_header( (char *)&Phar_ext_head.format_level, phar_ext_msg );
dmp_rtp_tbl();
dmp_seg_info_tbl();
dmp_reloc_tbl();
dmp_dts();
dmp_tss();
return( 1 );
}
return( 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?