+/* The instruction sequences used in x86_64 machines for a
+ disabled is-enabled probe. */
+
+const gdb_byte amd64_dtrace_disabled_probe_sequence_1[] = {
+ /* xor %rax, %rax */ 0x48, 0x33, 0xc0,
+ /* nop */ 0x90,
+ /* nop */ 0x90
+};
+
+const gdb_byte amd64_dtrace_disabled_probe_sequence_2[] = {
+ /* xor %rax, %rax */ 0x48, 0x33, 0xc0,
+ /* ret */ 0xc3,
+ /* nop */ 0x90
+};
+
+/* The instruction sequence used in x86_64 machines for enabling a
+ DTrace is-enabled probe. */
+
+const gdb_byte amd64_dtrace_enable_probe_sequence[] = {
+ /* mov $0x1, %eax */ 0xb8, 0x01, 0x00, 0x00, 0x00
+};
+
+/* The instruction sequence used in x86_64 machines for disabling a
+ DTrace is-enabled probe. */
+
+const gdb_byte amd64_dtrace_disable_probe_sequence[] = {
+ /* xor %rax, %rax; nop; nop */ 0x48, 0x33, 0xC0, 0x90, 0x90
+};
+
+/* Implementation of `gdbarch_dtrace_probe_is_enabled', as defined in
+ gdbarch.h. */
+
+static int
+amd64_dtrace_probe_is_enabled (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ gdb_byte buf[5];
+
+ /* This function returns 1 if the instructions at ADDR do _not_
+ follow any of the amd64_dtrace_disabled_probe_sequence_*
+ patterns.
+
+ Note that ADDR is offset 3 bytes from the beginning of these
+ sequences. */
+
+ read_code (addr - 3, buf, 5);
+ return (memcmp (buf, amd64_dtrace_disabled_probe_sequence_1, 5) != 0
+ && memcmp (buf, amd64_dtrace_disabled_probe_sequence_2, 5) != 0);
+}
+
+/* Implementation of `gdbarch_dtrace_enable_probe', as defined in
+ gdbarch.h. */
+
+static void
+amd64_dtrace_enable_probe (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ /* Note also that ADDR is offset 3 bytes from the beginning of
+ amd64_dtrace_enable_probe_sequence. */
+
+ write_memory (addr - 3, amd64_dtrace_enable_probe_sequence, 5);
+}
+
+/* Implementation of `gdbarch_dtrace_disable_probe', as defined in
+ gdbarch.h. */
+
+static void
+amd64_dtrace_disable_probe (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+ /* Note also that ADDR is offset 3 bytes from the beginning of
+ amd64_dtrace_disable_probe_sequence. */
+
+ write_memory (addr - 3, amd64_dtrace_disable_probe_sequence, 5);
+}
+
+/* Implementation of `gdbarch_dtrace_parse_probe_argument', as defined
+ in gdbarch.h. */
+
+static void
+amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch,
+ struct expr_builder *builder,
+ int narg)
+{
+ struct stoken str;
+
+ /* DTrace probe arguments can be found on the ABI-defined places for
+ regular arguments at the current PC. The probe abstraction
+ currently supports up to 12 arguments for probes. */
+
+ if (narg < 6)
+ {
+ static const int arg_reg_map[6] =
+ {
+ AMD64_RDI_REGNUM, /* Arg 1. */
+ AMD64_RSI_REGNUM, /* Arg 2. */
+ AMD64_RDX_REGNUM, /* Arg 3. */
+ AMD64_RCX_REGNUM, /* Arg 4. */
+ AMD64_R8_REGNUM, /* Arg 5. */
+ AMD64_R9_REGNUM /* Arg 6. */
+ };
+ int regno = arg_reg_map[narg];
+ const char *regname = user_reg_map_regnum_to_name (gdbarch, regno);
+
+ write_exp_elt_opcode (builder, OP_REGISTER);
+ str.ptr = regname;
+ str.length = strlen (regname);
+ write_exp_string (builder, str);
+ write_exp_elt_opcode (builder, OP_REGISTER);
+ }
+ else
+ {
+ /* Additional arguments are passed on the stack. */
+ const char *regname = user_reg_map_regnum_to_name (gdbarch, AMD64_RSP_REGNUM);
+
+ /* Displacement. */
+ write_exp_elt_opcode (builder, OP_LONG);
+ write_exp_elt_type (builder, builtin_type (gdbarch)->builtin_long);
+ write_exp_elt_longcst (builder, narg - 6);
+ write_exp_elt_opcode (builder, OP_LONG);
+
+ /* Register: SP. */
+ write_exp_elt_opcode (builder, OP_REGISTER);
+ str.ptr = regname;
+ str.length = strlen (regname);
+ write_exp_string (builder, str);
+ write_exp_elt_opcode (builder, OP_REGISTER);
+
+ write_exp_elt_opcode (builder, BINOP_ADD);
+
+ /* Cast to long. */
+ write_exp_elt_opcode (builder, UNOP_CAST);
+ write_exp_elt_type (builder,
+ lookup_pointer_type (builtin_type (gdbarch)->builtin_long));
+ write_exp_elt_opcode (builder, UNOP_CAST);
+
+ write_exp_elt_opcode (builder, UNOP_IND);
+ }
+}
+