madman.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,275 行 · 第 1/5 页
C
2,275 行
/****************************************************************************
*
* 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: Machine Architecture Description manager - generic routines.
*
****************************************************************************/
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <i64.h>
#include "mad.h"
#include "madimp.h"
#include "madcli.h"
#include "xfloat.h"
#if defined( __386__ ) || defined( __I86__ ) || defined( __ALPHA__ ) || defined( __PPC__ ) || defined( __MIPS__ )
#define MNR_HOST_SIGNED MNR_TWOS_COMP
#define FLOAT_IEEE
#else
#error Host MAD type info not configured
#endif
#if defined( __BIG_ENDIAN__ )
#define ME_HOST ME_BIG
#else
#define ME_HOST ME_LITTLE
#endif
const static unsigned EndMap[2][8] = {
/* ME_LITTLE */ { 0, 1, 2, 3, 4, 5, 6, 7 },
/* ME_BIG */ { 7, 6, 5, 4, 3, 2, 1, 0 },
};
struct mad_state_data {
mad_state_data *next;
/* followed by the imp_mad_state structure */
};
typedef struct mad_entry mad_entry;
struct mad_entry {
mad_entry *next;
char *file;
char *desc;
mad_imp_routines *rtns;
mad_state_data *sl;
mad_handle mh;
unsigned long sh;
};
static mad_entry *MADList;
static mad_entry *Active;
/*
* System specific support routines
*/
mad_status MADSysLoad( char *, mad_client_routines *,
mad_imp_routines **, unsigned long * );
void MADSysUnload( unsigned long );
/*
* Client interface
*/
static mad_status DIGCLIENT MADCliTypeInfoForHost( mad_type_kind tk, int size, mad_type_info *mti )
{
return( MADTypeInfoForHost( tk, size, mti ) );
}
static mad_status DIGCLIENT MADCliTypeConvert( const mad_type_info *in_t, const void *in_d, const mad_type_info *out_t, void *out_d, addr_seg seg )
{
return( MADTypeConvert( in_t, in_d, out_t, out_d, seg ) );
}
static mad_status DIGCLIENT MADCliTypeToString( unsigned radix, const mad_type_info *mti, const void *data, unsigned *max, char *buff )
{
return( MADTypeToString( radix, mti, data, max, buff ) );
}
mad_client_routines MADClientInterface = {
MAD_MAJOR,
MAD_MINOR_OLD, //NYI: change to MAD_MINOR when everybody's updated
sizeof( mad_client_routines ),
DIGCliAlloc,
DIGCliRealloc,
DIGCliFree,
DIGCliOpen,
DIGCliSeek,
DIGCliRead,
DIGCliClose,
MADCliReadMem,
MADCliWriteMem,
MADCliString,
MADCliAddString,
MADCliRadixPrefix,
MADCliNotify,
DIGCliMachineData,
MADCliAddrToString,
MADCliMemExpr,
MADCliAddrSection,
MADCliAddrOvlReturn,
MADCliSystemConfig,
MADCliTypeInfoForHost,
MADCliTypeConvert,
MADCliTypeToString
};
/*
* Support Routines
*/
static mad_imp_routines DummyRtns; /* forward reference */
static mad_entry Dummy =
{ NULL, "", "Unknown Architecture", &DummyRtns, MAD_NIL, 0 };
static const mad_string EmptyStrList[] = { MSTR_NIL };
static const mad_toggle_strings EmptyToggleList[] = { { MSTR_NIL }, { MSTR_NIL }, { MSTR_NIL } };
static mad_status MADStatus( mad_status ms )
{
MADCliNotify( MNT_ERROR, &ms );
return( ms );
}
static mad_entry *MADFind( mad_handle mh )
{
mad_entry *curr;
if( mh == MAD_NIL ) return( NULL );
if( mh == Active->mh ) return( Active );
for( curr = MADList; curr != NULL; curr = curr->next ) {
if( curr->mh == mh ) return( curr );
}
return( NULL );
}
/*
* Control Routines
*/
mad_status MADInit( void )
{
static const struct {
mad_handle mh;
const char *file;
const char *desc;
} list[] = {
{ MAD_X86, "madx86", "Intel Architecture [80(x)86]" },
{ MAD_AXP, "madaxp", "Alpha Architecture" },
{ MAD_PPC, "madppc", "PowerPC Architecture" },
{ MAD_MIPS, "madmips", "MIPS Architecture" },
{ MAD_MSJ, "msj", "Java Virtual Machine (Microsoft)" }
};
mad_status ms;
unsigned i;
MADList = NULL;
Active = &Dummy;
for( i = 0; i < sizeof( list ) / sizeof( list[0] ); ++i ) {
ms = MADRegister( list[i].mh, list[i].file, list[i].desc );
if( ms != MS_OK ) return( ms );
}
return( ms );
}
mad_status MADRegister( mad_handle mh, const char *file, const char *desc )
{
mad_entry **owner;
mad_entry *curr;
mad_entry *old;
unsigned file_len;
unsigned desc_len;
owner = &MADList;
for( ;; ) {
curr = *owner;
if( curr == NULL ) break;
if( curr->mh == mh ) {
*owner = curr->next;
old = Active;
Active = curr;
while( curr->sl != NULL ) {
MADStateDestroy( curr->sl );
}
Active = old;
if( curr == Active ) Active = &Dummy;
/* MADUnload( curr->mh ); Did not work from here. */
/* Removed call, and moved fixed functionality here */
if( curr->rtns != NULL ) {
curr->rtns->MIFini();
curr->rtns = NULL;
}
if( curr->sh != 0 ) MADSysUnload( curr->sh );
DIGCliFree( curr );
break;
}
owner = &curr->next;
}
if( file == NULL ) return( MS_OK );
file_len = strlen( file );
desc_len = strlen( desc );
curr = DIGCliAlloc( (sizeof( *curr ) + 2) + file_len + desc_len );
if( curr == NULL ) return( MADStatus( MS_ERR | MS_NO_MEM ) );
curr->next = *owner;
*owner = curr;
curr->file = (char *)curr + sizeof( *curr );
curr->desc = &curr->file[ file_len + 1 ];
curr->rtns = NULL;
curr->sl = NULL;
curr->mh = mh;
curr->sh = 0;
strcpy( curr->file, file );
strcpy( curr->desc, desc );
return( MS_OK );
}
static mad_status DIGREGISTER DummyInit( void )
{
/* never actually called */
return( MS_OK );
}
mad_status MADLoad( mad_handle mh )
{
mad_entry *me;
mad_status ms;
me = MADFind( mh );
if( me == NULL ) return( MADStatus( MS_ERR | MS_UNREGISTERED_MAD ) );
if( me->rtns != NULL ) return( MS_OK );
ms = MADSysLoad( me->file, &MADClientInterface, &me->rtns, &me->sh );
if( ms != MS_OK ) {
me->rtns = NULL;
return( MADStatus( ms ) );
}
if( MADClientInterface.major != me->rtns->major
|| MADClientInterface.minor > me->rtns->minor ) {
me->rtns = NULL;
MADUnload( mh );
return( MADStatus( MS_ERR|MS_INVALID_MAD_VERSION ) );
}
ms = me->rtns->MIInit();
if( ms != MS_OK ) {
me->rtns = NULL;
MADUnload( mh );
return( MADStatus( ms ) );
}
if( me->sl == NULL ) {
me->sl = DIGCliAlloc( sizeof( *me->sl ) + me->rtns->MIStateSize() );
if( me->sl == NULL ) {
MADUnload( mh );
return( MADStatus( MS_ERR|MS_NO_MEM ) );
}
me->rtns->MIStateInit( (imp_mad_state_data *)&me->sl[1] );
me->sl->next = NULL;
}
Active->rtns->MIStateSet( (imp_mad_state_data *)&me->sl[1] );
return( MS_OK );
}
static void DIGREGISTER DummyFini( void )
{
/* never actually called */
}
void MADUnload( mad_handle mh )
{
mad_entry *me;
me = MADFind( mh );
if( me == NULL ) return;
if( me->rtns != NULL ) {
me->rtns->MIFini();
me->rtns = NULL;
}
if( me->sh != 0 ) {
MADSysUnload( me->sh );
}
}
mad_status MADLoaded( mad_handle mh )
{
mad_entry *me;
me = MADFind( mh );
if( me == NULL ) return( MADStatus( MS_ERR|MS_UNREGISTERED_MAD ) );
return( me->rtns != NULL ? MS_OK : MS_FAIL );
}
mad_handle MADActiveSet( mad_handle mh )
{
mad_handle old;
mad_entry *me;
old = Active->mh;
me = MADFind( mh );
if( me != NULL ) Active = me;
return( old );
}
static unsigned DIGREGISTER DummyStateSize( void )
{
return( 0 );
}
static void DIGREGISTER DummyStateInit( imp_mad_state_data *msd )
{
msd = msd;
}
static void DIGREGISTER DummyStateSet( imp_mad_state_data *msd )
{
msd = msd;
}
static void DIGREGISTER DummyStateCopy( const imp_mad_state_data *src, imp_mad_state_data *dst )
{
src = src;
dst = dst;
}
mad_state_data *MADStateCreate( void )
{
mad_state_data *new;
new = DIGCliAlloc( sizeof( *new ) + Active->rtns->MIStateSize() );
if( new == NULL ) {
MADStatus( MS_ERR | MS_NO_MEM );
return( NULL );
}
/* first one is currently active state */
new->next = Active->sl->next;
Active->sl->next = new;
Active->rtns->MIStateInit( (imp_mad_state_data *)&new[1] );
return( new );
}
mad_state_data *MADStateSet( mad_state_data *msd )
{
mad_state_data **owner;
mad_state_data *curr;
if( msd == NULL ) return( Active->sl );
owner = &Active->sl;
for( ;; ) {
curr = *owner;
if( curr == NULL ) {
MADStatus( MS_ERR|MS_NO_MEM );
return( Active->sl );
}
if( curr == msd ) break;
owner = &curr->next;
}
curr = Active->sl;
*owner = msd->next;
msd->next = curr;
Active->sl = msd;
Active->rtns->MIStateSet( (imp_mad_state_data *)&msd[1] );
return( curr );
}
void MADStateCopy( const mad_state_data *src, mad_state_data *dst )
{
Active->rtns->MIStateCopy( (const imp_mad_state_data *)&src[1], (imp_mad_state_data *)&dst[1] );
}
void MADStateDestroy( mad_state_data *msd )
{
mad_state_data **owner;
mad_state_data *curr;
owner = &Active->sl;
for( ;; ) {
curr = *owner;
if( curr == NULL ) {
MADStatus( MS_ERR|MS_INVALID_STATE );
return;
}
if( curr == msd ) break;
owner = &curr->next;
}
*owner = msd->next;
DIGCliFree( msd );
}
void MADFini( void )
{
while( MADList != NULL ) {
MADRegister( MADList->mh, NULL, NULL );
}
}
walk_result MADWalk( MAD_WALKER *wk, void *d )
{
walk_result wr;
mad_entry *me;
for( me = MADList; me != NULL; me = me->next ) {
wr = wk( me->mh, d );
if( wr != WR_CONTINUE ) return( wr );
}
return( WR_CONTINUE );
}
unsigned MADNameFile( mad_handle mh, unsigned max, char *name )
{
mad_entry *me;
unsigned len;
me = MADFind( mh );
if( me == NULL ) {
MADStatus( MS_ERR|MS_UNREGISTERED_MAD );
return( 0 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?