aboutsummaryrefslogtreecommitdiff
path: root/src/monkey/mi_gdb.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/monkey/mi_gdb.h')
-rw-r--r--src/monkey/mi_gdb.h972
1 files changed, 972 insertions, 0 deletions
diff --git a/src/monkey/mi_gdb.h b/src/monkey/mi_gdb.h
new file mode 100644
index 000000000..df932b4ec
--- /dev/null
+++ b/src/monkey/mi_gdb.h
@@ -0,0 +1,972 @@
1/**[txh]********************************************************************
2
3 Copyright (c) 2004-2009 by Salvador E. Tropea.
4 Covered by the GPL license.
5
6 Comments:
7 Main header for libmigdb.
8
9***************************************************************************/
10
11#ifdef __cplusplus
12extern "C" {
13#endif
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <unistd.h> /* pid_t */
18
19#define MI_OK 0
20#define MI_OUT_OF_MEMORY 1
21#define MI_PIPE_CREATE 2
22#define MI_FORK 3
23#define MI_DEBUGGER_RUN 4
24#define MI_PARSER 5
25#define MI_UNKNOWN_ASYNC 6
26#define MI_UNKNOWN_RESULT 7
27#define MI_FROM_GDB 8
28#define MI_GDB_TIME_OUT 9
29#define MI_GDB_DIED 10
30#define MI_MISSING_XTERM 11
31#define MI_CREATE_TEMPORAL 12
32#define MI_MISSING_GDB 13
33#define MI_LAST_ERROR 13
34
35#define MI_R_NONE 0 /* We are no waiting any response. */
36#define MI_R_SKIP 1 /* We want to discard it. */
37#define MI_R_FE_AND_S 2 /* Wait for done. */
38#define MI_R_E_ARGS 3
39
40enum mi_val_type { t_const, t_tuple, t_list };
41
42/* Types and subtypes. */
43/* Type. */
44#define MI_T_OUT_OF_BAND 0
45#define MI_T_RESULT_RECORD 1
46/* Out of band subtypes. */
47#define MI_ST_ASYNC 0
48#define MI_ST_STREAM 1
49/* Async sub-subtypes. */
50#define MI_SST_EXEC 0
51#define MI_SST_STATUS 1
52#define MI_SST_NOTIFY 2
53/* Stream sub-subtypes. */
54#define MI_SST_CONSOLE 3
55#define MI_SST_TARGET 4
56#define MI_SST_LOG 5
57/* Classes. */
58/* Async classes. */
59#define MI_CL_UNKNOWN 0
60#define MI_CL_STOPPED 1
61#define MI_CL_DOWNLOAD 2
62/* Result classes. */
63#define MI_CL_DONE 2
64#define MI_CL_RUNNING 3
65#define MI_CL_CONNECTED 4
66#define MI_CL_ERROR 5
67#define MI_CL_EXIT 6
68
69#define MI_DEFAULT_TIME_OUT 10
70
71#define MI_DIS_ASM 0
72#define MI_DIS_SRC_ASM 1
73
74/* Implemented workaround for gdb bugs that we can dis/enable. */
75/* At least gdb<=6.1.1 fails to find a source file with absolute path if the
76 name is for a psym instead of a sym. psym==partially loaded symbol table. */
77#define MI_PSYM_SEARCH 0
78
79#define MI_VERSION_STR "0.8.12"
80#define MI_VERSION_MAJOR 0
81#define MI_VERSION_MIDDLE 8
82#define MI_VERSION_MINOR 12
83
84struct mi_results_struct
85{
86 char *var; /* Result name or NULL if just a value. */
87 enum mi_val_type type;
88 union
89 {
90 char *cstr;
91 struct mi_results_struct *rs;
92 } v;
93 struct mi_results_struct *next;
94};
95typedef struct mi_results_struct mi_results;
96
97struct mi_output_struct
98{
99 /* Type of output. */
100 char type;
101 char stype;
102 char sstype;
103 char tclass;
104 /* Content. */
105 mi_results *c;
106 /* Always modeled as a list. */
107 struct mi_output_struct *next;
108};
109typedef struct mi_output_struct mi_output;
110
111typedef void (*stream_cb)(const char *, void *);
112typedef void (*async_cb)(mi_output *o, void *);
113typedef int (*tm_cb)(void *);
114
115/* Values of this structure shouldn't be manipulated by the user. */
116struct mi_h_struct
117{
118 /* Pipes connected to gdb. */
119 int to_gdb[2];
120 int from_gdb[2];
121 /* Streams for the pipes. */
122 FILE *to, *from;
123 /* PID of child gdb. */
124 pid_t pid;
125 char died;
126 /* Which rensponse we are waiting for. */
127 /*int response;*/
128 /* The line we are reading. */
129 char *line;
130 int llen, lread;
131 /* Parsed output. */
132 mi_output *po, *last;
133 /* Tunneled streams callbacks. */
134 stream_cb console;
135 void *console_data;
136 stream_cb target;
137 void *target_data;
138 stream_cb log;
139 void *log_data;
140 /* Async responses callback. */
141 async_cb async;
142 void *async_data;
143 /* Callbacks to get echo of gdb dialog. */
144 stream_cb to_gdb_echo;
145 void *to_gdb_echo_data;
146 stream_cb from_gdb_echo;
147 void *from_gdb_echo_data;
148 /* Time out */
149 tm_cb time_out_cb;
150 void *time_out_cb_data;
151 int time_out;
152 /* Ugly workaround for some of the show responses :-( */
153 int catch_console;
154 char *catched_console;
155 /* MI version, currently unknown but the user can force v2 */
156 unsigned version;
157};
158typedef struct mi_h_struct mi_h;
159
160#define MI_TO(a) ((a)->to_gdb[1])
161
162enum mi_bkp_type { t_unknown=0, t_breakpoint=1, t_hw=2 };
163enum mi_bkp_disp { d_unknown=0, d_keep=1, d_del=2 };
164enum mi_bkp_mode { m_file_line=0, m_function=1, m_file_function=2, m_address=3 };
165
166struct mi_bkpt_struct
167{
168 int number;
169 enum mi_bkp_type type;
170 enum mi_bkp_disp disp; /* keep or del if temporal */
171 char enabled;
172 void *addr;
173 char *func;
174 char *file;
175 int line;
176 int ignore;
177 int times;
178
179 /* For the user: */
180 char *cond;
181 char *file_abs;
182 int thread;
183 enum mi_bkp_mode mode;
184 struct mi_bkpt_struct *next;
185};
186typedef struct mi_bkpt_struct mi_bkpt;
187
188enum mi_wp_mode { wm_unknown=0, wm_write=1, wm_read=2, wm_rw=3 };
189
190struct mi_wp_struct
191{
192 int number;
193 char *exp;
194 enum mi_wp_mode mode;
195
196 /* For the user: */
197 struct mi_wp_struct *next;
198 char enabled;
199};
200typedef struct mi_wp_struct mi_wp;
201
202struct mi_frames_struct
203{
204 int level; /* The frame number, 0 being the topmost frame, i.e. the innermost
205 function. */
206 void *addr; /* The `$pc' value for that frame. */
207 char *func; /* Function name. */
208 char *file; /* File name of the source file where the function lives. */
209 char *from;
210 int line; /* Line number corresponding to the `$pc'. */
211 /* When arguments are available: */
212 mi_results *args;
213 int thread_id;
214 /* When more than one is provided: */
215 struct mi_frames_struct *next;
216};
217typedef struct mi_frames_struct mi_frames;
218
219struct mi_aux_term_struct
220{
221 pid_t pid;
222 char *tty;
223};
224typedef struct mi_aux_term_struct mi_aux_term;
225
226struct mi_pty_struct
227{
228 char *slave;
229 int master;
230};
231typedef struct mi_pty_struct mi_pty;
232
233enum mi_gvar_fmt { fm_natural=0, fm_binary=1, fm_decimal=2, fm_hexadecimal=3,
234 fm_octal=4,
235 /* Only for registers format: */
236 fm_raw=5 };
237enum mi_gvar_lang { lg_unknown=0, lg_c, lg_cpp, lg_java };
238
239#define MI_ATTR_DONT_KNOW 0
240#define MI_ATTR_NONEDITABLE 1
241#define MI_ATTR_EDITABLE 2
242
243struct mi_gvar_struct
244{
245 char *name;
246 int numchild;
247 char *type;
248 enum mi_gvar_fmt format;
249 enum mi_gvar_lang lang;
250 char *exp;
251 int attr;
252
253 /* MI v2 fills it, not yet implemented here. */
254 /* Use gmi_var_evaluate_expression. */
255 char *value;
256
257 /* Pointer to the parent. NULL if none. */
258 struct mi_gvar_struct *parent;
259 /* List containing the children.
260 Filled by gmi_var_list_children.
261 NULL if numchild==0 or not yet filled. */
262 struct mi_gvar_struct *child;
263 /* Next var in the list. */
264 struct mi_gvar_struct *next;
265
266 /* For the user: */
267 char opened; /* We will show its children. 1 when we fill "child" */
268 char changed; /* Needs to be updated. 0 when created. */
269 int vischild; /* How many items visible. numchild when we fill "child" */
270 int depth; /* How deep is this var. */
271 char ispointer;
272};
273typedef struct mi_gvar_struct mi_gvar;
274
275struct mi_gvar_chg_struct
276{
277 char *name;
278 int in_scope; /* if true the other fields apply. */
279 char *new_type; /* NULL if type_changed==false */
280 int new_num_children; /* only when new_type!=NULL */
281
282 struct mi_gvar_chg_struct *next;
283};
284typedef struct mi_gvar_chg_struct mi_gvar_chg;
285
286
287/* A list of assembler instructions. */
288struct mi_asm_insn_struct
289{
290 void *addr;
291 char *func;
292 unsigned offset;
293 char *inst;
294
295 struct mi_asm_insn_struct *next;
296};
297typedef struct mi_asm_insn_struct mi_asm_insn;
298
299/* A list of source lines containing assembler instructions. */
300struct mi_asm_insns_struct
301{
302 char *file;
303 int line;
304 mi_asm_insn *ins;
305
306 struct mi_asm_insns_struct *next;
307};
308typedef struct mi_asm_insns_struct mi_asm_insns;
309
310/* Changed register. */
311struct mi_chg_reg_struct
312{
313 int reg;
314 char *val;
315 char *name;
316 char updated;
317
318 struct mi_chg_reg_struct *next;
319};
320typedef struct mi_chg_reg_struct mi_chg_reg;
321
322/*
323 Examining gdb sources and looking at docs I can see the following "stop"
324reasons:
325
326Breakpoints:
327a) breakpoint-hit (bkptno) + frame
328Also: without reason for temporal breakpoints.
329
330Watchpoints:
331b) watchpoint-trigger (wpt={number,exp};value={old,new}) + frame
332c) read-watchpoint-trigger (hw-rwpt{number,exp};value={value}) + frame
333d) access-watchpoint-trigger (hw-awpt{number,exp};value={[old,]new}) + frame
334e) watchpoint-scope (wpnum) + frame
335
336Movement:
337f) function-finished ([gdb-result-var,return-value]) + frame
338g) location-reached + frame
339h) end-stepping-range + frame
340
341Exit:
342i) exited-signalled (signal-name,signal-meaning)
343j) exited (exit-code)
344k) exited-normally
345
346Signal:
347l) signal-received (signal-name,signal-meaning) + frame
348
349Plus: thread-id
350*/
351enum mi_stop_reason
352{
353 sr_unknown=0,
354 sr_bkpt_hit,
355 sr_wp_trigger, sr_read_wp_trigger, sr_access_wp_trigger, sr_wp_scope,
356 sr_function_finished, sr_location_reached, sr_end_stepping_range,
357 sr_exited_signalled, sr_exited, sr_exited_normally,
358 sr_signal_received
359};
360
361struct mi_stop_struct
362{
363 enum mi_stop_reason reason; /* If more than one reason just the last. */
364 /* Flags indicating if non-pointer fields are filled. */
365 char have_thread_id;
366 char have_bkptno;
367 char have_exit_code;
368 char have_wpno;
369 /* Where stopped. Doesn't exist for sr_exited*. */
370 int thread_id;
371 mi_frames *frame;
372 /* sr_bkpt_hit */
373 int bkptno;
374 /* sr_*wp_* no scope */
375 mi_wp *wp;
376 char *wp_old;
377 char *wp_val;
378 /* sr_wp_scope */
379 int wpno;
380 /* sr_function_finished. Not for void func. */
381 char *gdb_result_var;
382 char *return_value;
383 /* sr_exited_signalled, sr_signal_received */
384 char *signal_name;
385 char *signal_meaning;
386 /* sr_exited */
387 int exit_code;
388};
389typedef struct mi_stop_struct mi_stop;
390
391/* Variable containing the last error. */
392extern int mi_error;
393extern char *mi_error_from_gdb;
394const char *mi_get_error_str();
395
396/* Indicate the name of gdb exe. Default is /usr/bin/gdb */
397void mi_set_gdb_exe(const char *name);
398const char *mi_get_gdb_exe();
399/* Indicate the name of a file containing commands to send at start-up */
400void mi_set_gdb_start(const char *name);
401const char *mi_get_gdb_start();
402/* Indicate the name of a file containing commands to send after connection */
403void mi_set_gdb_conn(const char *name);
404const char *mi_get_gdb_conn();
405void mi_send_target_commands(mi_h *h);
406/* Connect to a local copy of gdb. */
407mi_h *mi_connect_local();
408/* Close connection. You should ask gdb to quit first. */
409void mi_disconnect(mi_h *h);
410/* Force MI version. */
411#define MI_VERSION2U(maj,mid,min) (maj*0x1000000+mid*0x10000+min)
412void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
413 unsigned vMinor);
414void mi_set_workaround(unsigned wa, int enable);
415int mi_get_workaround(unsigned wa);
416/* Parse gdb output. */
417mi_output *mi_parse_gdb_output(const char *str);
418/* Functions to set/get the tunneled streams callbacks. */
419void mi_set_console_cb(mi_h *h, stream_cb cb, void *data);
420void mi_set_target_cb(mi_h *h, stream_cb cb, void *data);
421void mi_set_log_cb(mi_h *h, stream_cb cb, void *data);
422stream_cb mi_get_console_cb(mi_h *h, void **data);
423stream_cb mi_get_target_cb(mi_h *h, void **data);
424stream_cb mi_get_log_cb(mi_h *h, void **data);
425/* The callback to deal with async events. */
426void mi_set_async_cb(mi_h *h, async_cb cb, void *data);
427async_cb mi_get_async_cb(mi_h *h, void **data);
428/* Time out in gdb responses. */
429void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data);
430tm_cb mi_get_time_out_cb(mi_h *h, void **data);
431void mi_set_time_out(mi_h *h, int to);
432int mi_get_time_out(mi_h *h);
433/* Callbacks to "see" the dialog with gdb. */
434void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data);
435void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data);
436stream_cb mi_get_to_gdb_cb(mi_h *h, void **data);
437stream_cb mi_get_from_gdb_cb(mi_h *h, void **data);
438/* Sends a message to gdb. */
439int mi_send(mi_h *h, const char *format, ...);
440/* Wait until gdb sends a response. */
441mi_output *mi_get_response_blk(mi_h *h);
442/* Check if gdb sent a complete response. Use with mi_retire_response. */
443int mi_get_response(mi_h *h);
444/* Get the last response. Use with mi_get_response. */
445mi_output *mi_retire_response(mi_h *h);
446/* Look for a result record in gdb output. */
447mi_output *mi_get_rrecord(mi_output *r);
448/* Look if the output contains an async stop.
449 If that's the case return the reason for the stop.
450 If the output contains an error the description is returned in reason. */
451int mi_get_async_stop_reason(mi_output *r, char **reason);
452mi_stop *mi_get_stopped(mi_results *r);
453mi_frames *mi_get_async_frame(mi_output *r);
454/* Wait until gdb sends a response.
455 Then check if the response is of the desired type. */
456int mi_res_simple_exit(mi_h *h);
457int mi_res_simple_done(mi_h *h);
458int mi_res_simple_running(mi_h *h);
459int mi_res_simple_connected(mi_h *h);
460/* It additionally extracts an specified variable. */
461mi_results *mi_res_done_var(mi_h *h, const char *var);
462/* Extract a frames list from the response. */
463mi_frames *mi_res_frames_array(mi_h *h, const char *var);
464mi_frames *mi_res_frames_list(mi_h *h);
465mi_frames *mi_parse_frame(mi_results *c);
466mi_frames *mi_res_frame(mi_h *h);
467/* Create an auxiliar terminal using xterm. */
468mi_aux_term *gmi_start_xterm();
469/* Indicate the name of xterm exe. Default is /usr/bin/X11/xterm */
470void mi_set_xterm_exe(const char *name);
471const char *mi_get_xterm_exe();
472/* Kill the auxiliar terminal and release the structure. */
473void gmi_end_aux_term(mi_aux_term *t);
474/* Look for a free Linux VT for the child. */
475mi_aux_term *gmi_look_for_free_vt();
476/* Look for a free and usable Linux VT. */
477int mi_look_for_free_vt();
478/* Close master and release the structure. */
479void gmi_end_pty(mi_pty *p);
480/* Look for a free pseudo terminal. */
481mi_pty *gmi_look_for_free_pty();
482/* Extract a list of thread IDs from response. */
483int mi_res_thread_ids(mi_h *h, int **list);
484int mi_get_thread_ids(mi_output *res, int **list);
485/* A variable response. */
486mi_gvar *mi_res_gvar(mi_h *h, mi_gvar *cur, const char *expression);
487enum mi_gvar_fmt mi_format_str_to_enum(const char *format);
488const char *mi_format_enum_to_str(enum mi_gvar_fmt format);
489char mi_format_enum_to_char(enum mi_gvar_fmt format);
490enum mi_gvar_lang mi_lang_str_to_enum(const char *lang);
491const char *mi_lang_enum_to_str(enum mi_gvar_lang lang);
492int mi_res_changelist(mi_h *h, mi_gvar_chg **changed);
493int mi_res_children(mi_h *h, mi_gvar *v);
494mi_bkpt *mi_res_bkpt(mi_h *h);
495mi_wp *mi_res_wp(mi_h *h);
496char *mi_res_value(mi_h *h);
497mi_stop *mi_res_stop(mi_h *h);
498enum mi_stop_reason mi_reason_str_to_enum(const char *s);
499const char *mi_reason_enum_to_str(enum mi_stop_reason r);
500int mi_get_read_memory(mi_h *h, unsigned char *dest, unsigned ws, int *na,
501 unsigned long *addr);
502mi_asm_insns *mi_get_asm_insns(mi_h *h);
503/* Starting point of the program. */
504void mi_set_main_func(const char *name);
505const char *mi_get_main_func();
506mi_chg_reg *mi_get_list_registers(mi_h *h, int *how_many);
507int mi_get_list_registers_l(mi_h *h, mi_chg_reg *l);
508mi_chg_reg *mi_get_list_changed_regs(mi_h *h);
509int mi_get_reg_values(mi_h *h, mi_chg_reg *l);
510mi_chg_reg *mi_get_reg_values_l(mi_h *h, int *how_many);
511int gmi_target_download(mi_h *h);
512
513/* Allocation functions: */
514void *mi_calloc(size_t count, size_t sz);
515void *mi_calloc1(size_t sz);
516char *mi_malloc(size_t sz);
517mi_results *mi_alloc_results(void);
518mi_output *mi_alloc_output(void);
519mi_frames *mi_alloc_frames(void);
520mi_gvar *mi_alloc_gvar(void);
521mi_gvar_chg *mi_alloc_gvar_chg(void);
522mi_bkpt *mi_alloc_bkpt(void);
523mi_wp *mi_alloc_wp(void);
524mi_stop *mi_alloc_stop(void);
525mi_asm_insns *mi_alloc_asm_insns(void);
526mi_asm_insn *mi_alloc_asm_insn(void);
527mi_chg_reg *mi_alloc_chg_reg(void);
528void mi_free_output(mi_output *r);
529void mi_free_output_but(mi_output *r, mi_output *no, mi_results *no_r);
530void mi_free_frames(mi_frames *f);
531void mi_free_aux_term(mi_aux_term *t);
532void mi_free_results(mi_results *r);
533void mi_free_results_but(mi_results *r, mi_results *no);
534void mi_free_gvar(mi_gvar *v);
535void mi_free_gvar_chg(mi_gvar_chg *p);
536void mi_free_wp(mi_wp *wp);
537void mi_free_stop(mi_stop *s);
538void mi_free_asm_insns(mi_asm_insns *i);
539void mi_free_asm_insn(mi_asm_insn *i);
540void mi_free_charp_list(char **l);
541void mi_free_chg_reg(mi_chg_reg *r);
542
543/* Porgram control: */
544/* Specify the executable and arguments for local debug. */
545int gmi_set_exec(mi_h *h, const char *file, const char *args);
546/* Start running the executable. Remote sessions starts running. */
547int gmi_exec_run(mi_h *h);
548/* Continue the execution after a "stop". */
549int gmi_exec_continue(mi_h *h);
550/* Indicate which terminal will use the target program. For local sessions. */
551int gmi_target_terminal(mi_h *h, const char *tty_name);
552/* Specify what's the local copy that have debug info. For remote sessions. */
553int gmi_file_symbol_file(mi_h *h, const char *file);
554/* Continue until function return, the return value is included in the async
555 response. */
556int gmi_exec_finish(mi_h *h);
557/* Stop the program using SIGINT. */
558int gmi_exec_interrupt(mi_h *h);
559/* Next line of code. */
560int gmi_exec_next(mi_h *h);
561/* Next count lines of code. */
562int gmi_exec_next_cnt(mi_h *h, int count);
563/* Next line of assembler code. */
564int gmi_exec_next_instruction(mi_h *h);
565/* Next line of code. Get inside functions. */
566int gmi_exec_step(mi_h *h);
567/* Next count lines of code. Get inside functions. */
568int gmi_exec_step_cnt(mi_h *h, int count);
569/* Next line of assembler code. Get inside calls. */
570int gmi_exec_step_instruction(mi_h *h);
571/* Execute until location is reached. If file is NULL then is until next line. */
572int gmi_exec_until(mi_h *h, const char *file, int line);
573int gmi_exec_until_addr(mi_h *h, void *addr);
574/* Return to previous frame inmediatly. */
575mi_frames *gmi_exec_return(mi_h *h);
576/* Just kill the program. Please read the notes in prg_control.c. */
577int gmi_exec_kill(mi_h *h);
578
579/* Target manipulation: */
580/* Connect to a remote gdbserver using the specified methode. */
581int gmi_target_select(mi_h *h, const char *type, const char *params);
582/* Attach to an already running process. */
583mi_frames *gmi_target_attach(mi_h *h, pid_t pid);
584/* Detach from an attached process. */
585int gmi_target_detach(mi_h *h);
586
587/* Miscellaneous commands: */
588/* Exit gdb killing the child is it is running. */
589void gmi_gdb_exit(mi_h *h);
590/* Send the version to the console. */
591int gmi_gdb_version(mi_h *h);
592/* Set a gdb variable. */
593int gmi_gdb_set(mi_h *h, const char *var, const char *val);
594/* Get a gdb variable. */
595char *gmi_gdb_show(mi_h *h, const char *var);
596
597/* Breakpoints manipulation: */
598/* Insert a breakpoint at file:line. */
599mi_bkpt *gmi_break_insert(mi_h *h, const char *file, int line);
600/* Insert a breakpoint, all available options. */
601mi_bkpt *gmi_break_insert_full(mi_h *h, int temporary, int hard_assist,
602 const char *cond, int count, int thread,
603 const char *where);
604mi_bkpt *gmi_break_insert_full_fl(mi_h *h, const char *file, int line,
605 int temporary, int hard_assist,
606 const char *cond, int count, int thread);
607/* Remove a breakpoint. */
608int gmi_break_delete(mi_h *h, int number);
609/* Free the memory used for a breakpoint description. */
610void mi_free_bkpt(mi_bkpt *b);
611/* Modify the "ignore" count for a breakpoint. */
612int gmi_break_set_times(mi_h *h, int number, int count);
613/* Associate a condition with the breakpoint. */
614int gmi_break_set_condition(mi_h *h, int number, const char *condition);
615/* Enable or disable a breakpoint. */
616int gmi_break_state(mi_h *h, int number, int enable);
617/* Set a watchpoint. It doesn't work for remote targets! */
618mi_wp *gmi_break_watch(mi_h *h, enum mi_wp_mode mode, const char *exp);
619
620/* Data Manipulation. */
621/* Evaluate an expression. Returns a parsed tree. */
622char *gmi_data_evaluate_expression(mi_h *h, const char *expression);
623/* Path for sources. */
624int gmi_dir(mi_h *h, const char *path);
625/* A very limited "data read memory" implementation. */
626int gmi_read_memory(mi_h *h, const char *exp, unsigned size,
627 unsigned char *dest, int *na, int convAddr,
628 unsigned long *addr);
629mi_asm_insns *gmi_data_disassemble_se(mi_h *h, const char *start,
630 const char *end, int mode);
631mi_asm_insns *gmi_data_disassemble_fl(mi_h *h, const char *file, int line,
632 int lines, int mode);
633mi_chg_reg *gmi_data_list_register_names(mi_h *h, int *how_many);
634int gmi_data_list_register_names_l(mi_h *h, mi_chg_reg *l);
635mi_chg_reg *gmi_data_list_changed_registers(mi_h *h);
636int gmi_data_list_register_values(mi_h *h, enum mi_gvar_fmt fmt, mi_chg_reg *l);
637mi_chg_reg *gmi_data_list_all_register_values(mi_h *h, enum mi_gvar_fmt fmt, int *how_many);
638
639/* Stack manipulation. */
640/* List of frames. Arguments aren't filled. */
641mi_frames *gmi_stack_list_frames(mi_h *h);
642/* List of frames. Indicating a range. */
643mi_frames *gmi_stack_list_frames_r(mi_h *h, int from, int to);
644/* List arguments. Only level and args filled. */
645mi_frames *gmi_stack_list_arguments(mi_h *h, int show);
646/* List arguments. Indicating a range. Only level and args filled. */
647mi_frames *gmi_stack_list_arguments_r(mi_h *h, int show, int from, int to);
648/* Information about the current frame, including args. */
649mi_frames *gmi_stack_info_frame(mi_h *h);
650/* Stack info depth. error => -1 */
651int gmi_stack_info_depth_get(mi_h *h);
652/* Set stack info depth. error => -1 */
653int gmi_stack_info_depth(mi_h *h, int max_depth);
654/* Change current frame. */
655int gmi_stack_select_frame(mi_h *h, int framenum);
656/* List of local vars. */
657mi_results *gmi_stack_list_locals(mi_h *h, int show);
658
659/* Thread. */
660/* List available thread ids. */
661int gmi_thread_list_ids(mi_h *h, int **list);
662/* Select a thread. */
663mi_frames *gmi_thread_select(mi_h *h, int id);
664/* List available threads. */
665mi_frames *gmi_thread_list_all_threads(mi_h *h);
666
667/* Variable objects. */
668/* Create a variable object. */
669mi_gvar *gmi_var_create_nm(mi_h *h, const char *name, int frame, const char *exp);
670mi_gvar *gmi_var_create(mi_h *h, int frame, const char *exp);
671/* Create the variable and also fill the lang and attr fields. */
672mi_gvar *gmi_full_var_create(mi_h *h, int frame, const char *exp);
673/* Delete a variable object. Doesn't free the mi_gvar data. */
674int gmi_var_delete(mi_h *h, mi_gvar *var);
675/* Set the format used to represent the result. */
676int gmi_var_set_format(mi_h *h, mi_gvar *var, enum mi_gvar_fmt format);
677/* Fill the format field with info from gdb. */
678int gmi_var_show_format(mi_h *h, mi_gvar *var);
679/* Fill the numchild field with info from gdb. */
680int gmi_var_info_num_children(mi_h *h, mi_gvar *var);
681/* Fill the type field with info from gdb. */
682int gmi_var_info_type(mi_h *h, mi_gvar *var);
683/* Fill the expression and lang fields with info from gdb.
684 Note that lang isn't filled during creation. */
685int gmi_var_info_expression(mi_h *h, mi_gvar *var);
686/* Fill the attr field with info from gdb.
687 Note that attr isn't filled during creation. */
688int gmi_var_show_attributes(mi_h *h, mi_gvar *var);
689/* Update variable. Use NULL for all.
690 Note that *changed can be NULL if none updated. */
691int gmi_var_update(mi_h *h, mi_gvar *var, mi_gvar_chg **changed);
692/* Change variable. Fills the value field. */
693int gmi_var_assign(mi_h *h, mi_gvar *var, const char *expression);
694/* Get current value for a variable. */
695int gmi_var_evaluate_expression(mi_h *h, mi_gvar *var);
696/* List children. It ONLY returns the first level information. :-( */
697int gmi_var_list_children(mi_h *h, mi_gvar *var);
698
699#ifdef __cplusplus
700};
701
702/* C++ interface */
703
704/*
705 State Can:
706 disconnected Connect
707 connected SelectTarget, Disconnect
708 target_specified TargetUnselect, Run, Set breakpoints/watchpoints, etc.
709 running Stop
710 stopped Kill, Restart?, Step, Trace, Continue, etc.
711 [auto exit]
712
713 Modes:
714 dmX11 Local debug for X11.
715 dmLinux Local debug for Linux console.
716 dmRemote Remote debug.
717*/
718class MIDebugger
719{
720public:
721 MIDebugger();
722 ~MIDebugger();
723
724 enum eState { disconnected, connected, target_specified, running, stopped };
725 enum dMode { dmX11, dmLinux, dmRemote, dmPID };
726 enum endianType { enUnknown, enLittle, enBig };
727 // Currently tested architectures
728 enum archType { arUnknown, arIA32, arSPARC, arPIC14, arAVR, arUnsupported };
729
730 int Connect(bool remote=false); /* remote is currently ignored. */
731 int Disconnect();
732 /* SelectTarget* */
733 int SelectTargetX11(const char *exec, const char *args=NULL,
734 const char *auxtty=NULL);
735 int SelectTargetLinux(const char *exec, const char *args,
736 const char *auxtty=NULL);
737 int SelectTargetRemote(const char *exec, const char *rparams,
738 const char *rtype=NULL, bool download=false);
739 // TODO: Linux PIDs can be represented as intergers. What should I use?
740 // ato_pid_t doesn't exist ;-)
741 mi_frames *SelectTargetPID(const char *exec, int pid);
742 int TargetUnselect();
743 int Run();
744 int Stop();
745 int Poll(mi_stop *&rs);
746 int Continue();
747 int RunOrContinue();
748 int Kill();
749 mi_bkpt *Breakpoint(const char *file, int line);
750 mi_bkpt *Breakpoint(const char *where, bool temporary=false, const char *cond=NULL,
751 int count=-1, int thread=-1, bool hard_assist=false);
752 mi_bkpt *BreakpointFull(const char *file, int line, bool temporary=false,
753 const char *cond=NULL, int count=-1, int thread=-1,
754 bool hard_assist=false);
755 mi_bkpt *Breakpoint(mi_bkpt *b);
756 int BreakDelete(mi_bkpt *b);
757 int BreakAfter(mi_bkpt *b)
758 {
759 if (state!=target_specified && state!=stopped)
760 return 0;
761 return gmi_break_set_times(h,b->number,b->ignore);
762 }
763 mi_wp *Watchpoint(enum mi_wp_mode mode, const char *exp);
764 int WatchDelete(mi_wp *w);
765 int RunToMain();
766 int StepOver(bool inst=false);
767 int TraceInto(bool inst=false);
768 int GoTo(const char *file, int line);
769 int GoTo(void *addr);
770 int FinishFun();
771 mi_frames *ReturnNow();
772 mi_frames *CallStack(bool args);
773 char *EvalExpression(const char *exp);
774 char *ModifyExpression(char *exp, char *newVal);
775 mi_gvar *AddgVar(const char *exp, int frame=-1)
776 {
777 if (state!=stopped)
778 return NULL;
779 return gmi_full_var_create(h,frame,exp);
780 }
781 int DelgVar(mi_gvar *var)
782 {
783 if (state!=stopped)
784 return 0;
785 return gmi_var_delete(h,var);
786 }
787 int EvalgVar(mi_gvar *var)
788 {
789 if (state!=stopped)
790 return 0;
791 return gmi_var_evaluate_expression(h,var);
792 }
793 int GetChildgVar(mi_gvar *var)
794 {
795 if (state!=stopped)
796 return 0;
797 return gmi_var_list_children(h,var);
798 }
799 int FillTypeVal(mi_gvar *var);
800 int FillOneTypeVal(mi_gvar *var);
801 int FillAttr(mi_gvar *var)
802 {
803 if (state!=stopped)
804 return 0;
805 return gmi_var_show_attributes(h,var);
806 }
807 int FillFormat(mi_gvar *var)
808 {
809 if (state!=stopped)
810 return 0;
811 return gmi_var_show_format(h,var);
812 }
813 int SetFormatgVar(mi_gvar *var, enum mi_gvar_fmt format)
814 {
815 if (state!=stopped)
816 return 0;
817 return gmi_var_set_format(h,var,format);
818 }
819 int ListChangedgVar(mi_gvar_chg *&changed)
820 {
821 if (state!=stopped)
822 return 0;
823 return gmi_var_update(h,NULL,&changed);
824 }
825 int AssigngVar(mi_gvar *var, const char *exp);
826 int Send(const char *command);
827 int Version()
828 {
829 if (state==running || state==disconnected)
830 return 0;
831 return gmi_gdb_version(h);
832 }
833 int PathSources(const char *path)
834 {
835 if (state==running || state==disconnected)
836 return 0;
837 return gmi_dir(h,path);
838 }
839 int ReadMemory(const char *exp, unsigned size, unsigned char *dest,
840 int &na, int convAddr, unsigned long *addr)
841 {
842 if (state!=stopped)
843 return 0;
844 return gmi_read_memory(h,exp,size,dest,&na,convAddr,addr);
845 }
846 char *Show(const char *var);
847 int ThreadListIDs(int *&list)
848 {
849 if (state!=stopped)
850 return 0;
851 return gmi_thread_list_ids(h,&list);
852 }
853 mi_frames *ThreadList()
854 {
855 if (state!=stopped)
856 return 0;
857 return gmi_thread_list_all_threads(h);
858 }
859 mi_frames *ThreadSelect(int id)
860 {
861 if (state!=stopped)
862 return NULL;
863 return gmi_thread_select(h,id);
864 }
865 mi_asm_insns *Disassemble(const char *start, const char *end, int mode)
866 {
867 if (state!=stopped)
868 return NULL;
869 return gmi_data_disassemble_se(h,start,end,mode);
870 }
871 mi_asm_insns *Disassemble(const char *file, int line, int lines, int mode)
872 {
873 if (state!=stopped)
874 return NULL;
875 return gmi_data_disassemble_fl(h,file,line,lines,mode);
876 }
877 mi_chg_reg *GetRegisterNames(int *how_many)
878 {
879 if (state!=target_specified && state!=stopped)
880 return NULL;
881 return gmi_data_list_register_names(h,how_many);
882 }
883 int GetRegisterNames(mi_chg_reg *chg)
884 {
885 if (state!=target_specified && state!=stopped)
886 return 0;
887 return gmi_data_list_register_names_l(h,chg);
888 }
889 int GetRegisterValues(mi_chg_reg *chg)
890 {
891 if (state!=stopped)
892 return 0;
893 return gmi_data_list_register_values(h,fm_natural,chg);
894 }
895 mi_chg_reg *GetRegisterValues(int *how_many)
896 {
897 if (state!=stopped)
898 return 0;
899 return gmi_data_list_all_register_values(h,fm_natural,how_many);
900 }
901 mi_chg_reg *GetChangedRegisters()
902 {
903 if (state!=stopped)
904 return NULL;
905 mi_chg_reg *chg=gmi_data_list_changed_registers(h);
906 if (chg && !gmi_data_list_register_values(h,fm_natural,chg))
907 {
908 mi_free_chg_reg(chg);
909 chg=NULL;
910 }
911 return chg;
912 }
913 int UpdateRegisters(mi_chg_reg *regs);
914
915 endianType GetTargetEndian();
916 archType GetTargetArchitecture();
917 eState GetState() { return state; }
918
919 /* Some wrappers */
920 static void SetGDBExe(const char *name) { mi_set_gdb_exe(name); }
921 static const char *GetGDBExe() { return mi_get_gdb_exe(); }
922 static void SetXTermExe(const char *name) { mi_set_xterm_exe(name); }
923 static const char *GetXTermExe() { return mi_get_xterm_exe(); }
924 static void SetGDBStartFile(const char *name) { mi_set_gdb_start(name); }
925 static const char *GetGDBStartFile() { return mi_get_gdb_start(); }
926 static void SetGDBConnFile(const char *name) { mi_set_gdb_conn(name); }
927 static const char *GetGDBConnFile() { return mi_get_gdb_conn(); }
928 static void SetMainFunc(const char *name) { mi_set_main_func(name); }
929 static const char *GetMainFunc() { return mi_get_main_func(); }
930
931 static const char *GetErrorStr() { return mi_get_error_str(); }
932 static const char *GetGDBError() { return mi_error_from_gdb; }
933 static int GetErrorNumber() { return mi_error; }
934 int GetErrorNumberSt();
935 void SetConsoleCB(stream_cb cb, void *data=NULL)
936 { mi_set_console_cb(h,cb,data); }
937 void SetTargetCB(stream_cb cb, void *data=NULL)
938 { mi_set_target_cb(h,cb,data); }
939 void SetLogCB(stream_cb cb, void *data=NULL)
940 { mi_set_log_cb(h,cb,data); }
941 void SetAsyncCB(async_cb cb, void *data=NULL)
942 { mi_set_async_cb(h,cb,data); }
943 void SetToGDBCB(stream_cb cb, void *data=NULL)
944 { mi_set_to_gdb_cb(h,cb,data); }
945 void SetFromGDBCB(stream_cb cb, void *data=NULL)
946 { mi_set_from_gdb_cb(h,cb,data); }
947 void SetTimeOutCB(tm_cb cb, void *data)
948 { mi_set_time_out_cb(h,cb,data); }
949 void SetTimeOut(int to)
950 { mi_set_time_out(h,to); }
951 void ForceMIVersion(unsigned vMajor, unsigned vMiddle, unsigned vMinor)
952 { mi_force_version(h,vMajor,vMiddle,vMinor); }
953
954 const char *GetAuxTTY()
955 { return aux_tty ? aux_tty->tty : NULL; }
956
957protected:
958 eState state;
959 dMode mode;
960 endianType targetEndian;
961 archType targetArch;
962 bool preRun; // Remote targets starts running but outside main.
963 mi_h *h;
964 mi_aux_term *aux_tty;
965 int waitingTempBkpt;
966
967 int SelectTargetTTY(const char *exec, const char *args, const char *auxtty,
968 dMode m);
969};
970
971#endif
972