qnxexe.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 365 行
C
365 行
/****************************************************************************
*
* 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: QNX executable dumping routines.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <string.h>
#include "wdglb.h"
#include "wdfunc.h"
static char *qnx_def_msg[] = {
"2version number = ",
"2cflags = ",
"2cpu (86, 186, 286, 386, 486) = ",
"2fpu (0, 87, 287, 287) = ",
"2selector of code start address = ",
"2selector where to put the stack = ",
"2selector to put heap = ",
"2selector where to put argv and environment = ",
"2zero = ",
"2zero = ",
"2zero = ",
"2zero = ",
"4code offset = ",
"4stack size in bytes = ",
"4initial near heap size in bytes = ",
"4image base = ",
"4zero = ",
"4zero = ",
NULL
};
static char *qnx_data_msg[] = {
"2segment index = ",
"4offset = ",
NULL
};
/*
* Dump the flags.
*/
static void dmp_flag( unsigned_16 flag )
/**************************************/
{
if( !flag ) {
return;
}
Wdputs( "flags =" );
if( flag & _TCF_LONG_LIVED ) {
Wdputs( " LONG_LIVED" );
}
if( flag & _TCF_32BIT ) {
Wdputs( " 32BIT" );
}
if( flag & _TCF_PRIV_MASK ) {
Wdputs( " PRIV_MASK" );
}
if( flag & _TCF_FLAT ) {
Wdputs( " FLAT" );
}
Wdputslc( "\n" );
}
/*
* Dump segments.
*/
static void dmp_seg( unsigned_16 size )
/*************************************/
{
unsigned_16 i;
unsigned_32 seg;
if( !size ) {
return;
}
Wdputslc( "segments = type:size\n" );
Wdputslc( "type 0==read/write, 1==read-only, 2==execute/read, 3==execute-only\n" );
for( i = 0; i < size; i++ ) {
if( i != 0 ) {
if( i % 6 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
Wread( &seg, sizeof( unsigned_32 ) );
Puthex( seg >> 28, 1 );
Wdputc( ':' );
Puthex( seg, 7 );
}
Wdputslc( "\n" );
}
/*
* Dump rw end.
*/
static void dmp_rw_end( void )
/****************************/
{
lmf_rw_end rw_end;
Wdputslc( "\n" );
Banner( "Read/Write end" );
Wread( &rw_end, sizeof( lmf_rw_end ) );
Wdputs( "verify = " );
Puthex( rw_end.verify, 4 );
Wdputs( "H signature = " );
Puthex( rw_end.signature, 8 );
Wdputslc( "H\n" );
}
/*
* Dump resources.
*/
static void dmp_resrc( unsigned_16 size, unsigned_32 offset )
/***********************************************************/
{
unsigned_16 i;
lmf_resource resrc;
Wdputslc( "\n" );
Banner( "Resource Table" );
Wread( &resrc, sizeof( lmf_resource ) );
Wdputs( "resource type (0==usage) = " );
Puthex( resrc.res_type, 4 );
Wdputslc( "H\n" );
Wdputs( "zeros = " );
for( i = 0; i < 3; i++ ) { // 3 spares (zeros)
Puthex( resrc.spare[i], 4 );
Wdputs( "H " );
}
Wdputslc( "\n" );
size -= sizeof( lmf_resource );
Wdputs( "size = " );
Puthex( size, 4 );
Wdputslc( "H\n" );
offset += sizeof( lmf_resource );
if( Options_dmp & RESRC_DMP ) {
Dmp_seg_data( offset, size );
}
}
/*
* Dump fixups.
*/
static void dmp_fixup( unsigned_16 size, bool float_pt )
/******************************************************/
{
lmf_data fixup;
unsigned_16 i;
Wdputslc( "\n" );
if( float_pt ) {
Banner( "Floating Point Fixup Table" );
} else {
Banner( "Fixup Table" );
}
Wdputs( "size = " );
Puthex( size, 4 );
if( Options_dmp & FIX_DMP ) {
if( float_pt ) {
Wdputslc( " segment : type:offset\n" );
} else {
Wdputslc( " segment : offset\n" );
}
for( i = 0; i < size / sizeof( lmf_data ); i++ ) {
Wread( &fixup, sizeof( lmf_data ) );
if( i != 0 ) {
if( i % 4 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
Puthex( fixup.segment, 4 );
Wdputs( " : " );
if( float_pt ) {
Puthex( fixup.offset >> 28, 1 );
Wdputc( ':' );
Puthex( fixup.offset, 7 );
} else {
Puthex( fixup.offset, 8 );
}
}
}
Wdputslc( "\n" );
}
static void dmp_banner( void )
/****************************/
{
char buff[80];
char sec;
strcpy( buff, "Data Table " );
strcat( buff, itoa( Data_count, &sec, 10 ) );
Banner( buff );
}
/*
* Dump data.
*/
static void dmp_data( unsigned_16 size, unsigned_32 offset )
/**********************************************************/
{
lmf_data data;
Wdputslc( "\n" );
Data_count++;
dmp_banner();
Wread( &data, sizeof( lmf_data ) );
Dump_header( (char *)&data.segment, qnx_data_msg );
size -= sizeof( lmf_data );
Wdputs( "size = " );
Puthex( size, 4 );
Wdputslc( "H\n" );
offset += sizeof( lmf_data );
if( Options_dmp & (DOS_SEG_DMP | OS2_SEG_DMP) ) {
if( Segspec == 0 || Segspec == Data_count ) {
Dmp_seg_data( offset, size );
}
}
}
/*
* Dump linear fixups.
*/
static void dmp_lin_fix( unsigned_16 size )
/*****************************************/
{
unsigned_16 seg_indx, i;
unsigned_32 offset;
Wdputslc( "\n" );
Banner( "Linear Fixup Table" );
Wread( &seg_indx, sizeof( unsigned_16 ) );
Wdputs( "fixup segment index = " );
Puthex( seg_indx, 4 );
size -= sizeof( unsigned_16 );
Wdputs( " size = " );
Puthex( size, 4 );
if( Options_dmp & FIX_DMP ) {
Wdputslc( "\n" );
Wdputslc( "80000000H = target is in code segment\n" );
for( i = 0; i < size / sizeof( unsigned_32 ); i++ ) {
Wread( &offset, sizeof( unsigned_32 ) );
if( i != 0 ) {
if( i % 6 == 0 ) {
Wdputslc( "\n" );
} else {
Wdputs( " " );
}
}
Puthex( offset, 8 );
}
}
Wdputslc( "\n" );
}
/*
* get type of next record.
*/
static void get_rec_type( unsigned_8 rtype, unsigned_16 size, unsigned_32 offset )
/********************************************************************************/
{
switch( rtype ) {
case LMF_COMMENT_REC:
Wdputslc( "\n" );
Banner( "Comments" );
Dmp_seg_data( offset, size );
break;
case LMF_LOAD_REC:
dmp_data( size, offset );
break;
case LMF_FIXUP_REC:
dmp_fixup( size, FALSE );
break;
case LMF_8087_FIXUP_REC:
dmp_fixup( size, TRUE );
break;
case LMF_RESOURCE_REC:
dmp_resrc( size, offset );
break;
case LMF_RW_END_REC:
dmp_rw_end();
break;
case LMF_LINEAR_FIXUP_REC:
dmp_lin_fix( size );
break;
default:
Wdputs( "unknown record type: " );
Putdec( rtype );
Wdputslc( "\n" );
break;
}
}
/*
* Dump the QNX header, if any.
*/
bool Dmp_qnx_head( void )
/***********************/
{
lmf_record qnx_rec;
unsigned_16 size;
unsigned_32 offset;
Wlseek( 0 );
Wread( &qnx_rec, sizeof( lmf_record ) );
if( qnx_rec.rec_type == LMF_HEADER_REC ) {
Wread( &Qnx_head, sizeof( lmf_header ) );
if( Qnx_head.version != QNX_VERSION ) {
return( 0 );
}
Banner( "QNX EXE Header" );
Dump_header( (char *)&Qnx_head.version, qnx_def_msg );
dmp_flag( Qnx_head.cflags );
size = ( qnx_rec.data_nbytes - sizeof( lmf_header ) ) / 4;
dmp_seg( size );
offset = qnx_rec.data_nbytes + sizeof( lmf_record );
for( ;; ) {
Wlseek( offset );
Wread( &qnx_rec, sizeof( lmf_record ) );
if( qnx_rec.rec_type == LMF_IMAGE_END_REC ) {
break;
}
offset += sizeof( lmf_record );
get_rec_type( qnx_rec.rec_type, qnx_rec.data_nbytes, offset );
offset += qnx_rec.data_nbytes;
}
return( 1 );
}
return( 0 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?