diff options
author | K. Richard Pixley <rich@cygnus> | 1992-12-08 04:59:31 +0000 |
---|---|---|
committer | K. Richard Pixley <rich@cygnus> | 1992-12-08 04:59:31 +0000 |
commit | 43bbd567f2d928b2628e508ee9c75a3920e26b4d (patch) | |
tree | 21f1ab246e1a3f963e73c3662bc1d44f591349a1 /gdb/tdesc.c | |
parent | a362ee23634a2f9ce9642eab09592e8ff6ae509b (diff) | |
download | gdb-43bbd567f2d928b2628e508ee9c75a3920e26b4d.zip gdb-43bbd567f2d928b2628e508ee9c75a3920e26b4d.tar.gz gdb-43bbd567f2d928b2628e508ee9c75a3920e26b4d.tar.bz2 |
recording file death
Diffstat (limited to 'gdb/tdesc.c')
-rwxr-xr-x | gdb/tdesc.c | 1650 |
1 files changed, 0 insertions, 1650 deletions
diff --git a/gdb/tdesc.c b/gdb/tdesc.c deleted file mode 100755 index 4a38649..0000000 --- a/gdb/tdesc.c +++ /dev/null @@ -1,1650 +0,0 @@ -/* This file has been modified by Data General Corporation, November 1989. */ - -/* -This file provides an abstract interface to "tdesc" information. - It is designed to be used in a uniform manner by several kinds - of debuggers: - (1) code in live debugged process (e.g., a traceback routine) - (2) a separate-process debugger debugging a live process - (3) a separate-process debugger debugging a memory dump - - Dcontext model notes - * captures machine context - * partial: excludes memory - * frames - * kinds - * make one for starters, chain in reverse order to previous ones - * representation: pointer to opaque - * alloc/free protocol - - Overall model - * access functions - * handle - * error handling -*/ - - - -typedef int dc_boolean_t; /* range 0 .. 1 */ -#define DC_FALSE 0 -#define DC_TRUE 1 - - -typedef int dc_tristate_t; /* range 0 .. 2 */ -#define DC_NO 0 -#define DC_YES 1 -#define DC_MAYBE 2 - - -/* - A word is 32 bits of information. In memory, a word is word-aligned. - - A common and important use of dc_word_t is to represent values in the - target process, including (byte) addresses in the target process. - In this case, C arithmetic can be used to simulate machine address - arithmetic on the target. (Unsigned arithmetic is actually modulus - arithmetic.) -*/ -typedef unsigned int dc_word_t; - - -/* These bit operations number bits from 0 at the least significant end. */ -#define bit_test(word,bit) ((word) & (1 << (bit))) /* returns 0 or other */ -#define bit_value(word,bit) (((word) >> (bit)) & 1) /* returns 0 or 1 */ -#define bit_set(word,bit) ((word) |= (1 << (bit))) -#define bit_clear(word,bit) ((word) &= ~(1 << (bit))) -#define bit_assign(word, bit, bool) \ - if (bool) bit_set(word, bit); else bit_clear(word, bit) - - -/*----------------*/ - - -/* The exactness of locations may not be certainly known. */ -typedef dc_tristate_t dc_exactness_t; - - -/* - The model includes five kinds of contexts. Because each context - has an associated region and frame, these describe region kinds - and frame kinds as well. - [more description needed] - Currently, only call contexts exist. -*/ - -typedef int dc_kind_t; /* range 0 .. 4 */ -#define DC_CALL_KIND 0 -#define DC_SAVE_KIND 1 -#define DC_EXCEPTION_KIND 2 -#define DC_PROTECTION_KIND 3 -#define DC_SPECIAL_KIND 4 -#define DC_NUM_KINDS 5 - -#define DC_MIO_ENTRY_POINT (1<< 0) -#define DC_MIO_PROLOGUE_END (1<< 1) -#define DC_MIO_EPILOGUE_START (1<< 2) -#define DC_MIO_IMPLICIT_PROLOGUE_END (1<<16) -#define DC_MIO_LITERAL_ENTRY_POINT (1<<17) -#define DC_MIO_LITERAL_EPILOGUE_START (1<<18) - -#define DC_MII_PRECEDING_TDESC_END (1<<0) -#define DC_MII_FOLLOWING_TDESC_START (1<<1) - -typedef struct dc_debug_info { - unsigned int protocol; /* 1 for this structure */ - dc_word_t tdesc_ptr; - unsigned int text_words_count; - dc_word_t text_words_ptr; - unsigned int data_words_count; - dc_word_t data_words_ptr; -} dc_debug_info_t; - - -typedef struct tdesc_hdr { - unsigned int map_protocol; /* 1 for this structure */ - unsigned int end; /* address beyond end */ -} tdesc_hdr_t; - - -typedef struct tdesc_chunk_hdr { - int zeroes : 8; - int info_length : 22; - int info_alignment : 2; - unsigned int info_protocol; - dc_word_t start_address; - dc_word_t end_address; -} tdesc_chunk_hdr_t; - - -typedef struct tdesc_chunk_info1 { - int variant : 8; /* 1 for this structure */ - int register_save_mask : 17; - int pad1 : 1; - int return_address_info_discriminant : 1; - int frame_address_register : 5; - unsigned int frame_address_offset; - unsigned int return_address_info; - unsigned int register_save_offset; -} tdesc_chunk_info1_t; - - -typedef struct tdesc_chunk1 { - tdesc_chunk_hdr_t hdr; - tdesc_chunk_info1_t info; -} tdesc_chunk1_t; - - -typedef struct dc_mstate { - dc_word_t reg[32]; /* general registers */ - dc_word_t xip; - dc_word_t nip; - dc_word_t fip; - dc_word_t fpsr; - dc_word_t fpcr; - dc_word_t psr; -} dc_mstate_t; - - -typedef struct dc_map_info_in { - dc_word_t flags; - dc_word_t preceding_tdesc_end; - dc_word_t following_tdesc_start; -} dc_map_info_in_t; - - -typedef struct dc_map_info_out { - dc_word_t flags; - dc_word_t entry_point; - dc_word_t prologue_end; - dc_word_t epilogue_start; -} dc_map_info_out_t; - - -#if 0 - - void error_fcn (env, continuable, message) - dc_word_t env; /* environment (arbitrary datum) */ - dc_boolean_t continuable; /* whether error function may return */ - char *message; /* string (no trailing newline) */ - - /* In the future, we probably want the error_fcn to be: */ - void error_fcn (env, continuable, code, ...) - dc_word_t env; /* environment (arbitrary datum) */ - dc_boolean_t continuable; /* whether error function may return */ - int code; /* error code */ - ... /* parameters to message associated - with the code */ - - void read_fcn (env, memory, length, buffer) - dc_word_t env; /* environment (arbitrary datum) */ - dc_word_t memory; /* start address in image */ - int length; /* in bytes */ - char *buffer; /* start address of buffer */ - /* There are no alignment assumptions for the read function. */ - - void write_fcn (env, memory, length, buffer) - dc_word_t env; /* environment (arbitrary datum) */ - dc_word_t memory; /* start address in image */ - int length; /* in bytes */ - char *buffer; /* start address of buffer */ - /* There are no alignment assumptions for the write function. */ - /* The write function is optional. It must be provided if changes - to writable registers are to be made. */ - - void exec_fcn (env, mstate) - dc_word_t env; /* environment (arbitrary datum) */ - dc_mstate_t *mstate; /* machine state (read-write) */ - /* The execute function is optional. It would be used (in the future) - by the implementation of a procedurally specified tdesc mechanism. */ - -#endif - -/*----------------*/ - - -#ifndef NULL -#define NULL ((void *) 0) -#endif - -extern char *malloc(); -extern char *calloc(); -extern void qsort(); - - -/* - At initialization, create a tdesc table from the tdesc info. - A tdesc table is simply a sorted array of tdesc elements. - A tdesc element is the last 6 words of the tdesc chunk. - We require that all tdesc chunks have info protocol 1. -*/ - -typedef struct tdesc_elem { - dc_word_t start_address; - dc_word_t end_address; - tdesc_chunk_info1_t info; -} tdesc_elem_t; - -typedef tdesc_elem_t *tdesc_table_t; - -void dc_correct_cr_data(); - -int dc_compare_tdesc_elems (elem1, elem2) - char *elem1, *elem2; -{ - dc_word_t s1, s2, e1, e2; - s1 = ((tdesc_elem_t *) elem1)->start_address; - s2 = ((tdesc_elem_t *) elem2)->start_address; - if (s1 < s2) return -1; - if (s1 > s2) return 1; - e1 = ((tdesc_elem_t *) elem1)->end_address; - e2 = ((tdesc_elem_t *) elem2)->end_address; - if (e1 < e2) return -1; - if (e1 > e2) return 1; - return 0; -} - - -typedef struct handle_info { - dc_word_t debug_info_ptr; - void (*error_fcn)(); - dc_word_t error_env; - void (*read_fcn)(); - dc_word_t read_env; - void (*write_fcn)(); /* NULL => absent */ - dc_word_t write_env; - void (*exec_fcn)(); /* NULL => absent */ - dc_word_t exec_env; - void (*map_fcn)(); /* NULL => absent */ - dc_word_t map_env; - tdesc_table_t tdesc_table; - int tdesc_table_size; -} handle_info_t; - -typedef handle_info_t *dc_handle_t; - - -/* - Errors detected in this module are funnelled through dc_error or dc_warn, - as appropriate. Both routines call dc_exception, which invokes the error - handler supplied by the user. - - Currently, dc_exception substitutes parameters into the message given - it and passes the resulting string to the user error handler. - In the future, dc_exception should simply pass an error code and - the parameters on to the user error handler. -*/ - -#include <varargs.h> -extern int vsprintf(); - -/* Exit status for exception-processing machinery failure */ -#define DC_EXCEPTION_FAILURE 250 - -void dc_exception(continuable, args) - dc_boolean_t continuable; - va_list args; -{ - dc_handle_t handle; - char *format; - char buffer[1024]; - - handle = va_arg(args, dc_handle_t); - format = va_arg(args, char *); - (void) vsprintf(buffer, format, args); - (*(handle->error_fcn)) (handle->error_env, continuable, buffer); - if (!continuable) - exit(DC_EXCEPTION_FAILURE); /* User error handler should never return in this case. */ -} - - -void dc_error(va_alist) /* (handle, format, args... ) */ - va_dcl -{ - va_list args; - - va_start(args); - dc_exception(DC_FALSE, args); - va_end(args); -} - - -void dc_warn(va_alist) /* (handle, format, args... ) */ - va_dcl -{ - va_list args; - - va_start(args); - dc_exception(DC_TRUE, args); - va_end(args); -} - - - -#define MALLOC_FAILURE_MESSAGE "Heap space exhausted (malloc failed)." -#define CALLOC_FAILURE_MESSAGE "Heap space exhausted (Calloc failed)." - - -/* Commonize memory allocation call so failure diagnosis is easier */ - -char* dc_malloc( handle, size ) - dc_handle_t handle; - int size; -{ - char* space = malloc( size ); - if (space == (char *)NULL) - dc_error( handle, MALLOC_FAILURE_MESSAGE ); - - return space; -} - - -/* Commonize memory allocation call so failure diagnosis is easier */ - -char* dc_calloc( handle,nelem, size ) - dc_handle_t handle; - int nelem; - int size; -{ - char* space = calloc( nelem, size ); - if (space == (char *)NULL) - dc_error( handle, CALLOC_FAILURE_MESSAGE ); - - return space; -} - - -dc_word_t dc_read_word (handle, address) - dc_handle_t handle; - dc_word_t address; -{ - dc_word_t word; - (*(handle->read_fcn)) (handle->read_env, address, - sizeof(dc_word_t), (char *)(&(word))); - return word; -} - - -void dc_write_word (handle, address, value) - dc_handle_t handle; - dc_word_t address; - dc_word_t value; -{ - dc_word_t word; - word = value; - if (handle->write_fcn) { - (*(handle->write_fcn)) (handle->write_env, address, - sizeof(dc_word_t), (char *)(&(word))); - } else { - dc_error (handle, "Writing is disabled."); - } -} - - -void dc_write_masked_word (handle, address, mask, value) - dc_handle_t handle; - dc_word_t address; - dc_word_t mask; - dc_word_t value; -{ - dc_write_word (handle, address, - (value & mask) | (dc_read_word(handle, address) & ~mask)); -} - - -dc_handle_t dc_initiate (debug_info_ptr, - error_fcn, error_env, - read_fcn, read_env, - write_fcn, write_env, - exec_fcn, exec_env, - map_fcn, map_env) - dc_word_t debug_info_ptr; - void (*error_fcn)(); - dc_word_t error_env; - void (*read_fcn)(); - dc_word_t read_env; - void (*write_fcn)(); /* NULL => absent */ - dc_word_t write_env; - void (*exec_fcn)(); /* NULL => absent */ - dc_word_t exec_env; - void (*map_fcn)(); /* NULL => absent */ - dc_word_t map_env; - /* write_fcn may be given as NULL if no writing is required. */ - /* exec_fcn may be given as NULL if no execution is required. - Currently, no execution is required. It would be if the - implementation needed to invoke procedures in the debugged process. */ -{ - dc_handle_t handle; - unsigned int debug_info_protocol; - dc_debug_info_t debug_info; - unsigned int tdesc_map_protocol; - tdesc_hdr_t tdesc_hdr; - dc_word_t tdesc_info_start; - dc_word_t tdesc_info_end; - dc_word_t tdesc_info_length; - - /* Set up handle enough for dc_error. */ - handle = (dc_handle_t) malloc(sizeof(handle_info_t)); - /* Cant use dc_malloc() as handle is being created ... */ - /* if (handle == NULL) (*error_fcn)( error_env, MALLOC_FAILURE_MESSAGE ) */ - handle->error_fcn = error_fcn; - handle->error_env = error_env; - handle->read_fcn = read_fcn; - handle->read_env = read_env; - handle->write_fcn = write_fcn; - handle->write_env = write_env; - handle->exec_fcn = exec_fcn; - handle->exec_env = exec_env; -/****************************************************************/ -/* BUG 9/19/89 Found by hls. Map functions not initialized. */ -/****************************************************************/ - handle->map_fcn = map_fcn; - handle->map_env = map_env; - handle->debug_info_ptr = debug_info_ptr; - handle->tdesc_table = (tdesc_table_t)NULL; - - /* Find tdesc info. */ - if (debug_info_ptr) { - (*read_fcn) (read_env, debug_info_ptr, sizeof(unsigned int), - (char *)(&debug_info_protocol)); - if (debug_info_protocol != 1) - dc_error (handle, "Unrecognized debug info protocol: %d", - debug_info_protocol); - (*read_fcn) (read_env, debug_info_ptr, sizeof(dc_debug_info_t), - (char *)(&debug_info)); - (*read_fcn) (read_env, debug_info.tdesc_ptr, sizeof(unsigned int), - (char *)(&tdesc_map_protocol)); - if (tdesc_map_protocol != 1) - dc_error (handle, "Unrecognized tdesc map protocol: %d", - tdesc_map_protocol); - (*read_fcn) (read_env, debug_info.tdesc_ptr, sizeof(tdesc_hdr_t), - (char *)(&tdesc_hdr)); - tdesc_info_start = debug_info.tdesc_ptr + sizeof(tdesc_hdr_t); - tdesc_info_end = tdesc_hdr.end; - tdesc_info_length = tdesc_info_end - tdesc_info_start; - - /* Create tdesc table from tdesc info. */ - { - /* Over-allocate in order to avoid second pass over tdesc info. */ - tdesc_table_t tt = (tdesc_table_t) dc_malloc(handle, tdesc_info_length); - dc_word_t p = tdesc_info_start; - dc_word_t q = tdesc_info_end - sizeof(tdesc_chunk1_t); - int n = 0; - tdesc_chunk1_t chunk; - dc_word_t start_address, end_address; - int i; - - for (; p <= q; ) { - (*read_fcn) (read_env, p, sizeof(tdesc_chunk1_t), (char *)(&chunk)); - if (chunk.hdr.zeroes != 0) { - /* Skip padding. */ - p += sizeof(dc_word_t); - continue; - } - if (chunk.hdr.info_protocol != 1) { - dc_warn (handle, "Unrecognized tdesc info protocol: %d", - chunk.hdr.info_protocol); - goto next_chunk; - } - if (chunk.hdr.info_length != 16) { - dc_warn (handle, "Incorrect tdesc info length: %d", - chunk.hdr.info_length); - goto next_chunk; - } - if (chunk.hdr.info_alignment > 2) { - dc_warn (handle, "Incorrect tdesc info alignment: %d", - chunk.hdr.info_alignment); - goto next_chunk; - } - start_address = chunk.hdr.start_address; - end_address = chunk.hdr.end_address; - if ((start_address&3)!=0) { - dc_warn (handle, - "Tdesc start address is not word-aligned: %#.8X", - start_address); - goto next_chunk; - } - if ((end_address&3)!=0) { - dc_warn (handle, - "Tdesc end address is not word-aligned: %#.8X", - end_address); - goto next_chunk; - } - if (start_address > end_address) { - /* Note that the range may be null. */ - dc_warn (handle, - "Tdesc start address (%#.8X) follows end address (%#.8X).", - start_address, end_address); - goto next_chunk; - } - if (chunk.info.variant != 1) { - dc_warn (handle, "Invalid tdesc chunk variant: %d", - chunk.info.variant); - goto next_chunk; - } - if (chunk.info.pad1 != 0) { - dc_warn (handle, "Tdesc chunk padding is not zero."); - goto next_chunk; - } - if (chunk.info.return_address_info_discriminant != 0) { - if ((chunk.info.return_address_info & 3) != 0) { - dc_warn (handle, - "Tdesc return address offset is not word-aligned: %#.8X", - chunk.info.return_address_info); - goto next_chunk; - } - } else { - if ((chunk.info.return_address_info & ~31) != 0) { - dc_warn (handle, - "Invalid tdesc return address register: %d", - chunk.info.return_address_info); - goto next_chunk; - } - } - if ((chunk.info.register_save_offset & 3) != 0) { - dc_warn (handle, - "Tdesc register save offset is not word-aligned: %#.8X", - chunk.info.register_save_offset); - goto next_chunk; - } - - tt[n].start_address = start_address; - tt[n].end_address = end_address; - tt[n].info = chunk.info; - n++; - - next_chunk: - p += sizeof(tdesc_chunk1_t); - } - /* Leftover (less than a tdesc_chunk1_t in size) is padding or - in error. Ignore it in either case. */ - - if (n != 0) { - - /* Sort table by start address. */ - qsort ((char *)tt, n, sizeof(tdesc_elem_t), dc_compare_tdesc_elems); - - /* Check for overlap among tdesc chunks. */ - for (i=0; i<(n-1); i++) { - if (tt[i].end_address > tt[i+1].start_address) - dc_error (handle, "Text chunks overlap."); - } - } - - /* Finish setting up handle. */ - handle->tdesc_table = tt; - handle->tdesc_table_size = n; - } - } else { - handle->tdesc_table_size = 0; - } - - return (dc_handle_t) handle; -} - - -void dc_terminate (handle) - dc_handle_t handle; -{ - if (((dc_handle_t)handle)->tdesc_table) { - free((char *)(((dc_handle_t)handle)->tdesc_table)); - } - free((char *)handle); -} - - - -/* - - Dcontext Model - - For each interesting register (word-sized piece of machine state), - a word of value information is kept. This word may - be either the value of the register, or the address in - subject memory where the value can be found (and changed). In - addition, the register may be invalid (in which case the value - information is undefined). These three cases are encoded for - a given register in the same-numbered bit of two words of flags: - - flags[0] bit flags[1] bit meaning - ------------ ------------ ------- - 0 0 register is invalid; info is undefined - 0 1 register is readable; info is value - 1 0 register is writable; info is address - 1 1 (reserved) - - The general registers (r0-r31) are handled by reg_info and - reg_flags. The bit number for a register is that register's number. - The other registers are grouped together for convenience and are - handled by aux_info and aux_flags. The bit numbers for these - registers are: - - bit number register - ---------- -------- - 0 location - 1 SXIP - 2 SNIP - 3 SFIP - 4 FPSR - 5 FPCR - - The SXIP, SNIP, and SFIP are the exception-time values of the - XIP, NIP, and FIP registers. They are valid only in the topmost frame. - (That is, in any context obtained from dc_previous_context, they - are invalid.) - - "location" is a pseudo-register of this model and represents the - location of the context. It is always valid. It also has an - exactness associated with it. The location and its exactness of a - context obtained from dc_previous_context are taken from the - return address and its exactness of the context given as an argument - to dc_previous_context. - - The following model is recommended for dealing with the partial - redundancy between location and the SXIP, SNIP, and SFIP values - in the topmost frame. The location should be set to either the - SNIP or SXIP value, and its exactness should be set to DC_NO. A - change to the register whose value the location is set to should - be accompanied by an identical change to the location. - - The PSR is handled separately, because it is a diverse collection - of flags. The PSR, as a whole, is always valid. A separate - psr_ind flag tells whether the psr_info data is a value or - an address. Each bit of the PSR has its own pair of flag bits to - mark validity and writability. - -*/ - - -/* The following value means "other", because state is stored in 2 bits. */ -#define DC_RESERVED 3 - - -#define RSTATE(flags, bit) \ - ((bit_value((flags)[0], bit) << 1) + bit_value((flags)[1], bit)) - -#define REG_STATE(dcontext, reg) RSTATE(dcontext->reg_flags, reg) -#define AUX_STATE(dcontext, reg) RSTATE(dcontext->aux_flags, reg) -#define PSR_STATE(dcontext, reg) RSTATE(dcontext->psr_flags, reg) - - -#define SET_INVALID(flags, bit) \ - { bit_clear ((flags)[0], bit); bit_clear ((flags)[1], bit); } - -#define SET_READABLE(flags, bit) \ - { bit_clear ((flags)[0], bit); bit_set ((flags)[1], bit); } - -#define SET_WRITABLE(flags, bit) \ - { bit_set ((flags)[0], bit); bit_clear ((flags)[1], bit); } - -#define ASSIGN_RSTATE(to_flags, to_bit, from_flags, from_bit) \ - { bit_assign ((to_flags)[0], to_bit, bit_value((from_flags)[0], from_bit));\ - bit_assign ((to_flags)[1], to_bit, bit_value((from_flags)[1], from_bit));} - - -#define CHECK_REG_READ(dcontext, reg) \ - if (REG_STATE(dcontext, reg) == DC_INVALID) \ - dc_error (dcontext->handle, \ - "General register %d is not readable.", reg) - -#define CHECK_REG_WRITE(dcontext, reg) \ - if (REG_STATE(dcontext, reg) != DC_WRITABLE) \ - dc_error (dcontext->handle, \ - "General register %d is not writable.", reg) - -#define CHECK_AUX_READ(dcontext, reg) \ - if (AUX_STATE(dcontext, reg) == DC_INVALID) \ - dc_error (dcontext->handle, \ - "Auxiliary register %d is not readable.", reg) - -#define CHECK_AUX_WRITE(dcontext, reg) \ - if (AUX_STATE(dcontext, reg) != DC_WRITABLE) \ - dc_error (dcontext->handle, \ - "Auxiliary register %d is not writable.", reg) - - - -#define DC_REG_RA 1 -#define DC_REG_FP 30 -#define DC_REG_SP 31 -#define DC_NUM_REG 32 - -#define DC_AUX_LOC 0 - /* DC_AUX_LOC must be first, with value 0 */ -#define DC_AUX_SXIP 1 -#define DC_AUX_SNIP 2 -#define DC_AUX_SFIP 3 -#define DC_AUX_FPSR 4 -#define DC_AUX_FPCR 5 -#define DC_NUM_AUX 6 - - - -#define CHECK_REG(dcontext, reg) \ - if ((reg < 0) || (reg >= DC_NUM_REG)) \ - dc_error (dcontext->handle, \ - "Bad general register number: %d", reg) - -#define CHECK_AUX(dcontext, reg) \ - if ((reg < 1) || (reg >= DC_NUM_AUX)) \ - dc_error (dcontext->handle, \ - "Bad auxiliary register number: %d", reg) - /* CHECK_AUX is not used for location pseudo-register. */ - -#define CHECK_BIT(dcontext, bit) \ - if ((bit < 0) || (bit >= 32)) \ - dc_error (dcontext->handle, \ - "Bad bit number: %d", bit) - - - -typedef struct cr_value { - int reg; - unsigned int off; - } dc_cr_value_t; - -#define DC_UNDEF 32 - -/* - A "dc_cr_value" represents an execution-time value symbolically, in - terms of the initial value of a register (the value on entry to - the procedure being analyzed) and a known offset. A value with - a 'reg' field value of 0 through 31 represents the value obtained - by summing (using 32-bit modulus arithmetic) the initial value of - register 'reg' and the value 'off'. Note that the value (0,k) - represents the constant value k, that (31,0) represents the CFA, and - that (1,0) represents the return address. A value with a 'reg' field - of DC_UNDEF represents an indeterminable value; in this case the - 'off' field is undefined. Other values of 'reg' are erroneous. -*/ - -typedef struct cr_data { - dc_cr_value_t reg_val[DC_NUM_REG]; - dc_word_t saved; - dc_word_t how; - unsigned int where[DC_NUM_REG]; -} dc_cr_data_t; - -/* - 'cr_data' collects all the information needed to represent the - symbolic machine state during code reading. - - The 'reg_val' array gives the current dc_cr_value for each register. - - The 'saved', 'how', and 'where' fields combine to describe what - registers have been saved, and where. The 'saved' and 'how' fields - are implicitly bit arrays over 0..31, where the numbering is from - 0 on the right. (Hence, 1<<r gives the mask for register r.) - If saved[r] is 0, the register is not saved, and how[r] and where[r] - are undefined. If saved[r] is 1, then how[r] tells whether register r - was saved in another register (how[r]==0) or in the frame (how[r]==1). - In the former case, where[r] gives the register number; in the latter - case, where[r] gives the frame position. -*/ - - -typedef int dc_register_state_t; /* range 0 to 2 */ - -#define DC_INVALID 0 -#define DC_READABLE 1 -#define DC_WRITABLE 2 - - - - -typedef struct dcontext_info { - dc_handle_t handle; /* environment of context */ - dc_word_t reg_info[DC_NUM_REG]; - dc_word_t reg_flags[2]; - dc_word_t aux_info[DC_NUM_AUX]; - dc_word_t aux_flags[2]; - dc_exactness_t loc_exact; - dc_word_t psr_info; /* value or address */ - dc_word_t psr_ind; /* DC_TRUE iff address */ - dc_word_t psr_flags[2]; /* per-PSR-bit flags */ - unsigned int code_reading; /* no tdesc therefore must read code*/ - union { - tdesc_elem_t *tdesc_elem_ptr; /* locates tdesc chunk */ - dc_cr_data_t *cr_data_ptr; /* or code reading data */ - } info_ptr; -} dcontext_info_t; - -typedef dcontext_info_t *dc_dcontext_t; - -dc_word_t dc_get_value (handle, info, flags, pos) - dc_handle_t handle; - dc_word_t info[]; - dc_word_t flags[2]; - int pos; - /* Assumes either DC_READABLE or DC_WRITABLE. */ -{ - if (bit_test(flags[0], pos)) { - /* DC_WRITABLE case */ - return dc_read_word(handle, info[pos]); - } else { - /* DC_READABLE case */ - return info[pos]; - } -} - -void dc_set_value (handle, info, flags, pos, value) - dc_handle_t handle; - dc_word_t info[]; - dc_word_t flags[2]; - int pos; - dc_word_t value; - /* Assumes DC_WRITABLE. */ -{ - dc_write_word(handle, info[pos], value); -} - - -#define GET_REG_VALUE(dcontext, reg) \ - dc_get_value(dcontext->handle, dcontext->reg_info, dcontext->reg_flags, reg) - -#define SET_REG_VALUE(dcontext, reg, value) \ - dc_set_value(dcontext->handle, dcontext->reg_info, dcontext->reg_flags, reg, \ - value) - -#define GET_AUX_VALUE(dcontext, reg) \ - dc_get_value(dcontext->handle, dcontext->aux_info, dcontext->aux_flags, reg) - -#define SET_AUX_VALUE(dcontext, reg, value) \ - dc_set_value(dcontext->handle, dcontext->aux_info, dcontext->aux_flags, reg, \ - value) - - - -void dc_check_dcontext (dc) - dc_dcontext_t dc; - /* Check consistency of information supplied to make a dcontext. */ -{ - int i; - - if ((REG_STATE(dc, 0) != DC_READABLE) || (dc->reg_info[0] != 0)) - dc_error (dc->handle, "Register 0 is misspecified"); - for (i = 1; i < DC_NUM_REG; i++) - if (REG_STATE(dc, i) == DC_RESERVED) - dc_error (dc->handle, - "State for general register %d is incorrect", i); - for (i = 0; i < DC_NUM_AUX; i++) - if (AUX_STATE(dc, i) == DC_RESERVED) - dc_error (dc->handle, - "State for auxiliary register %d is incorrect", i); - if (AUX_STATE(dc, DC_AUX_LOC) == DC_INVALID) - dc_error (dc->handle, "Location is specified as invalid"); - if (GET_AUX_VALUE(dc, DC_AUX_LOC) == 0) - dc_error (dc->handle, "Location is zero."); - if (dc->loc_exact >= 3) - dc_error (dc->handle, "Location exactness is incorrectly specified: %d", - dc->loc_exact); - if (dc->psr_ind >= 2) - dc_error (dc->handle, - "PSR indirection flag is incorrectly specified: %d", - dc->psr_ind); - for (i = 0; i < 32; i++) - if (PSR_STATE(dc, i) == DC_RESERVED) - dc_error (dc->handle, "State for PSR bit %d is incorrect", i); -} - - - -tdesc_elem_t * dc_tdesc_lookup (loc, tt, tt_size, map_info_in_ptr) - dc_word_t loc; - tdesc_table_t tt; - int tt_size; - dc_map_info_in_t *map_info_in_ptr; - /* Return address of tdesc_elem_t for given location, or NULL if - there is no tdesc chunk for the location. - */ -{ - int l = 0; - int h = tt_size; - int m; - - if (tt_size == 0) { - map_info_in_ptr->flags = 0; - return (tdesc_elem_t *)NULL; - } - for (;;) { - m = (l + h) / 2; - if (m == l) break; - if (loc >= tt[m].start_address) - l = m; - else - h = m; - } - if (loc >= tt[m].end_address) { - map_info_in_ptr->preceding_tdesc_end = tt[m].end_address; - if (m+1 < tt_size) { - map_info_in_ptr->following_tdesc_start = tt[m+1].start_address; - map_info_in_ptr->flags = DC_MII_PRECEDING_TDESC_END | - DC_MII_FOLLOWING_TDESC_START; - } else { - map_info_in_ptr->flags = DC_MII_PRECEDING_TDESC_END; - } - return (tdesc_elem_t *)NULL; - } else if (loc < tt[m].start_address) { - map_info_in_ptr->following_tdesc_start = tt[m].start_address; - map_info_in_ptr->flags = DC_MII_FOLLOWING_TDESC_START; - return (tdesc_elem_t *)NULL; - } else { - return (&tt[m]); - } -} - - - -dc_dcontext_t dc_make_dcontext (handle, - reg_info, reg_flags, - aux_info, aux_flags, loc_exact, - psr_info, psr_ind, psr_flags) - dc_handle_t handle; - dc_word_t reg_info[DC_NUM_REG]; - dc_word_t reg_flags[2]; - dc_word_t aux_info[DC_NUM_AUX]; - dc_word_t aux_flags[2]; - dc_exactness_t loc_exact; - dc_word_t psr_info; - dc_boolean_t psr_ind; - dc_word_t psr_flags[2]; -{ - dc_dcontext_t dc = (dc_dcontext_t) dc_malloc (handle, sizeof(dcontext_info_t)); - int i; - dc_map_info_in_t map_info_in; - - /* Fill in supplied content. */ - dc->handle = ((dc_handle_t)handle); - for (i = 0; i < DC_NUM_REG; i++) dc->reg_info[i] = reg_info[i]; - for (i = 0; i < 2; i++) dc->reg_flags[i] = reg_flags[i]; - for (i = 0; i < DC_NUM_AUX; i++) dc->aux_info[i] = aux_info[i]; - for (i = 0; i < 2; i++) dc->aux_flags[i] = aux_flags[i]; - dc->loc_exact = loc_exact; - dc->psr_info = psr_info; - dc->psr_ind = psr_ind; - for (i = 0; i < 2; i++) dc->psr_flags[i] = psr_flags[i]; - - dc_check_dcontext(dc); - - /* Find tdesc information for the text chunk. */ - { -/***************************************************************/ -/* BUG 8/16/89 Found by hls. Not zeroing EV bits of location. */ -/* SHOULD USE dc_location()! */ -/* dc_word_t loc = GET_AUX_VALUE(dc, DC_AUX_LOC); */ -/***************************************************************/ - dc_word_t loc = GET_AUX_VALUE(dc, DC_AUX_LOC) & ~3; - tdesc_elem_t *tep = - dc_tdesc_lookup(loc, ((dc_handle_t)handle)->tdesc_table, - ((dc_handle_t)handle)->tdesc_table_size,&map_info_in); - if (tep) { - dc->code_reading = 0; - dc->info_ptr.tdesc_elem_ptr = tep; - } else { - dc->code_reading = 1; - if (!dc->handle->map_fcn) { - dc_error (dc->handle, "No tdesc information for %#.8X and no map function supplied.",loc); - } -/****************************************************************/ -/* BUG 9/18/89 Found by hls. Not using dc_malloc() */ -/* dc->info_ptr.cr_data_ptr= (dc_cr_data_t *)malloc(sizeof(dc_cr_data_t )); */ -/****************************************************************/ - dc->info_ptr.cr_data_ptr= (dc_cr_data_t *)dc_calloc(dc->handle,1,sizeof(dc_cr_data_t )); - dc_read_code(loc,dc,map_info_in,dc->info_ptr.cr_data_ptr); - } - } - - return (dc_dcontext_t) dc; -} - - - -void dc_free_dcontext (dcontext) - dc_dcontext_t dcontext; -{ -/****************************************************************/ -/* BUG 9/19/89 Found by hls. Freeing non-pointer value. */ -/* free((char *)dcontext->code_reading); */ -/****************************************************************/ - if (dcontext->code_reading) - free((char *)dcontext->info_ptr.cr_data_ptr); - free((char *)dcontext); -} - - - -dc_register_state_t dc_location_state (dcontext) - dc_dcontext_t dcontext; -{ - return AUX_STATE(((dc_dcontext_t)dcontext), DC_AUX_LOC); -} - - -dc_exactness_t dc_location_exactness (dcontext) - dc_dcontext_t dcontext; -{ - return ((dc_dcontext_t)dcontext)->loc_exact; -} - - -dc_word_t dc_location (dcontext) - dc_dcontext_t dcontext; - /* Return high 30 bits only. */ -{ - /* Don't need: CHECK_AUX_READ (((dc_dcontext_t)dcontext), DC_AUX_LOC); */ - return GET_AUX_VALUE (((dc_dcontext_t)dcontext), DC_AUX_LOC) & ~3; -} - - -dc_boolean_t dc_location_in_text_chunk( dcontext, value ) - dc_dcontext_t dcontext; - dc_word_t value; -{ - /* Check that new location is still within same text chunk. */ - tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr; -/********************************************************************/ -/* Bug in predicate -- LS adjusted according to OCS documentation.. */ -/* if ((value < tep->start_address) || (value >= tep->end_address))*/ -/********************************************************************/ - if ((value >= tep->start_address) && (value < tep->end_address)) - return DC_TRUE; - else - return DC_FALSE; - -} - - -void dc_set_location (dcontext, value) - dc_dcontext_t dcontext; - dc_word_t value; - /* Set high 30 bits only. */ -{ - if (dc_location_in_text_chunk( dcontext, value ) != DC_TRUE) - dc_warn (((dc_dcontext_t)dcontext)->handle, - "New location is not in same text chunk."); - - CHECK_AUX_WRITE (((dc_dcontext_t)dcontext), DC_AUX_LOC); - dc_write_masked_word (((dc_dcontext_t)dcontext)->handle, - ((dc_dcontext_t)dcontext)->aux_info[DC_AUX_LOC], ~3, value); -} - - - -dc_register_state_t dc_general_register_state (dcontext, reg) - dc_dcontext_t dcontext; - int reg; -{ - CHECK_REG (((dc_dcontext_t)dcontext), reg); - return REG_STATE(((dc_dcontext_t)dcontext), reg); -} - - -dc_word_t dc_general_register (dcontext, reg) - dc_dcontext_t dcontext; - int reg; -{ - CHECK_REG (((dc_dcontext_t)dcontext), reg); - CHECK_REG_READ (((dc_dcontext_t)dcontext), reg); - return GET_REG_VALUE(((dc_dcontext_t)dcontext), reg); -} - - -void dc_set_general_register (dcontext, reg, value) - dc_dcontext_t dcontext; - int reg; - dc_word_t value; -{ - CHECK_REG (((dc_dcontext_t)dcontext), reg); - CHECK_REG_WRITE (((dc_dcontext_t)dcontext), reg); - SET_REG_VALUE (((dc_dcontext_t)dcontext), reg, value); -} - - - -dc_register_state_t dc_auxiliary_register_state (dcontext, reg) - dc_dcontext_t dcontext; - int reg; -{ - CHECK_AUX (((dc_dcontext_t)dcontext), reg); - return AUX_STATE(((dc_dcontext_t)dcontext), reg); -} - - -dc_word_t dc_auxiliary_register (dcontext, reg) - dc_dcontext_t dcontext; - int reg; -{ - CHECK_AUX (((dc_dcontext_t)dcontext), reg); - CHECK_AUX_READ (((dc_dcontext_t)dcontext), reg); - return GET_AUX_VALUE(((dc_dcontext_t)dcontext), reg); -} - - -void dc_set_auxiliary_register (dcontext, reg, value) - dc_dcontext_t dcontext; - int reg; - dc_word_t value; -{ - CHECK_AUX (((dc_dcontext_t)dcontext), reg); - CHECK_AUX_WRITE (((dc_dcontext_t)dcontext), reg); - SET_AUX_VALUE (((dc_dcontext_t)dcontext), reg, value); -} - - - -dc_register_state_t dc_psr_register_bit_state (dcontext, bit) - dc_dcontext_t dcontext; - int bit; -{ - CHECK_BIT (((dc_dcontext_t)dcontext), bit); - return PSR_STATE(((dc_dcontext_t)dcontext), bit); -} - - -dc_word_t dc_psr_register (dcontext) - dc_dcontext_t dcontext; -{ - if (((dc_dcontext_t)dcontext)->psr_ind) { - return dc_read_word(((dc_dcontext_t)dcontext)->handle, - ((dc_dcontext_t)dcontext)->psr_info); - } else { - return ((dc_dcontext_t)dcontext)->psr_info; - } -} - - -void dc_set_psr_register (dcontext, mask, value) - dc_dcontext_t dcontext; - dc_word_t mask; - dc_word_t value; - /* Set bits of PSR corresponding to 1 bits in mask. */ -{ - if (((dc_dcontext_t)dcontext)->psr_ind) { - if (((((dc_dcontext_t)dcontext)->psr_flags[0] & mask) != mask) || - ((((dc_dcontext_t)dcontext)->psr_flags[1] & mask) != 0)) - dc_error (((dc_dcontext_t)dcontext)->handle, - "Some PSR bits specified are not writable."); - dc_write_masked_word (((dc_dcontext_t)dcontext)->handle, - ((dc_dcontext_t)dcontext)->psr_info, mask, value); - } else { - dc_error (((dc_dcontext_t)dcontext)->handle, "PSR is not writable."); - } -} - - - -dc_word_t dc_frame_address (dcontext) - dc_dcontext_t dcontext; -{ - if (!dcontext->code_reading) { - tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr; - return dc_general_register(dcontext, - tep->info.frame_address_register) + tep->info.frame_address_offset; - } else { - if (dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_FP].reg == DC_REG_SP) { - return (dc_general_register(dcontext,DC_REG_FP) - - dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_FP].off); - } - if (dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_SP].reg == DC_REG_SP) { - return (dc_general_register(dcontext,DC_REG_SP) - - dcontext->info_ptr.cr_data_ptr->reg_val[DC_REG_SP].off); - } - dc_error (((dc_dcontext_t)dcontext)->handle, "Cannot locate frame pointer."); - } -} - - - -dc_kind_t dc_context_kind (dcontext) - dc_dcontext_t dcontext; -{ - return DC_CALL_KIND; -} - - - - -/* operations valid for call contexts only */ - - -dc_register_state_t dc_return_address_state (dcontext) - dc_dcontext_t dcontext; -{ - tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr; - int reg; - - if (!dcontext->code_reading) { - if (tep->info.return_address_info_discriminant) { - return DC_WRITABLE; - } else { - return REG_STATE(((dc_dcontext_t)dcontext), tep->info.return_address_info); - } - } else { - reg= DC_REG_RA; - if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,DC_REG_RA)) { - if (bit_test(dcontext->info_ptr.cr_data_ptr->how,DC_REG_RA)) { - return DC_WRITABLE; - } else { - reg= dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]; - } - } - return REG_STATE(((dc_dcontext_t)dcontext),reg); - - - } -} - - -dc_exactness_t dc_return_address_exactness (dcontext) - dc_dcontext_t dcontext; -{ - return DC_MAYBE; -} - - -dc_word_t dc_return_address (dcontext) - dc_dcontext_t dcontext; - /* Return high 30 bits only. */ -{ - tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr; - dc_word_t rai = tep->info.return_address_info; - dc_word_t val; - int reg; - - if (!dcontext->code_reading) { - if (tep->info.return_address_info_discriminant) { - val = dc_read_word (((dc_dcontext_t)dcontext)->handle, - dc_frame_address(dcontext) + rai); - } else { - val = dc_general_register (dcontext, rai); - } - } else { - reg=DC_REG_RA; - if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,reg)) { - if (bit_test(dcontext->info_ptr.cr_data_ptr->how,reg)) { - val = dc_read_word (((dc_dcontext_t)dcontext)->handle, - dc_frame_address(dcontext) + - (dcontext->info_ptr.cr_data_ptr->where[reg])); - } else { - reg= dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]; - val = dc_general_register (dcontext, reg); - } - } else { - val = dc_general_register (dcontext, reg); - } - } - return val & ~3; -} - - -void dc_set_return_address (dcontext, value) - dc_dcontext_t dcontext; - dc_word_t value; - /* Set high 30 bits only. */ -{ - if (!dcontext->code_reading) { - tdesc_elem_t *tep = ((dc_dcontext_t)dcontext)->info_ptr.tdesc_elem_ptr; - dc_word_t rai = tep->info.return_address_info; - - if (tep->info.return_address_info_discriminant) { - dc_write_masked_word (((dc_dcontext_t)dcontext)->handle, - dc_frame_address(dcontext) + rai, ~3, value); - } else { - dc_set_general_register (dcontext, rai, - (value & ~3) | (dc_general_register(dcontext, rai) & 3)); - } - } else { - if (bit_test(dcontext->info_ptr.cr_data_ptr->saved,DC_REG_RA)) { - if (bit_test(dcontext->info_ptr.cr_data_ptr->how,DC_REG_RA)) { - dc_write_masked_word (((dc_dcontext_t)dcontext)->handle, - dc_frame_address(dcontext) - + dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA], ~3, value); - } else { - dc_set_general_register( dcontext, - dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]); - } - } else { - dc_set_general_register( dcontext, - dcontext->info_ptr.cr_data_ptr->where[DC_REG_RA]); - } - } -} - - - -/* operations valid for save contexts only */ - -/* (none) */ - - - -/* operations valid for exception contexts only */ - - -void dc_get_exception_info (dcontext, handler, datum) - dc_dcontext_t dcontext; - dc_word_t *handler; - dc_word_t *datum; -{ - dc_error (((dc_dcontext_t)dcontext)->handle, - "dc_get_exception_info is not yet implemented."); -} - - - -/* operations valid for protection contexts only */ - - -void dc_get_protection_info (dcontext, handler, datum) - dc_dcontext_t dcontext; - dc_word_t *handler; - dc_word_t *datum; -{ - dc_error (((dc_dcontext_t)dcontext)->handle, - "dc_get_protection_info is not yet implemented."); -} - - - -/* operations valid for special contexts only */ - - -void dc_get_special_info (dcontext, kind, datum) - dc_dcontext_t dcontext; - dc_word_t *kind; - dc_word_t *datum; -{ - dc_error (((dc_dcontext_t)dcontext)->handle, - "dc_get_special_info is not yet implemented."); -} - - - -/* operations valid for all contexts (again) */ - - -dc_dcontext_t dc_previous_dcontext (dcontext) - dc_dcontext_t dcontext; - /* Return NULL if there is no previous context. */ -{ - dc_dcontext_t old = (dc_dcontext_t) dcontext; - dcontext_info_t new; /* to serve as temporary storage only */ - tdesc_elem_t *tep; - dc_cr_data_t *cdp; - dc_word_t cfa; - int rsm; - dc_word_t offset; - dc_word_t rai; - int r; - - if (dc_return_address_state((dc_dcontext_t)old) == DC_INVALID) - dc_error (old->handle, "Return address is invalid."); - - if (dc_return_address((dc_dcontext_t)old) == 0) - return (dc_dcontext_t)NULL; /* end of the chain */ - - /* Copy over old contents. */ - new = *old; - - cfa = dc_frame_address(old); - /* Restore stack pointer. */ - new.reg_info[DC_REG_SP] = cfa; - SET_READABLE (new.reg_flags, DC_REG_SP); - - /* Invalidate temporary registers. */ - for (r = 1; r <= 13; r++) SET_INVALID (new.reg_flags, r); - - if (!old->code_reading) { - tep = old->info_ptr.tdesc_elem_ptr; - /* Restore preserved registers. */ - rsm = tep->info.register_save_mask; - offset = cfa + tep->info.register_save_offset; - for (r = 14; r <= 30; r++) { - if (bit_test(rsm, 30-r)) { - new.reg_info[r] = offset; - SET_WRITABLE (new.reg_flags, r); - offset += sizeof(dc_word_t); - } - } - - /* Set location from old return address. */ - rai = tep->info.return_address_info; - if (tep->info.return_address_info_discriminant) { - new.aux_info[DC_AUX_LOC] = cfa + rai; - SET_WRITABLE (new.aux_flags, DC_AUX_LOC); - } else { - new.aux_info[DC_AUX_LOC] = old->reg_info[rai]; - ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, old->reg_flags, rai); - } - } else { - cdp = old->info_ptr.cr_data_ptr; - - /* Restore preserved registers. */ - for (r = 14; r <= 30; r++) { - if (bit_test(cdp->saved,r)) { - if (bit_test(cdp->how,r)){ /* saved in the frame */ - new.reg_info[r] = cfa+cdp->where[r]; - SET_WRITABLE (new.reg_flags, r); - } else { /* saved in the in a register */ - new.reg_info[r] = dc_general_register(old,cdp->where[r]); - ASSIGN_RSTATE (new.aux_flags, r, old->reg_flags, cdp->where[r]); - } - } /* not saved, therefore, already valid , no else*/ - } - - /* Set location from old return address. */ - if (bit_test(cdp->saved,DC_REG_RA)) { - if (bit_test(cdp->how,DC_REG_RA)){ /* saved in the frame */ - new.aux_info[DC_AUX_LOC] = - new.reg_info[DC_REG_RA] = cfa+cdp->where[DC_REG_RA]; - SET_WRITABLE (new.reg_flags, DC_REG_RA); - SET_WRITABLE (new.aux_flags, DC_AUX_LOC); - } else { /* saved in the in a register */ - new.reg_info[DC_REG_RA] = - new.aux_info[DC_AUX_LOC] = - dc_general_register(old,cdp->where[DC_REG_RA]); - ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, - old->reg_flags, cdp->where[DC_REG_RA]); - } - } else { /* not saved, therefore, already valid , set DC_AUX_LOC only*/ - new.aux_info[DC_AUX_LOC] = - dc_general_register(old,DC_REG_RA); - ASSIGN_RSTATE (new.aux_flags, DC_AUX_LOC, - old->reg_flags, DC_REG_RA); - } - } - - /* Invalidate instruction pointers. */ - SET_INVALID (new.aux_flags, DC_AUX_SXIP); - SET_INVALID (new.aux_flags, DC_AUX_SNIP); - SET_INVALID (new.aux_flags, DC_AUX_SFIP); - - /* No change to FCR registers. */ - - /* No change to PSR register. */ - - return dc_make_dcontext ((dc_handle_t)new.handle, - new.reg_info, new.reg_flags, - new.aux_info, new.aux_flags, new.loc_exact, - new.psr_info, new.psr_ind, new.psr_flags); -} - - - -/* extensions for nonlocal goto */ - -#if 0 - -typedef - struct label { - ??? - } label_t; - - -label_t dc_make_label (dcontext, location) - dc_dcontext_t dcontext; - dc_word_t location; -{ -} - -#endif - -/* procedure for reading code */ - -dc_read_code(loc,dc,map_info_in,cdp) -dc_word_t loc; -dc_dcontext_t dc; -dc_cr_data_t *cdp; -dc_map_info_in_t map_info_in; -{ -dc_map_info_out_t map_info_out; -dc_word_t pc; -dc_boolean_t found_branch=DC_FALSE; -dc_word_t instr; - - (*dc->handle->map_fcn)(dc->handle->map_env,loc,map_info_in,&map_info_out); - if (map_info_out.flags & DC_MIO_ENTRY_POINT - && (!(map_info_in.flags & DC_MII_PRECEDING_TDESC_END) - || map_info_out.entry_point >= map_info_in.preceding_tdesc_end - || map_info_out.flags & DC_MIO_LITERAL_ENTRY_POINT)) { - dc_init_cr_data(cdp,(tdesc_elem_t *)NULL); - pc= map_info_out.entry_point; - } else if (map_info_in.flags & DC_MII_PRECEDING_TDESC_END) { - /**/ - /* tdesc_lookup gets the tep for the preceeding tdesc information - /* so we call it with one less than the preceding tdesc end since - /* tdesc information is exclusive of the ending address - /**/ - dc_init_cr_data(cdp, - dc_tdesc_lookup(map_info_in.preceding_tdesc_end-1, - ((dc_handle_t)dc->handle)->tdesc_table, - ((dc_handle_t)dc->handle)->tdesc_table_size, - &map_info_in)); - pc= map_info_in.preceding_tdesc_end; - } else { - dc_error (dc->handle, "Insufficient information for code reading."); - } - for (;;pc+=4) { - if (pc==loc) { - return (DC_TRUE); - } - instr= dc_read_word(dc->handle,pc); - found_branch= dc_decode_finds_branch(dc,instr); - if ((map_info_out.flags & DC_MIO_PROLOGUE_END) - && (pc==map_info_out.prologue_end)) { - break; - } - if (found_branch) { - if (DC_MIO_IMPLICIT_PROLOGUE_END & map_info_out.flags) { - break; - } else { - dc_error (dc->handle, "Found branch before end of prologue."); - } - } - } - if (!(map_info_out.flags & DC_MIO_LITERAL_EPILOGUE_START) - && (map_info_out.epilogue_start >= loc - || !(map_info_out.flags & DC_MIO_EPILOGUE_START))) { - return (DC_TRUE); - } - dc_correct_cr_data(cdp,dc->handle); - for (pc=map_info_out.epilogue_start;pc<loc;pc+=4) { - instr= dc_read_word(dc->handle,pc); - if (dc_decode_finds_branch(dc,instr)) { - return (DC_FALSE); - } - } - return (DC_TRUE); - -} - - - -dc_init_cr_data(cdp,tep) -dc_cr_data_t *cdp; -tdesc_elem_t *tep; -{ -int reg; -dc_word_t rai; -dc_word_t raid; -dc_word_t rsm; -dc_word_t frpos; - - if (tep){ - - /* Start off with all registers undefined and none saved. */ - for (reg = 0; reg < DC_NUM_REG; reg++) { - cdp->reg_val[reg].reg = DC_UNDEF; - } - cdp->saved = 0; - - /* Overwrite with what tdesc element says. */ - - cdp->reg_val[tep->info.frame_address_register].reg = DC_REG_SP; - cdp->reg_val[tep->info.frame_address_register].off = - - tep->info.frame_address_offset; - - rai = tep->info.return_address_info; - raid = tep->info.return_address_info_discriminant; - if (raid || rai != DC_REG_RA) { - bit_set(cdp->saved,DC_REG_RA); - bit_assign(cdp->how,DC_REG_RA,raid); - cdp->where[DC_REG_RA] = rai; - } - - rsm = tep->info.register_save_mask; - frpos = tep->info.register_save_offset; - for (reg = 14; reg <= 30; reg++) { - if (bit_test(rsm, 30-reg)) { - bit_set(cdp->saved,reg); - bit_set(cdp->how,reg); - cdp->where[reg] = frpos; - frpos += sizeof(dc_word_t); - } else { - cdp->reg_val[reg].reg = reg; - cdp->reg_val[reg].off = 0; - } - } - - cdp->reg_val[0].reg = 0; /* guarantee what hardware does */ - cdp->reg_val[0].off = 0; - - } else { - /* Each register has its own initial value. */ - for (reg = 0; reg < DC_NUM_REG; reg++) { - cdp->reg_val[reg].reg = reg; - cdp->reg_val[reg].off = 0; - } - /* No register is yet saved. */ - cdp->saved = 0; - cdp->how = 0; - } -} -void dc_correct_cr_data(cdp,handle) -dc_cr_data_t *cdp; -dc_handle_t handle; -{ -long sr,r; -dc_word_t save_regs = 0; /* registers used to save others */ - for (r = 1; r < DC_REG_SP; r++) { - if (bit_test(cdp->saved,r) && !bit_test(cdp->how,r)) { - sr = cdp->where[r]; - if (bit_test(save_regs,sr)) { - dc_error(handle, "Same register used to save two others."); - } - bit_set(save_regs,sr); - } - } - for (r = 1; r < DC_REG_FP; r++) { - if ((r < 14 || bit_test(cdp->saved,r)) && !bit_test(save_regs,r)) { - cdp->reg_val[r].reg = DC_UNDEF; - } - } - if (bit_test(cdp->saved,DC_REG_FP) && - cdp->reg_val[DC_REG_FP].reg == DC_REG_SP) { /* is r30 the far? */ - cdp->reg_val[DC_REG_SP].reg = DC_UNDEF; /* trash sp */ - } else if (cdp->reg_val[DC_REG_SP].reg == DC_REG_SP) { /* is r31 the far? */ - if (bit_test(cdp->saved,DC_REG_FP) && !bit_test(save_regs,DC_REG_FP)) { - cdp->reg_val[DC_REG_FP].reg = DC_UNDEF; /* trash r30 */ - } - } -} |