Category : Files from Magazines
Archive   : DDJ9403B.ZIP
Filename : DESIGN.ASC

 
Output of file : DESIGN.ASC contained in archive : DDJ9403B.ZIP

_PORTABILITY BY DESIGN_
by Michael Ross

Listing One

/* Machine dependent information required by front-end */
#ifndef CALLCONV_H
#include "callconv.h"
#endif

#ifndef LANGUAGE_H
#include "language.h"
#endif

#ifndef FP_H
#include "fp.h"
#endif
#ifndef TCLASSES_H
#include "tclasses.h"
#endif

typedef unsigned long inline_flags_type;

typedef enum {
CPU_unknown,

CPU_I386, /* Intel 386 */
CPU_370, /* IBM 370 */
CPU_RT, /* IBM RT */
CPU_AM29K, /* AM29000 */
CPU_I860, /* Intel 860 */
CPU_MC68000, /* Motorola 68000 */
CPU_MC68020, /* Motorola 68020 */
CPU_VAX, /* DEC VAX */
CPU_MDD, /* McDonald Douglas */
CPU_SPARC, /* SPARC (Sun 4) */
CPU_R3000, /* MIPS R3000 */
CPU_HOBBIT,
CPU_PARISC, /* HP9000-600/700/800 PA-RISC */
CPU_Ix86, /* 80x86 -- 16-bit Intel */
CPU_RS6000, /* IBM RS-6000 */
CPU_PPC /* IBM Power PC */
} CPU_type;

/*Object module formats*/

typedef enum {
NOFORMAT, /* OMF not applicable or unknown*/
COFF, /* Basic AT&T COFF */
AMDCOFF, /* AMD version of COFF */
LAMDCOFF, /*AMD version of COFF (little-endian mode) */
INTELOMF, /* Intel OMF (MSDOS) */
ADOTOUT, /* BSD a.out */
ELF, /* SVR4 ELF format */
MACH, /* MACH object module format */
HPUXCOFF, /* HPUX version of COFF */
} objformat_type;

/* Operating systems */
typedef enum {
NOOS, /* OS unknown */
AIX_OS, /* IBM's UNIX */
BSD_OS, /* Berkeley UNIX BSD4.x */
SUN_OS, /* Sun OS */
ATT_OS, /* AT&T UNIX System V.3 */
EPI_OS, /* EPI-OS (AM29000) */
VMS_OS, /* DEC */
MSDOS_OS, /* MS-DOS */
OS2_OS, /* OS/2 */
XNX_OS, /* Xenix */
ISIS_OS, /* Isis */
ATT4_OS, /* AT&T UNIX System V.4 */
NeXT_OS, /* NeXTStep from NeXT */
NEWS_OS, /* Sony NEWS-OS */
MSNT_OS, /* Microsoft NT */
SOL_OS, /* Solaris */
HPUX_OS, /* HP UNIX System V. */
} os_type;

/* Inline transcendentals */
#define SIN_INLINE 0x00000001
#define COS_INLINE 0x00000002
#define ASIN_INLINE 0x00000004 /* Arcsin or Arccos */
#define SQRT_INLINE 0x00000008
#define LOG_INLINE 0x00000010 /* Natural or common log */
#define EXP_INLINE 0x00000020
#define TAN_INLINE 0x00000040
#define ATAN_INLINE 0x00000080
#define ATAN2_INLINE 0x00000100 /* Arctan(a,b) */
#define SINH_INLINE 0x00000200
#define COSH_INLINE 0x00000400
#define TANH_INLINE 0x00000800 /* tanh */
#define FABS_INLINE 0x00001000 /* fabs */
#define ASM_INLINE 0x00002000 /* ASM directive supported */
#define INS_INLINE 0x00004000 /* _inline(bytes) */

/* Status of pragma processing: */
typedef enum {
OKAY_DELETE_p, /* Pragma fully processed; do not pass to backend */
OKAY_PASS_p, /* Pass pragma to back-end */
TOO_LATE_p, /* Pragma specified too late */
ERROR_p, /* Suboperands of pragma incorrect */
/* badptr set to bad parameter */
IGNORED_p, /* Already specified */
} PRAG_STATUS;
struct struct_aligns {char if_its_this_big, align_to_this;};

extern struct mapping_entry{
/* False if structs are packed by default */
bool align_members;
ubyte shortsize; /* size of "short" in bytes */
ubyte intsize; /* size of "int" in bytes */
ubyte longsize; /* size of "long" in bytes */
ubyte floatsize; /* size of "float" */
ubyte doublesize; /* size of "double" */
ubyte longdoublesize;/* size of "long double" */
ubyte min_parm_align;/* Min alignment of a passed parm */
bool unsigned_char; /*"char" unsigned by default? */
bool pure_32_bit; /* All integer operations in 32 bits?*/
ubyte code_ptr_size; /* Code pointer size */
ubyte data_ptr_size; /* Data pointer size */
/* Size of "near" pointer to code */
ubyte near_code_ptr_size;
/* Size of "far" pointer to code */
ubyte far_code_ptr_size;
/* Size of "near" pointer to data */
ubyte near_data_ptr_size;
/*Size of "far" pointer to data */
ubyte far_data_ptr_size;

ubyte short_align; /* Alignment of shorts */
ubyte long_align; /* Long alignment */
ubyte int_align; /* int alignment */
ubyte ptr_align; /* pointer alignment */
ubyte double_align; /* double alignment */
ubyte max_field_align; /* Maximum field alignment */
bool msb_first; /*integers stored MSB first? */
/* Align all vars to int boundary (even chars) */
bool word_align_vars;
bool off_boundary_refs;/* Are off-boundary refs supported?*/
char *version; /* Version number of compiler */
/* Align structs 3 bytes or longer to word boundary */
bool word_align_structs;
calling_convention_set default_calling_convention;
/* If true varargs must be explicitly specified with "..." syntax */
bool ansi_varargs_only;
/* Which transcendentals may be inline? */
inline_flags_type inline_flags;
ubyte max_parm_align;/* Max alignment of a passed parm */
ubyte offset_size; /* Pascal offset size */
ubyte area_size; /* Pascal area size */
/* Largest array in bytes (Pascal) */
unsigned long max_data_size;
bool signed_halfwords_preferred; /*True for 370. (Pascal)*/
bool range_checks_require_range; /*Do we need a lower and upper
value for rangecheck?*/
/* How are Pascal sets mapped? */
/* Also see "set_unit_size" below */
bool sets_mapped_LSB_first;
/* used in machines where pointer arithmetic will not work unless the
* computed address is a multiple of machine's word size. */
ubyte address_resolution;
/* In creating a common block for Professional Pascal interface packages,
* we use the name of the package, prefixed and suffixed with a
* special character. */
/* char to be prefixed to Pascal package block*/
char package_prefix;
/* char to be suffixed to Pascal package block*/
char package_suffix;
/* size of "char" in bytes, believe it or not char is 8 bytes on NAM */
ubyte charsize;
/* Format of floating point */
real_form floating_point_format;
/* If off-boundary references are NOT supported, do we
* handle packed structures nevertheless? */
bool packed_structs_supported;
ubyte char_align; /*Alignment of "char" */
ubyte float_align; /*Alignment of "float" */
ubyte longdouble_align; /*Alignment of "long double" */
char bits_per_int; /*bits per integer used for bitfields */
/* Implies the machine can convert (signed|unsigned)(char|short) to float
* in a way more efficient than to double. The result is that the front
* end is careful to generate FLT vs FLTU in this context so back end can
* tell from register length and FLT/FLTU whether to generate the better
* code and which kind of better code (it differs from U to nonU). */
bool short_to_float;
/* Given the case index of a pseudo-function that target machine is
* usually supports, do we support it with corrent configuration? */
bool (*recognize_pseudo_function)(func_case_index);
CPU_type cpu; /* Target CPU */
os_type os; /* Target OS */
objformat_type omf; /*Target OMF*/
/* For non-padded structs, search this array, terminated by {0,0}.
* If struct size is >= first member, align to at least 2nd member.
* Thus "word_align_structs" could be {3,4},{2,2},{0,0}. */
struct struct_aligns *struct_aligns, *array_aligns;
bool use_INFO; /* Can code generator tolerate INFO
* rather than LINE/FILE/STAB ? */
type_class wchartype; /* this can be any intger type */
ubyte wcharsize; /* sizeof (wchar_t) */
/* We changed the way debugger information is passed to code generator.
* If "debug_info_scheme" is 0, then old way is used. Otherwise, the
* new way. */
ubyte debug_info_scheme;
bool try_supported;
bool wchar_is_short; /* wchar_t is short int */
bool wchar_is_long; /* wchar_t is long int */
/* Given a toggle that may have been defined in
* establish_machine_dependencies, is it still good at this point? */
/* Return TRUE if so. Otherwise, the compiler will issued */
/* "Toggle cannot be specified here." */
bool (*toggle_is_valid)(toggle t, bool turn_it_on);

/* "init", if not zero, is called when the first non-pragma is seen.
* Its primary purpose is to adjust other fields in mapping that are
* dependant on pragmas and toggles. E.g. 1167 toggle for 386 causes long
* doubles to be 8 bytes instead of 12 */
void (*init)(void);
/* The default global aliasing convention. NULL implies "%r". */
char *global_aliasing_convention;
/* Are "far" variables support? That is, does it make
* sense to qualify a variable declaration with "_far"? */
/* This must be FALSE on ESA/370. */
bool far_variables_supported;
/* Are "far" functions supported? If false, compiler will */
/* ignore "_far" and issue a warning. */
bool far_functions_supported;
/* Does the target machine's OMF handle multiple named */
/* control sections (segments)? */
/* If this is false, then the front-end will ignore */
/* "pragma code", "pragma literals(xx)", and "pragma static_segment()". */
/* (Pragma data is handled on UNIX by converting to named blocks). */
bool multiple_named_sections_supported;
/* Can control sections of class "common" be initialized? */
/* On DOS and VMS this is true. */
bool common_section_initialization_supported;
/* Are we generated code for a strict IEEE machine? */
/* If true, we must generate unordered comparisons. */
/* I.e., X < Y is a different operation than !(X >= Y). */
bool IEEE_unordered_compares_supported;
/* code_sections_supported -- if true, the target machine */

/* had separate I & D spaces but is able to reference the */
/* I space as data. (E.g.,386 with its segment override). */
/* If set to TRUE, the toggles "const_in_code" and "literals_in_code"
* will be supported for putting const variables into instruction space.*/
bool code_sections_supported;
/* Is the calling convention "CALLEE_POPS_STACK" supported? */
bool callee_pops_stack_supported;
/* Is the calling convention "REVERSE_PARMS" supported? */
/* (Applies to those machines that have a "PUSH" instruction only. */
bool reverse_parms_supported;
/* Default data aliasing convention for Professional Pascal */
/* Default routine aliasing convention for Professional Pascal */
char *data_aliasing_convention;
char *routine_aliasing_convention;
/* set_unit_size in conjunction with the "sets_mapped_LSB_first" */
/* flag above determine how (Pascal) sets are mapped in storage. */
/* High C/Professional Pascal ordinarily maps sets as a sequence
* of halfwords. Microsoft maps them as an even number of bytes,
* MSB first. */
ubyte set_unit_size;
/* type_checking is true if type information should be kept even when
* g_flag is off. This is used for 370/ESA type checking at link time. */
bool type_checking;
/* Size of a "long long" type. If such types are not supported,
* then the size should match "long". */
ubyte longlongsize;
ubyte longlong_align; /* Alignment of long long */
/* What is the largest auto-variable of type struct that can be mapped
* directly into a series of one or more registers? Value is in bytes. */
uint largest_aggregate_in_registers;
/* When doubles or long doubles are just plain variables (or arrays
* thereof), what should the alignment be? For Pentium, it's much
* better for them to be 8-byte aligned. */
ubyte double_variable_align; /*double variable alignment */
/*Alignment of "long double" variable */
ubyte longdouble_variable_align;
bool supports_call_lit; /* Code generator supports call-lit construct.*/
/* These tell if we require certain calling convention bits: */
/* Must have cc_CALLEE_POPS_STACK.*/
bool callee_pops_stack_required;
bool reverse_parms_required;/* Must have cc_REVERSE_PARMS.*/
/* For C++ constructors/destructors of static/global variables, does
* get handle the initialization level protocol? True for systems
* that support .init/.fini sections. */
bool support_initialization_order;
/* Use Sun's and AT&T's convention for mapping bit fields? */
bool ABI_bit_fields;
/* SYS_SIZETTYPE takes on one of the values s, i, l for short, int, long.
* SYS_SIZETSIGNED takes one of the values s, u, or n for signed,
* unsigned or non-signed (for "char"). */
char sizet_signed; /* s, u, n. */
char sizet_type; /* s, i, l. c not supported currently. */

}mapping;
extern const char *machine_name; /*Name of machine*/
#define LONGLONG_SUPPORTED (SYS_LONGLONGSIZE > SYS_LONGSIZE)
#define SYS_PACKEDSTRUCT (!mapping.align_members)
/* CHARSIZE is always the same on all machines. Wrong!! not on NAM */
#define SYS_CHARSIZE mapping.charsize
#define SYS_INTSIZE mapping.intsize
#define SYS_FLOATSIZE mapping.floatsize
#define SYS_DOUBLESIZE mapping.doublesize
#define SYS_EXTENDEDSIZE mapping.longdoublesize
#define SYS_LINKSIZE mapping.near_data_ptr_size
#define SYS_LONGLONGSIZE mapping.longlongsize
#define SYS_SHORTSIZE mapping.shortsize
#define SYS_LONGSIZE mapping.longsize
#define SYS_SIGNEDCHAR (!mapping.unsigned_char)

/*Pointer that is loaded into reg*/
#define SYS_PTRSIZE SYS_LINKSIZE
#define SYS_DPTRSIZE mapping.data_ptr_size
#define SYS_CPTRSIZE mapping.code_ptr_size
#define SYS_WCHARSIZE mapping.wcharsize
#define SYS_WCHARTYPE mapping.wchartype
#define SYS_WCHARSHORT mapping.wchar_is_short
#define SYS_WCHARLONG mapping.wchar_is_long
#define SYS_SIZETSIGNED mapping.sizet_signed
#define SYS_SIZETTYPE mapping.sizet_type
#define BITS_PER_BYTE 8
#define BITS_PER_INT mapping.bits_per_int
#define BITS_PER_LONG (sizeof(long)*BITS_PER_BYTE)
#define SYS_INTAL mapping.int_align
#define SYS_LONGAL mapping.long_align
#define SYS_LONGLONGAL mapping.longlong_align
#define SYS_SHORTAL mapping.short_align
#define SYS_FLOATAL mapping.float_align
#define SYS_CHARAL mapping.char_align
#define SYS_DOUBLEAL mapping.double_align
#define SYS_LONGDOUBLEAL mapping.longdouble_align
#define SYS_DOUBLE_VARIABLE_AL mapping.double_variable_align
#define SYS_LONGDOUBLE_VARIABLE_AL \
mapping.longdouble_variable_align
#define SYS_PTRAL mapping.ptr_align
#define SYS_OFF_BOUNDARY_REFS mapping.off_boundary_refs
#define SYS_STRINGAL 1 /*Alignment of strings*/
#define SYS_MSB_FIRST mapping.msb_first
#define SYS_LSB_FIRST (!SYS_MSB_FIRST)
#define SYS_STACK_AL mapping.min_parm_align
#define SYS_32_BIT_ARITHMETIC_ONLY mapping.pure_32_bit
#define SYS_MAX_FIELD_AL mapping.max_field_align
#define SYS_WORD_ALIGN_STRUCTS mapping.word_align_structs

#define SYS_ADR_RESOLUTION mapping.address_resolution
#define SEGMENT_REG_SIZE (mapping.far_data_ptr_size - \
SYS_INTSIZE )
#define NEW_DEBUG_INFO (mapping.debug_info_scheme> 0)

/* Establish_machine_dependencies -- initializes "mapping" to correspond
* to "machine". Returns FALSE if machine is not recognized. */
extern bool establish_machine_dependencies(
const char *machine, language_type l);
/* Defines which object module formatter should be used for the target OS and
* machine name of the target operating system passed by the driver */
extern const char *targetos_name;



Listing Two

#define LS (sizeof(long)*8) /* Maximum bits for left shift */
#define BS (sizeof(long long)*8) /* Maximum bits for long long shift */
struct longlong{ /* Define structure for systems that don't support long long*/

long lo;
long hi;
};
typedef struct longlong Big_int;
/* Grab a mantissa from a floating point number */
static long extract_mantissa(FP_number F){
Big_int b;
int cnt, rbit;
cnt = BS -1 - F->Exp; /* Determine how far to shift to find exponent */
if (cnt >= LS){ /* If shifting at least a longword */
cnt -= LS; /* subtract longword length from shift count */
if (cnt == 0)
rbit = long(b.lo) < 0; /* Guard bit needed? */
b.lo = b.hi;
b.hi = 0;
}
if (cnt){ /* Anything left to shift? */
rbit = (b.lo & (1L << (cnt-1))) !=0;
if (cnt == LS){ /* Some machines can't shift by long word length */
b.lo = 0; /* Defend against this. Result would be zero */
b.hi = 0;
}
else{
b.lo = ((unsigned long)b.lo >> cnt | (b.hi << (LS-cnt));
b.hi = (unsigned long) b.hi >> cnt;
}
}
}




Listing Three

#ifndef Process_h
#define Process_h

#include "addrvect.h"
#include "disassem.h"
#include "itemnumb.h"
#include "linklist.h"
#include "memacces.h"
#include "modulemg.h"
#include "stmt.h"
#include "symbolta.h"
#include "tempbkpt.h"


typedef int Outcome;
#define user_failure -1
#define failure 0
#define success 1

class Declaration;
class DiFile;
class EventMgr;
class ExecSpec;
class ExprObj;
class StackFrame;
class Status;
class Thread;

enum PSA1 { psa1_none,
psa1_replace_breakop,
psa1_replace_libpt,
};
enum PSA2 { psa_none,
psa_run_to_retaddr,
};
class Process : public ItemNumber {
Key key;
Thread * current; // 0 in ctor
LinkList threadlist;
TempBkptMgr tempbkptmgr;
EventMgr * eventmgr; // set in ctor
MemAccess memaccess;
Disassembler disassembler;
Symboltable symboltable;
ModuleMgr modulemgr;
AddrVector destvector;
Stmt startstmt;
Boolean now_executing;
DiFile * target_difile;
PSA1 psa1;
PSA2 psa2;
char *current_lang; // Temporary hack to be able
// to set the language.
Thread * lookup_thread( unsigned int );

Outcome check_state();
Outcome set_execspec( const ExecSpec & );
Boolean goal_attained();

Outcome start_step_into( Thread * );
Outcome start_step_over( Thread * );
Outcome start_step_retaddr( Thread * );
Outcome start_run( Thread * );

Outcome analyse_stmt_into( Boolean & );
Outcome analyse_stmt_over( Boolean & );

Outcome run_to_return_addr( Thread * );
Outcome execute_to_return_addr( Thread * );
Outcome run_to_caller( Thread * );

Outcome end_instr_step_into( Thread * );
Outcome end_instr_step_over( Thread * );
Outcome end_stmt_step_into( Thread * );
Outcome end_stmt_step_over( Thread * );
Outcome end_run( Thread * );

Outcome check_instr_step_into( Thread * );
Outcome check_instr_step_over( Thread * );
Outcome check_stmt_step_into( Thread * );
Outcome check_stmt_step_over( Thread * );
Outcome check_run( Thread * );

Outcome respond_to_hop_completion( Thread * );
Outcome respond_to_retpoint( Thread * );
Outcome respond_to_destpoint( Thread * );
Outcome respond_to_breakpoint( Thread * );
Outcome respond_to_watchpoint( Thread * );
Outcome respond_to_exception( Thread * );
Outcome respond_to_step_completion( Thread * );
Outcome respond_to_suspension( Thread * );
Outcome respond_to_exec( Thread *, DiFile * );
Outcome respond_to_libpt( Thread * );

Outcome respond_to_module_load( const Status & );
Outcome respond_to_module_unload( const Status & );
Outcome respond_to_thread_creation( const Status & );
Outcome respond_to_thread_destruction( const Status & );

Outcome start_stmt_step_into( Thread * );
Outcome start_stmt_step_over( Thread * );
public:
Process( unsigned int, DiFile * );
~Process();

Outcome get_status( Status & );
Outcome wait_status( Status & );
Outcome update_status( const Status & );
Boolean is_executing() { return now_executing; }

Outcome run( const ExecSpec & );
Outcome instr_step_into( const ExecSpec & );
Outcome instr_step_over( const ExecSpec & );
Outcome stmt_step_into( const ExecSpec & );
Outcome stmt_step_over( const ExecSpec & );
Outcome resume();
Outcome stop();

Thread * current_thread() { return current; }

Outcome disassemble( const Addr &, Instruction &, Addr & );
Outcome find_stmt( const Addr &, Stmt & );
Outcome find_function( const Addr &, Declaration & );

Outcome evaluate( char *, StackFrame &, ExprObj & );
Outcome set_language(char *input_language);
char *get_lang_string();
Process * next() { return (Process *)Item::get_next(); }
};
#endif




Example 1

(a)

#include
struct bad_layout{
char direction;
union {
char var;
float fvar;
double dvar;
} mess;
int myint;
};

main(){
struct bad_layout mystruct;
printf("sizeof(mystruct) = %d\n", sizeof(mystruct));
}


(b)

COMMON /SLOW/ I,D,L
EQUIVALENCE (D,N(2)),(I,N(1))
INTEGER I,N(2)
DOUBLE PRECISION D
LOGICAL L

PRINT *,D
END


(c)

SUBROUTINE USELESS(I,J)

INTEGER I,J
IF (J.EQ.0) GOTO 10
I = J ** 2
GOTO 20
10 I = 3
J = 10
20 CONTINUE
END