blob: adfd14979e93ebc3fb537ce93d369414570fdfc2 [file] [log] [blame]
/*******************************************************************************
* 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.
*
* 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 <config.h>
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 */