/******************************************************************************* * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * You may elect to redistribute this code under either of these licenses. * * Contributors: * Wind River Systems - initial API and implementation *******************************************************************************/ /* * This module contains definitions of target CPU registers and stack frames. */ #ifndef D_cpudefs #define D_cpudefs #include typedef struct Context Context; /* Type to represent byte address inside context memory */ #if ENABLE_ContextProxy typedef uint64_t ContextAddress; #else typedef uintptr_t ContextAddress; #endif #if ENABLE_DebugContext #define REGNUM_DWARF 1 #define REGNUM_EH_FRAME 2 typedef struct RegisterData RegisterData; typedef struct RegisterDefinition RegisterDefinition; typedef struct NamedRegisterValue NamedRegisterValue; struct NamedRegisterValue { uint8_t * value; const char * name; const char * description; }; struct RegisterDefinition { const char * name; /* pointer to register name */ size_t offset; /* offset to entry in REG_SET */ size_t size; /* register size in bytes */ int16_t dwarf_id; /* ID of the register in DWARF sections, or -1 */ int16_t eh_frame_id; /* ID of the register in .eh_frame section, or -1 */ uint8_t big_endian; /* 0 - little endian, 1 - big endian */ uint8_t fp_value; /* true if the register value is a floating-point value */ uint8_t no_read; /* true if context value can not be read */ uint8_t no_write; /* true if context value can not be written */ uint8_t read_once; /* true if reading the context (register) destroys its current value */ uint8_t write_once; /* true if register value can not be overwritten - every write counts */ uint8_t side_effects; /* true if writing the context can change values of other registers */ uint8_t volatile_value;/* true if the register value can change even when target is stopped */ uint8_t left_to_right; /* true if the lowest numbered bit should be shown to user as the left-most bit */ int first_bit; /* bit numbering base (0 or 1) to use when showing bits to user */ int * bits; /* if context is a bit field, contains the field bit numbers in the parent register definition, -1 marks end of the list */ RegisterDefinition * parent; /* parent register definition, NULL for top level definitions */ NamedRegisterValue ** values; /* predefined names (mnemonics) for some of register values */ ContextAddress memory_address;/* the address of a memory mapped register */ const char * memory_context;/* the context ID of a memory context in which a memory mapped register is located */ const char * role; /* the role the register plays in a program execution */ }; /* Stack tracing command codes */ #define SFT_CMD_NUMBER 1 #define SFT_CMD_REGISTER 2 #define SFT_CMD_FP 3 #define SFT_CMD_DEREF 4 #define SFT_CMD_ADD 5 #define SFT_CMD_SUB 6 #define SFT_CMD_AND 7 #define SFT_CMD_OR 8 /* Stack tracing command */ typedef struct StackTracingCommand { int cmd; int64_t num; size_t size; int big_endian; RegisterDefinition * reg; } StackTracingCommand; /* Stack tracing command sequence */ typedef struct StackTracingCommandSequence { RegisterDefinition * reg; int cmds_cnt; int cmds_max; StackTracingCommand cmds[1]; } StackTracingCommandSequence; /* Complete stack tracing info for a range of instruction addresses */ typedef struct StackTracingInfo { ContextAddress addr; ContextAddress size; StackTracingCommandSequence * fp; StackTracingCommandSequence ** regs; int reg_cnt; } StackTracingInfo; #define STACK_BOTTOM_FRAME 0 #define STACK_NO_FRAME (-1) #define STACK_TOP_FRAME (-2) typedef struct StackFrame { int is_top_frame; Context * ctx; ContextAddress fp; /* frame address */ RegisterData * regs; /* register values */ } StackFrame; typedef struct RegisterIdScope { uint16_t machine; uint8_t os_abi; uint8_t big_endian; uint8_t id_type; } RegisterIdScope; /* Return array of CPU register definitions. Last item in the array has name == NULL */ extern RegisterDefinition * get_reg_definitions(Context * ctx); /* Search register definition for given register ID, return NULL if not found */ extern RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope * scope); /* Return register definition of instruction pointer */ extern RegisterDefinition * get_PC_definition(Context * ctx); /* Read register value from stack frame data, return 0 on success, return -1 and set errno if register is not available */ extern int read_reg_value(StackFrame * frame, RegisterDefinition * reg_def, uint64_t * value); /* Write register value into stack frame data, return 0 on success, return -1 and set errno if register is not available */ extern int write_reg_value(StackFrame * frame, RegisterDefinition * reg_def, uint64_t value); /* Read register bytes from stack frame data, return 0 on success, return -1 and set errno if register is not available */ extern int read_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf); /* Write register bytes into stack frame data, return 0 on success, return -1 and set errno if register is not available */ extern int write_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf); /* Get instruction pointer (PC) value */ extern ContextAddress get_regs_PC(Context * ctx); /* Set instruction pointer (PC) value */ extern void set_regs_PC(Context * ctx, ContextAddress y); /* Get TCF ID of a stack frame */ extern const char * frame2id(Context * ctx, int frame); /* Get stack frame for TCF ID */ extern int id2frame(const char * id, Context ** ctx, int * frame); /* Get TCF ID of a register */ extern const char * register2id(Context * ctx, int frame, RegisterDefinition * reg); /* Get register for TCF ID */ extern int id2register(const char * id, Context ** ctx, int * frame, RegisterDefinition ** reg_def); /* Get breakpoint instruction code and size */ extern uint8_t * get_break_instruction(Context * ctx, size_t * size); /* * Retrieve stack frame information by examining stack data in memory. * * "frame" is current frame info, it should have frame->regs and frame->mask filled with * proper values before this function is called. * * "down" is next frame - moving from stack top to the bottom. * * The function uses register values in current frame to calculate frame address "frame->fp", * and calculate register values in the next frame. */ extern int crawl_stack_frame(StackFrame * frame, StackFrame * down); /* Execute stack tracing command sequence */ extern uint64_t evaluate_stack_trace_commands(Context * ctx, StackFrame * frame, StackTracingCommandSequence * cmds); #endif /* ENABLE_DebugContext */ #endif /* D_cpudefs */