Add interface for JIT code generation.

* NEWS: Announce JIT interface.
	* Makefile.in (SFILES): Add jit.c.
	(HFILES_NO_SRCDIR): Add jit.h.
	(COMMON_OBS): Add jit.o.
	* jit.c: New file.
	* jit.h: New file.
	* breakpoint.h (enum bptype): Add bp_jit_event to enum.
	* breakpoint.c:
	(update_breakpoints_after_exec): Delete jit breakpoints after exec.
	(bpstat_what): Update event table for bp_jit_event.
	(print_it_typical): Added case for bp_jit_event.
	(print_one_breakpoint_location): Added case for bp_jit_event.
	(allocate_bp_location): Added case for bp_jit_event.
	(mention): Added case for bp_jit_event.
	(delete_command): Added case for bp_jit_event.
	(breakpoint_re_set_one): Added case for bp_jit_event.
	(breakpoint_re_set): Added call to jit_inferior_created_hook.
	(create_jit_event_breakpoint): New.
	* infrun.c (handle_inferior_event): Add handler for jit event.
	(follow_exec): Add call to jit_inferior_created_hook.
	* doc/gdb.texinfo: Add chapter on JIT interface.
This commit is contained in:
Doug Evans
2009-08-20 18:02:48 +00:00
parent c469dcaa81
commit 4efc650796
10 changed files with 769 additions and 31 deletions

View File

@ -59,6 +59,7 @@
#include "top.h"
#include "wrapper.h"
#include "valprint.h"
#include "jit.h"
/* readline include files */
#include "readline/readline.h"
@ -1592,6 +1593,13 @@ update_breakpoints_after_exec (void)
continue;
}
/* JIT breakpoints must be explicitly reset after an exec(). */
if (b->type == bp_jit_event)
{
delete_breakpoint (b);
continue;
}
/* Thread event breakpoints must be set anew after an exec(),
as must overlay event and longjmp master breakpoints. */
if (b->type == bp_thread_event || b->type == bp_overlay_event
@ -2583,6 +2591,7 @@ print_it_typical (bpstat bs)
case bp_watchpoint_scope:
case bp_call_dummy:
case bp_tracepoint:
case bp_jit_event:
default:
result = PRINT_UNKNOWN;
break;
@ -3308,6 +3317,9 @@ bpstat_what (bpstat bs)
/* We hit the shared library event breakpoint. */
shlib_event,
/* We hit the jit event breakpoint. */
jit_event,
/* This is just used to count how many enums there are. */
class_last
};
@ -3323,6 +3335,7 @@ bpstat_what (bpstat bs)
#define clr BPSTAT_WHAT_CLEAR_LONGJMP_RESUME
#define sr BPSTAT_WHAT_STEP_RESUME
#define shl BPSTAT_WHAT_CHECK_SHLIBS
#define jit BPSTAT_WHAT_CHECK_JIT
/* "Can't happen." Might want to print an error message.
abort() is not out of the question, but chances are GDB is just
@ -3343,12 +3356,13 @@ bpstat_what (bpstat bs)
back and decide something of a lower priority is better. The
ordering is:
kc < clr sgl shl slr sn sr ss
sgl < shl slr sn sr ss
slr < err shl sn sr ss
clr < err shl sn sr ss
ss < shl sn sr
sn < shl sr
kc < jit clr sgl shl slr sn sr ss
sgl < jit shl slr sn sr ss
slr < jit err shl sn sr ss
clr < jit err shl sn sr ss
ss < jit shl sn sr
sn < jit shl sr
jit < shl sr
shl < sr
sr <
@ -3366,28 +3380,18 @@ bpstat_what (bpstat bs)
table[(int) class_last][(int) BPSTAT_WHAT_LAST] =
{
/* old action */
/* kc ss sn sgl slr clr sr shl
*/
/*no_effect */
{kc, ss, sn, sgl, slr, clr, sr, shl},
/*wp_silent */
{ss, ss, sn, ss, ss, ss, sr, shl},
/*wp_noisy */
{sn, sn, sn, sn, sn, sn, sr, shl},
/*bp_nostop */
{sgl, ss, sn, sgl, slr, slr, sr, shl},
/*bp_silent */
{ss, ss, sn, ss, ss, ss, sr, shl},
/*bp_noisy */
{sn, sn, sn, sn, sn, sn, sr, shl},
/*long_jump */
{slr, ss, sn, slr, slr, err, sr, shl},
/*long_resume */
{clr, ss, sn, err, err, err, sr, shl},
/*step_resume */
{sr, sr, sr, sr, sr, sr, sr, sr},
/*shlib */
{shl, shl, shl, shl, shl, shl, sr, shl}
/* kc ss sn sgl slr clr sr shl jit */
/* no_effect */ {kc, ss, sn, sgl, slr, clr, sr, shl, jit},
/* wp_silent */ {ss, ss, sn, ss, ss, ss, sr, shl, jit},
/* wp_noisy */ {sn, sn, sn, sn, sn, sn, sr, shl, jit},
/* bp_nostop */ {sgl, ss, sn, sgl, slr, slr, sr, shl, jit},
/* bp_silent */ {ss, ss, sn, ss, ss, ss, sr, shl, jit},
/* bp_noisy */ {sn, sn, sn, sn, sn, sn, sr, shl, jit},
/* long_jump */ {slr, ss, sn, slr, slr, err, sr, shl, jit},
/* long_resume */ {clr, ss, sn, err, err, err, sr, shl, jit},
/* step_resume */ {sr, sr, sr, sr, sr, sr, sr, sr, sr },
/* shlib */ {shl, shl, shl, shl, shl, shl, sr, shl, shl},
/* jit_event */ {jit, jit, jit, jit, jit, jit, sr, jit, jit}
};
#undef kc
@ -3400,6 +3404,7 @@ bpstat_what (bpstat bs)
#undef sr
#undef ts
#undef shl
#undef jit
enum bpstat_what_main_action current_action = BPSTAT_WHAT_KEEP_CHECKING;
struct bpstat_what retval;
@ -3470,6 +3475,9 @@ bpstat_what (bpstat bs)
case bp_shlib_event:
bs_class = shlib_event;
break;
case bp_jit_event:
bs_class = jit_event;
break;
case bp_thread_event:
case bp_overlay_event:
case bp_longjmp_master:
@ -3603,6 +3611,7 @@ print_one_breakpoint_location (struct breakpoint *b,
{bp_longjmp_master, "longjmp master"},
{bp_catchpoint, "catchpoint"},
{bp_tracepoint, "tracepoint"},
{bp_jit_event, "jit events"},
};
static char bpenables[] = "nynny";
@ -3731,6 +3740,7 @@ print_one_breakpoint_location (struct breakpoint *b,
case bp_overlay_event:
case bp_longjmp_master:
case bp_tracepoint:
case bp_jit_event:
if (opts.addressprint)
{
annotate_field (4);
@ -4375,6 +4385,7 @@ allocate_bp_location (struct breakpoint *bpt)
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_jit_event:
case bp_longjmp_master:
loc->loc_type = bp_loc_software_breakpoint;
break;
@ -4657,6 +4668,17 @@ struct lang_and_radix
int radix;
};
/* Create a breakpoint for JIT code registration and unregistration. */
struct breakpoint *
create_jit_event_breakpoint (struct gdbarch *gdbarch, CORE_ADDR address)
{
struct breakpoint *b;
b = create_internal_breakpoint (gdbarch, address, bp_jit_event);
update_global_location_list_nothrow (1);
return b;
}
void
remove_solib_event_breakpoints (void)
@ -5338,6 +5360,7 @@ mention (struct breakpoint *b)
case bp_shlib_event:
case bp_thread_event:
case bp_overlay_event:
case bp_jit_event:
case bp_longjmp_master:
break;
}
@ -7654,6 +7677,7 @@ delete_command (char *arg, int from_tty)
{
if (b->type != bp_call_dummy
&& b->type != bp_shlib_event
&& b->type != bp_jit_event
&& b->type != bp_thread_event
&& b->type != bp_overlay_event
&& b->type != bp_longjmp_master
@ -7673,6 +7697,7 @@ delete_command (char *arg, int from_tty)
if (b->type != bp_call_dummy
&& b->type != bp_shlib_event
&& b->type != bp_thread_event
&& b->type != bp_jit_event
&& b->type != bp_overlay_event
&& b->type != bp_longjmp_master
&& b->number >= 0)
@ -7999,6 +8024,7 @@ breakpoint_re_set_one (void *bint)
case bp_step_resume:
case bp_longjmp:
case bp_longjmp_resume:
case bp_jit_event:
break;
}
@ -8027,6 +8053,8 @@ breakpoint_re_set (void)
set_language (save_language);
input_radix = save_input_radix;
jit_inferior_created_hook ();
create_overlay_event_breakpoint ("_ovly_debug_event");
create_longjmp_master_breakpoint ("longjmp");
create_longjmp_master_breakpoint ("_longjmp");