Skip to main content
summaryrefslogtreecommitdiffstats
blob: 0df38265b131036332827f89f768c1604acc38e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/*******************************************************************************
 * Copyright (c) 2007, 2013 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 <tcf/config.h>

typedef struct Context Context;
typedef struct ContextBreakpoint ContextBreakpoint;

/* 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;        /* byte offset in the regsiers data cache */
    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 */
    const char *    description;   /* the description of the register */
};

typedef struct RegisterIdScope {
    uint16_t machine;
    uint8_t os_abi;
    uint8_t fp_abi;
    uint8_t elf64;
    uint8_t big_endian;
    uint8_t id_type;
} RegisterIdScope;

/* Location expression command codes */
#define SFT_CMD_NUMBER          1
#define SFT_CMD_RD_REG          2
#define SFT_CMD_FP              3
#define SFT_CMD_RD_MEM          4
#define SFT_CMD_ADD             5
#define SFT_CMD_SUB             6
#define SFT_CMD_MUL             7
#define SFT_CMD_DIV             8
#define SFT_CMD_AND             9
#define SFT_CMD_OR             10
#define SFT_CMD_XOR            11
#define SFT_CMD_NEG            12
#define SFT_CMD_GE             13
#define SFT_CMD_GT             14
#define SFT_CMD_LE             15
#define SFT_CMD_LT             16
#define SFT_CMD_SHL            17
#define SFT_CMD_SHR            18
#define SFT_CMD_ARG            19
#define SFT_CMD_LOCATION       20 /* A DWARF location expression */
#define SFT_CMD_FCALL          21
#define SFT_CMD_WR_REG         22
#define SFT_CMD_WR_MEM         23
#define SFT_CMD_PIECE          24
#define SFT_CMD_LOAD           25
#define SFT_CMD_STORE          26
#define SFT_CMD_SET_ARG        27

#define SFT_CMD_REGISTER        2 /* Deprecated, use SFT_CMD_RD_REG */
#define SFT_CMD_DEREF           4 /* Deprecated, use SFT_CMD_RD_MEM */

typedef struct LocationExpressionCommand LocationExpressionCommand;

typedef struct LocationPiece {
    ContextAddress addr;
    RegisterDefinition * reg;
    void * value;
    size_t size;
    unsigned bit_offs;
    unsigned bit_size;
} LocationPiece;

typedef struct LocationExpressionState {
    /* Evaluation context */
    Context * ctx;
    struct StackFrame * stack_frame;
    RegisterIdScope reg_id_scope;
    size_t addr_size;
    uint64_t * args;
    unsigned args_cnt;

    /* Code to execute */
    uint8_t * code;
    size_t code_pos;
    size_t code_len;

    /* Client callback */
    void (*client_op)(uint8_t op);

    /* Result */
    LocationExpressionCommand * sft_cmd;
    LocationPiece * pieces;
    unsigned pieces_cnt;
    unsigned pieces_max;

    /* Evaluation stack */
    unsigned stk_pos;
    unsigned stk_max;
    uint64_t * stk;
} LocationExpressionState;

typedef int LocationExpressionCallback(LocationExpressionState *);

/* Location expression command */
struct LocationExpressionCommand {
    int cmd;
    union {
        int64_t num;
        RegisterDefinition * reg;
        struct {
            size_t size;
            int big_endian;
        } deref; /* Deprecated, use .mem */
        struct {
            size_t size;
            int big_endian;
        } mem;
        struct {
            LocationExpressionCallback * func;
            RegisterIdScope reg_id_scope;
            uint8_t * code_addr;
            size_t code_size;
            size_t addr_size;
        } loc;
        struct {
            void * value;
            RegisterDefinition * reg;
            unsigned bit_offs;
            unsigned bit_size;
        } piece;
        unsigned arg_no;
    } args;
};

typedef struct CodeArea {
    const char * directory;
    const char * file;
    uint32_t file_mtime;
    uint32_t file_size;
    ContextAddress start_address;
    int start_line;
    int start_column;
    ContextAddress end_address;
    int end_line;
    int end_column;
    ContextAddress next_address; /* Address of next area - in source text order */
    int isa;
    int is_statement;
    int basic_block;
    int prologue_end;
    int epilogue_begin;
    int op_index;
    int discriminator;
} CodeArea;

#define STACK_BOTTOM_FRAME  0
#define STACK_NO_FRAME      (-1)
#define STACK_TOP_FRAME     (-2)

typedef struct StackFrame {
    int frame;
    int is_top_frame;
    int is_walked;          /* Data collected by: 0 - crawl, 1 - walk */
    int has_reg_data;
    CodeArea * area;        /* if the frame is inlined */
    Context * ctx;
    ContextAddress fp;      /* frame address */
    RegisterData * regs;    /* register values */
} StackFrame;

/* 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.
 * Return NULL if the context does not support software breakpoints. */
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 location expression. Throw an exception if error. */
extern LocationExpressionState * evaluate_location_expression(
            Context * ctx, StackFrame * frame,
            LocationExpressionCommand * cmds, unsigned cmds_cnt,
            uint64_t * args, unsigned args_cnt);

extern void read_location_pieces(
            Context * ctx, StackFrame * frame,
            LocationPiece * pieces, unsigned pieces_cnt, int big_endian,
            void ** value, size_t * size);

extern void write_location_pieces(
            Context * ctx, StackFrame * frame,
            LocationPiece * pieces, unsigned pieces_cnt, int big_endian,
            void * value, size_t size);

/* Deprecated misspelled function names */
#define read_location_peices read_location_pieces
#define write_location_peices write_location_pieces

/*** CPU hardware breakpoints API ***/

/* Get supported memory access modes */
extern int cpu_bp_get_capabilities(Context * ctx);

/* Plant hardware breakpoint */
extern int cpu_bp_plant(ContextBreakpoint * bp);

/* Remove hardware breakpoint */
extern int cpu_bp_remove(ContextBreakpoint * bp);

/* Setup breakpoint registers for a context that is about to resume */
extern int cpu_bp_on_resume(Context * ctx, int * single_step);

/* Check breakpoint registers for a context that has stopped */
extern int cpu_bp_on_suspend(Context * ctx, int * triggered);

/*** CPU external stepping mode API ***/

/* Disable the stepping mode */
extern int cpu_disable_stepping_mode (Context * ctx);

/* Enable the stepping mode */
extern int cpu_enable_stepping_mode (Context * ctx, uint32_t * is_cont);

/*** Initialization functions ***/

extern void ini_cpu_disassembler(Context * cpu);

extern void ini_cpudefs(void);

#endif /* ENABLE_DebugContext */

#endif /* D_cpudefs */

Back to the top