gdb_special_events.c [plain text]
#include "gdb_private_interfaces.h"
#include <stdio.h>
#include <stdarg.h>
#include "command.h"
#include "cli/cli-decode.h"
#include "breakpoint.h"
#include "gdbcore.h" // file_changed_hook
#include "inferior.h"
static void (*saved_call_command_hook)(struct cmd_list_element *c, char *arg, int from_tty);
static int (*users_call_command)(char *arg, int from_tty);
static int call_command_defined = 0;
static void (*saved_set_hook)(struct cmd_list_element *c);
static Gdb_Set_Funct users_set_hook;
static int set_hook_defined = 0;
static int (*saved_query_hook)(const char *format, va_list ap);
static int (*users_query_hook)(const char *message, int *result);
static int query_hook_defined = 0;
static int (*saved__default_gdb_query_hook)(char *, va_list);
static int (*users_query_after_hook)(int result);
static int query_after_hook_defined = 0;
static void (*saved_warning_hook)(const char *format, va_list);
static int (*users_warning_hook)(const char *message);
static int warning_hook_defined = 0;
static void (*saved_create_bkpt)(struct breakpoint *b);
static void (*users_create_bkpt)(GDB_ADDRESS addr, int enabled);
static int create_bkpt_defined = 0;
static void (*saved_delete_bkpt)(struct breakpoint *b);
static void (*users_delete_bkpt)(GDB_ADDRESS addr, int enabled);
static int delete_bkpt_defined = 0;
static void (*saved_modify_bkpt)(struct breakpoint *b);
static void (*users_modify_bkpt)(GDB_ADDRESS addr, int enabled);
static int modify_bkpt_defined = 0;
static void (*saved_attach_hook)(void);
static void (*users_attach_hook)(int pid);
static int attach_hook_defined = 0;
static void (*saved_detach_hook)(void);
static void (*users_detach_hook)(void);
static int detach_hook_defined = 0;
static void (*saved_register_changed_hook)(int regno);
static void (*users_register_changed_hook)(void);
static int register_changed_hook_defined = 0;
static void (*saved_memory_changed_hook)(CORE_ADDR addr, int len);
static void (*users_memory_changed_hook)(GDB_ADDRESS addr, int len);
static int memory_changed_hook_defined = 0;
static void (*saved_context_hook)(int pid);
static void (*users_context_hook)(int pid);
static int context_hook_defined = 0;
static void (*saved_error_begin_hook)(void);
static void (*users_error_begin_hook)(void);
static int error_begin_hook_defined = 0;
static void (*saved_file_changed_hook)(char *filename);
static void (*users_file_changed_hook)(char *filename);
static int file_changed_hook_defined = 0;
static void (*saved_exec_file_display_hook)(char *filename);
static void (*users_exec_file_display_hook)(char *filename);
static int exec_file_display_hook_defined = 0;
static void (*saved_rl_startup_hook)(void);
static void (*users_rl_startup_hook)(void);
static int rl_startup_hook_defined = 0;
static void (*saved_readline_begin_hook)(char *format, ...);
static void (*users_readline_begin_hook)(char *prompt);
static int readline_begin_hook_defined = 0;
static char *(*saved_command_line_input_hook)(char *prompt);
static char *(*users_command_line_input_hook)(char *prompt);
static int command_line_input_hook_defined = 0;
static void (*saved_readline_end_hook)(void);
static void (*users_readline_end_hook)(void);
static int readline_end_hook_defined = 0;
static void (*saved_state_change_hook)(Debugger_state new_state);
static void (*users_state_change_hook)(GdbState new_state);
static int state_change_hook_defined = 0;
static void (*saved__word__completion_hook)(int save_cursor);
static void (*users__word__completion_hook)(int save_cursor);
static int __word__completion_hook_defined = 0;
static void (*saved__word__completion_query_hook)(GDB_FILE *stream, char *format, ...);
static void (*users__word__completion_query_hook)(GDB_FILE *stream, char *prompt);
static int __word__completion_query_hook_defined = 0;
static void (*saved__word__completion_read_hook)(void);
static void (*users__word__completion_read_hook)(void);
static int __word__completion_read_hook_defined = 0;
#if 0
static int (*saved_rl_getc_function)(FILE *);
static int (*users_rl_getc_function)(int);
static int rl_getc_function_defined = 0;
#endif
static void (*saved_rl_redisplay_function)(void);
static char *(*users_rl_redisplay_function)(char *);
static int rl_redisplay_function_defined = 0;
static void (*saved_interactive_hook)(void);
static void (*users_interactive_hook)(void);
static int interactive_hook_defined = 0;
static void my_call_command_hook(struct cmd_list_element *c, char *arg, int from_tty)
{
if (users_call_command(arg, from_tty)) {
if (saved_call_command_hook)
saved_call_command_hook(c, arg, from_tty);
(*c->function.cfunc)(arg, from_tty);
}
}
static void my_set_hook(struct cmd_list_element *c)
{
void *value;
Gdb_Set_Type type;
__my_set_hook_guts(c, &type, &value);
users_set_hook(c->name, type, value, 0, input_from_terminal_p());
if (saved_set_hook)
saved_set_hook(c);
}
static int my_query_hook(const char *format, va_list ap)
{
int result = 0;
char msg[1024];
vsprintf(msg, format, ap);
if (users_query_hook(msg, &result)) {
deprecated_query_hook = NULL;
result = query("%s", msg);
deprecated_query_hook = my_query_hook;
if (users_query_after_hook)
result = users_query_after_hook(result);
}
return (result);
}
static void my_warning_hook(const char *format, va_list ap)
{
char msg[1024];
int result = 0;
vsprintf(msg, format, ap);
if (users_warning_hook(msg)) {
deprecated_warning_hook = NULL;
warning("%s", msg);
deprecated_warning_hook = my_warning_hook;
}
}
static void my_create_breakpoint_hook(struct breakpoint *b)
{
users_create_bkpt((unsigned long)b->loc->address, b->enable_state == bp_enabled);
if (saved_create_bkpt)
saved_create_bkpt(b);
}
static void my_delete_breakpoint_hook(struct breakpoint *b)
{
users_delete_bkpt((unsigned long)b->loc->address, b->enable_state == bp_enabled);
if (saved_delete_bkpt)
saved_delete_bkpt(b);
}
static void my_modify_breakpoint_hook(struct breakpoint *b)
{
users_modify_bkpt((unsigned long)b->loc->address, b->enable_state == bp_enabled);
if (saved_modify_bkpt)
saved_modify_bkpt(b);
}
static void my_attach_hook(void)
{
users_attach_hook(PIDGET(inferior_ptid));
if (saved_attach_hook)
saved_attach_hook();
}
static void my_detach_hook(void)
{
users_detach_hook();
if (saved_detach_hook)
saved_detach_hook();
}
static void my_register_changed_hook(int ignore)
{
users_register_changed_hook();
if (saved_register_changed_hook)
saved_register_changed_hook(ignore);
}
static void my_memory_changed_hook(CORE_ADDR addr, int len)
{
users_memory_changed_hook((GDB_ADDRESS)addr, len);
if (saved_memory_changed_hook)
saved_memory_changed_hook(addr, len);
}
static void my_context_hook(int pid)
{
users_context_hook(pid);
if (saved_context_hook)
saved_context_hook(pid);
}
static void my_error_begin_hook(void)
{
users_error_begin_hook();
if (saved_error_begin_hook)
saved_error_begin_hook();
}
static void my_file_changed_hook(char *filename)
{
users_file_changed_hook(filename);
if (saved_file_changed_hook)
saved_file_changed_hook(filename);
}
static void my_exec_file_display_hook(char *filename)
{
users_exec_file_display_hook(filename);
if (saved_exec_file_display_hook)
saved_exec_file_display_hook(filename);
}
static void my_rl_startup_hook(void)
{
users_rl_startup_hook();
if (saved_rl_startup_hook)
saved_rl_startup_hook();
}
static void my_readline_begin_hook(char *format, ...)
{
va_list ap;
char prompt[1024];
va_start(ap, format);
vsprintf(prompt, format, ap);
va_end(ap);
users_readline_begin_hook(prompt);
if (saved_readline_begin_hook)
saved_readline_begin_hook("%s", prompt);
}
static char *my_command_line_input_hook(char *prompt, int repeat, char *annotation_suffix)
{
char *line = users_command_line_input_hook(prompt);
if (!line && saved_command_line_input_hook)
line = saved_command_line_input_hook(prompt);
if (!line) {
command_line_input_hook = NULL;
line = command_line_input(prompt, repeat, annotation_suffix);
command_line_input_hook = my_command_line_input_hook;
}
return (line);
}
static void my_readline_end_hook(void)
{
users_readline_end_hook();
if (saved_readline_end_hook)
saved_readline_end_hook();
}
static void my_state_change_hook(Debugger_state new_state)
{
GdbState my_state;
switch (new_state) {
case STATE_NOT_ACTIVE: my_state = Gdb_Not_Active; break;
case STATE_ACTIVE: my_state = Gdb_Active; break;
case STATE_INFERIOR_LOADED: my_state = Gdb_Target_Loaded; break;
case STATE_INFERIOR_EXITED: my_state = Gdb_Target_Exited; break;
case STATE_INFERIOR_LOGICALLY_RUNNING: my_state = Gdb_Target_Running; break;
case STATE_INFERIOR_STOPPED: my_state = Gdb_Target_Stopped; break;
default: return;
}
users_state_change_hook(my_state);
if (saved_state_change_hook)
saved_state_change_hook(new_state);
}
static void my__word__completion_hook(int save_cursor)
{
users__word__completion_hook(save_cursor);
if (saved__word__completion_hook)
saved__word__completion_hook(save_cursor);
}
static void my__word__completion_query_hook(GDB_FILE *stream, char *format, ...)
{
va_list ap;
char prompt[1024];
va_start(ap, format);
vsprintf(prompt, format, ap);
va_end(ap);
users__word__completion_query_hook(stream, prompt);
if (saved__word__completion_query_hook)
saved__word__completion_query_hook(stream, prompt);
}
static int my__word__completion_read_hook(void)
{
users__word__completion_read_hook();
if (saved__word__completion_read_hook)
saved__word__completion_read_hook();
}
#if 0
static int my_rl_getc_function(FILE *stream)
{
int c = ((int (*)(FILE*))saved_rl_getc_function)(stream);
return (users_rl_getc_function(c));
}
#endif
static void my_rl_redisplay_function(void)
{
if (rl_display_prompt && rl_display_prompt != rl_prompt)
rl_display_prompt = users_rl_redisplay_function(rl_display_prompt);
if (saved_rl_redisplay_function)
saved_rl_redisplay_function();
}
static void my_interactive_hook(void)
{
users_interactive_hook();
if (saved_interactive_hook)
saved_interactive_hook();
}
void gdb_special_events(GdbEvent theEvent, void (*callback)())
{
switch (theEvent) {
case Gdb_Before_Command:
if (callback) {
saved_call_command_hook = deprecated_call_command_hook;
users_call_command = (int (*)(char *, int))callback;
deprecated_call_command_hook = my_call_command_hook;
call_command_defined = 1;
} else if (call_command_defined) {
deprecated_call_command_hook = saved_call_command_hook;
call_command_defined = 0;
}
break;
case Gdb_After_SET_Command:
if (callback) {
saved_set_hook = deprecated_set_hook;
users_set_hook = (Gdb_Set_Funct)callback;
deprecated_set_hook = my_set_hook;
set_hook_defined = 1;
} else if (set_hook_defined) {
deprecated_set_hook = saved_set_hook;
set_hook_defined = 0;
}
break;
case Gdb_Before_Query:
if (callback) {
saved_query_hook = deprecated_query_hook;
users_query_hook = (int (*)(const char *, int *))callback;
deprecated_query_hook = my_query_hook;
query_hook_defined = 1;
saved__default_gdb_query_hook = __default_gdb_query_hook;
__default_gdb_query_hook = my_query_hook;
} else if (query_hook_defined) {
deprecated_query_hook = saved_query_hook;
query_hook_defined = 0;
__default_gdb_query_hook = saved__default_gdb_query_hook;
}
break;
case Gdb_After_Query:
if (callback) {
users_query_after_hook = (int (*)(int))callback;
query_after_hook_defined = 1;
} else if (query_after_hook_defined)
query_after_hook_defined = 0;
break;
case Gdb_Before_Warning:
if (callback) {
saved_warning_hook = deprecated_warning_hook;
users_warning_hook = (int (*)(const char *))callback;
deprecated_warning_hook = my_warning_hook;
warning_hook_defined = 1;
} else if (warning_hook_defined) {
deprecated_warning_hook = saved_warning_hook;
warning_hook_defined = 0;
}
break;
case Gdb_After_Creating_Breakpoint:
if (callback) {
saved_create_bkpt = deprecated_create_breakpoint_hook;
users_create_bkpt = (void (*)(GDB_ADDRESS addr, int enabled))callback;
deprecated_create_breakpoint_hook = my_create_breakpoint_hook;
create_bkpt_defined = 1;
} else if (create_bkpt_defined) {
deprecated_create_breakpoint_hook = saved_create_bkpt;
create_bkpt_defined = 0;
}
break;
case Gdb_Before_Deleting_Breakpoint:
if (callback) {
saved_delete_bkpt = deprecated_delete_breakpoint_hook;
users_delete_bkpt = (void (*)(GDB_ADDRESS addr, int enabled))callback;
deprecated_delete_breakpoint_hook = my_delete_breakpoint_hook ;
delete_bkpt_defined = 1;
} else if (delete_bkpt_defined) {
deprecated_delete_breakpoint_hook = saved_delete_bkpt;
delete_bkpt_defined = 0;
}
break;
case Gdb_After_Modified_Breakpoint:
if (callback) {
saved_modify_bkpt = deprecated_modify_breakpoint_hook;
users_modify_bkpt = (void (*)(GDB_ADDRESS addr, int enabled))callback;
deprecated_modify_breakpoint_hook = my_modify_breakpoint_hook ;
modify_bkpt_defined = 1;
} else if (modify_bkpt_defined) {
deprecated_modify_breakpoint_hook = saved_modify_bkpt;
modify_bkpt_defined = 0;
}
break;
case Gdb_After_Attach:
if (callback) {
saved_attach_hook = deprecated_attach_hook;
users_attach_hook = (void (*)(void))callback;
deprecated_attach_hook = my_attach_hook;
attach_hook_defined = 1;
} else if (attach_hook_defined) {
deprecated_attach_hook = saved_attach_hook;
attach_hook_defined = 0;
}
break;
case Gdb_Before_Detach:
if (callback) {
saved_detach_hook = deprecated_detach_hook;
users_detach_hook = (void (*)(void))callback;
deprecated_detach_hook = my_detach_hook;
detach_hook_defined = 1;
} else if (detach_hook_defined) {
deprecated_detach_hook = saved_detach_hook;
detach_hook_defined = 0;
}
break;
case Gdb_After_Register_Changed:
if (callback) {
saved_register_changed_hook = deprecated_register_changed_hook;
users_register_changed_hook = (void (*)(void))callback;
deprecated_register_changed_hook = my_register_changed_hook;
register_changed_hook_defined = 1;
} else if (register_changed_hook_defined) {
deprecated_register_changed_hook = saved_register_changed_hook;
register_changed_hook_defined = 0;
}
break;
case Gdb_After_Memory_Changed:
if (callback) {
saved_memory_changed_hook = deprecated_memory_changed_hook;
users_memory_changed_hook = (void (*)(GDB_ADDRESS, int))callback;
deprecated_memory_changed_hook = my_memory_changed_hook;
memory_changed_hook_defined = 1;
} else if (memory_changed_hook_defined) {
deprecated_memory_changed_hook = saved_memory_changed_hook;
memory_changed_hook_defined = 0;
}
break;
case Gdb_Context_Is_Changed:
if (callback) {
saved_context_hook = deprecated_context_hook;
users_context_hook = (void (*)(int))callback;
deprecated_context_hook = my_context_hook;
context_hook_defined = 1;
} else if (context_hook_defined) {
deprecated_context_hook = saved_context_hook;
context_hook_defined = 0;
}
break;
case Gdb_Before_Error:
if (callback) {
saved_error_begin_hook = deprecated_error_begin_hook;
users_error_begin_hook = (void (*)(void))callback;
deprecated_error_begin_hook = my_error_begin_hook;
error_begin_hook_defined = 1;
} else if (error_begin_hook_defined) {
deprecated_error_begin_hook = saved_error_begin_hook;
error_begin_hook_defined = 0;
}
break;
case Gdb_After_File_Changed:
if (callback) {
saved_file_changed_hook = deprecated_file_changed_hook;
users_file_changed_hook = (void (*)(char *))callback;
deprecated_file_changed_hook = my_file_changed_hook;
file_changed_hook_defined = 1;
} else if (file_changed_hook_defined) {
deprecated_file_changed_hook = saved_file_changed_hook;
file_changed_hook_defined = 0;
}
break;
case Gdb_After_Attach_To_File:
if (callback) {
saved_exec_file_display_hook = deprecated_exec_file_display_hook;
users_exec_file_display_hook = (void (*)(char *))callback;
deprecated_exec_file_display_hook = my_exec_file_display_hook;
exec_file_display_hook_defined = 1;
} else if (exec_file_display_hook_defined) {
deprecated_exec_file_display_hook = saved_exec_file_display_hook;
exec_file_display_hook_defined = 0;
}
break;
case Gdb_Before_Prompt:
if (callback) {
saved_rl_startup_hook = rl_startup_hook;
users_rl_startup_hook = (void (*)(void))callback;
rl_startup_hook = my_rl_startup_hook;
rl_startup_hook_defined = 1;
} else if (rl_startup_hook_defined) {
rl_startup_hook = saved_rl_startup_hook;
rl_startup_hook_defined = 0;
}
break;
case Gdb_Begin_ReadRawLine:
if (callback) {
saved_readline_begin_hook = deprecated_readline_begin_hook;
users_readline_begin_hook = (void (*)(char *))callback;
deprecated_readline_begin_hook = my_readline_begin_hook;
readline_begin_hook_defined = 1;
} else if (readline_begin_hook_defined) {
deprecated_readline_begin_hook = saved_readline_begin_hook;
readline_begin_hook_defined = 0;
}
break;
case Gdb_ReadRawLine:
if (callback) {
saved_command_line_input_hook = command_line_input_hook;
users_command_line_input_hook = (char *(*)(char *))callback;
command_line_input_hook = my_command_line_input_hook;
command_line_input_hook_defined = 1;
} else if (command_line_input_hook_defined) {
command_line_input_hook = saved_command_line_input_hook;
command_line_input_hook_defined = 0;
}
break;
case Gdb_End_ReadRawLine:
if (callback) {
saved_readline_end_hook = deprecated_readline_end_hook;
users_readline_end_hook = (void (*)(void))callback;
deprecated_readline_end_hook = my_readline_end_hook;
readline_end_hook_defined = 1;
} else if (readline_end_hook_defined) {
deprecated_readline_end_hook = saved_readline_end_hook;
readline_end_hook_defined = 0;
}
break;
case Gdb_State_Changed:
if (callback) {
saved_state_change_hook = state_change_hook;
users_state_change_hook = (void (*)(GdbState))callback;
state_change_hook = my_state_change_hook;
state_change_hook_defined = 1;
} else if (state_change_hook_defined) {
state_change_hook = saved_state_change_hook;
state_change_hook_defined = 0;
}
break;
case Gdb_Word_Completion_Cursor:
if (callback) {
saved__word__completion_hook = __word__completion_hook;
users__word__completion_hook = (void (*)(int))callback;
__word__completion_hook = my__word__completion_hook;
__word__completion_hook_defined = 1;
} else if (__word__completion_hook_defined) {
__word__completion_hook = saved__word__completion_hook;
__word__completion_hook_defined = 0;
}
break;
case Gdb_Word_Completion_Query:
if (callback) {
saved__word__completion_query_hook = __word__completion_query_hook;
users__word__completion_query_hook = (void (*)(GDB_FILE*, char*))callback;
__word__completion_query_hook = my__word__completion_query_hook;
__word__completion_query_hook_defined = 1;
} else if (__word__completion_query_hook_defined) {
__word__completion_query_hook = saved__word__completion_query_hook;
__word__completion_query_hook_defined = 0;
}
break;
case Gdb_Word_Completion_Read:
if (callback) {
saved__word__completion_read_hook = __word__completion_read_hook;
users__word__completion_read_hook = (void (*)(void))callback;
__word__completion_read_hook = my__word__completion_read_hook;
__word__completion_read_hook_defined = 1;
} else if (__word__completion_read_hook_defined) {
__word__completion_read_hook = saved__word__completion_read_hook;
__word__completion_read_hook_defined = 0;
}
break;
#if 0
case Gdb_Raw_Terminal_Getc:
if (callback) {
saved_rl_getc_function = rl_getc_function;;
users_rl_getc_function = (int (*)(int))callback;
rl_getc_function = my_rl_getc_function;
rl_getc_function_defined = 1;
} else if (rl_getc_function_defined) {
rl_getc_function = saved_rl_getc_function;
rl_getc_function_defined = 0;
}
break;
#endif
case Gdb_History_Prompt:
if (callback) {
saved_rl_redisplay_function = rl_redisplay_function;;
users_rl_redisplay_function = (char *(*)(char *))callback;
rl_redisplay_function = my_rl_redisplay_function;
rl_redisplay_function_defined = 1;
} else if (rl_redisplay_function_defined) {
rl_redisplay_function = saved_rl_redisplay_function;
rl_redisplay_function_defined = 0;
}
break;
case Gdb_Interactive:
if (callback) {
saved_interactive_hook = deprecated_interactive_hook;
users_interactive_hook = (void (*)(void))callback;
deprecated_interactive_hook = my_interactive_hook;
interactive_hook_defined = 1;
} else if (interactive_hook_defined) {
deprecated_interactive_hook = saved_interactive_hook;
interactive_hook_defined = 0;
}
break;
default:
gdb_internal_error("gdb_special_events() with an invalid GdbEvent");
}
}