| Index: gdb/nacl-tdep.c
|
| diff --git a/gdb/nacl-tdep.c b/gdb/nacl-tdep.c
|
| index 53dc8f9f253bc94ca38354b33b667f8b8441cf6c..6ac49c75b7078453736102c85a2c855b0b71cf66 100644
|
| --- a/gdb/nacl-tdep.c
|
| +++ b/gdb/nacl-tdep.c
|
| @@ -27,6 +27,9 @@
|
| #include "solib-svr4.h"
|
| #include "frame.h"
|
| #include "osabi.h"
|
| +#include "disasm.h"
|
| +#include "breakpoint.h"
|
| +#include "target.h"
|
|
|
| static void
|
| nacl_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
| @@ -99,6 +102,52 @@ amd64_nacl_fetch_link_map_offsets (void)
|
| return lmp;
|
| }
|
|
|
| +static CORE_ADDR
|
| +amd64_nacl_skip_rsp_sandboxing (CORE_ADDR addr)
|
| +{
|
| + gdb_byte buf[3];
|
| + if (target_read_memory (addr, buf, sizeof(buf)) == 0)
|
| + {
|
| + /* 4c 01 fc add %r15,%rsp */
|
| + if (buf[0] == 0x4c && buf[1] == 0x01 && buf[2] == 0xfc)
|
| + {
|
| + return addr + 3;
|
| + }
|
| + }
|
| + return addr;
|
| +}
|
| +
|
| +static CORE_ADDR
|
| +amd64_nacl_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR addr)
|
| +{
|
| + return amd64_nacl_skip_rsp_sandboxing (addr);
|
| +}
|
| +
|
| +static int
|
| +amd64_nacl_software_single_step (struct frame_info *frame)
|
| +{
|
| + struct gdbarch *gdbarch;
|
| + CORE_ADDR pc;
|
| + CORE_ADDR bp_pc;
|
| +
|
| + gdbarch = get_frame_arch (frame);
|
| + pc = get_frame_register_unsigned (frame, gdbarch_pc_regnum (gdbarch));
|
| +
|
| + /* Check if next instruction is rsp sandboxing. If yes, assume current
|
| + instruction is rsp modification. */
|
| + pc += gdb_insn_length (gdbarch, pc);
|
| + bp_pc = amd64_nacl_skip_rsp_sandboxing (pc);
|
| + if (bp_pc != pc)
|
| + {
|
| + insert_single_step_breakpoint (gdbarch,
|
| + get_frame_address_space (frame),
|
| + bp_pc);
|
| + return 1;
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| static void
|
| amd64_nacl_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
| {
|
| @@ -130,6 +179,11 @@ amd64_nacl_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
| set_gdbarch_addr_bits_remove (gdbarch, amd64_nacl_addr_bits_remove);
|
| set_gdbarch_unwind_pc (gdbarch, amd64_nacl_unwind_pc);
|
| set_gdbarch_unwind_sp (gdbarch, amd64_nacl_unwind_sp);
|
| +
|
| + /* Where to set breakpoints. */
|
| + set_gdbarch_adjust_breakpoint_address (gdbarch,
|
| + amd64_nacl_adjust_breakpoint_address);
|
| + set_gdbarch_software_single_step (gdbarch, amd64_nacl_software_single_step);
|
| }
|
|
|
| /* Provide a prototype to silence -Wmissing-prototypes. */
|
|
|