static LONGEST sparc64_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[8]; /* The result. */ LONGEST ret; /* Getting the system call number from the register. When dealing with the sparc architecture, this information is stored at the %g1 register. */ regcache_cooked_read (regcache, SPARC_G1_REGNUM, buf); ret = extract_signed_integer (buf, 8, byte_order); return ret; }
static LONGEST i386_linux_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid) { struct regcache *regcache = get_thread_regcache (ptid); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The content of a register. */ gdb_byte buf[4]; /* The result. */ LONGEST ret; /* Getting the system call number from the register. When dealing with x86 architecture, this information is stored at %eax register. */ regcache_cooked_read (regcache, I386_LINUX_ORIG_EAX_REGNUM, buf); ret = extract_signed_integer (buf, 4, byte_order); return ret; }
static int arm_breakpoint_at (CORE_ADDR where) { struct regcache *regcache = get_thread_regcache (current_thread, 1); unsigned long cpsr; collect_register_by_name (regcache, "cpsr", &cpsr); if (cpsr & 0x20) { /* Thumb mode. */ unsigned short insn; (*the_target->read_memory) (where, (unsigned char *) &insn, 2); if (insn == thumb_breakpoint) return 1; if (insn == thumb2_breakpoint[0]) { (*the_target->read_memory) (where + 2, (unsigned char *) &insn, 2); if (insn == thumb2_breakpoint[1]) return 1; } } else { /* ARM mode. */ unsigned long insn; (*the_target->read_memory) (where, (unsigned char *) &insn, 4); if (insn == arm_breakpoint) return 1; if (insn == arm_eabi_breakpoint) return 1; } return 0; }
int gdb_condition_true_at_breakpoint (CORE_ADDR where) { /* Fetch registers for the current inferior. */ struct breakpoint *bp = find_gdb_breakpoint_at (where); ULONGEST value = 0; struct point_cond_list *cl; int err = 0; struct eval_agent_expr_context ctx; if (bp == NULL) return 0; /* Check if the breakpoint is unconditional. If it is, the condition always evaluates to TRUE. */ if (bp->cond_list == NULL) return 1; ctx.regcache = get_thread_regcache (current_inferior, 1); ctx.tframe = NULL; ctx.tpoint = NULL; /* Evaluate each condition in the breakpoint's list of conditions. Return true if any of the conditions evaluates to TRUE. If we failed to evaluate the expression, TRUE is returned. This forces GDB to reevaluate the conditions. */ for (cl = bp->cond_list; cl && !value && !err; cl = cl->next) { /* Evaluate the condition. */ err = gdb_eval_agent_expr (&ctx, cl->cond, &value); } if (err) return 1; return (value != 0); }
ps_err_e ps_lgetregs (gdb_ps_prochandle_t ph, lwpid_t lwpid, prgregset_t gregset) { #ifdef HAVE_REGSETS struct lwp_info *lwp; struct thread_info *reg_inferior, *save_inferior; struct regcache *regcache; lwp = find_lwp_pid (pid_to_ptid (lwpid)); if (lwp == NULL) return PS_ERR; reg_inferior = get_lwp_thread (lwp); save_inferior = current_inferior; current_inferior = reg_inferior; regcache = get_thread_regcache (current_inferior, 1); gregset_info ()->fill_function (regcache, gregset); current_inferior = save_inferior; return PS_OK; #else return PS_ERR; #endif }
struct regcache * get_thread_regcache_for_ptid (ptid_t ptid) { return get_thread_regcache (find_thread_ptid (ptid), 1); }
static int cris_remove_point (char type, CORE_ADDR addr, int len) { int bp; unsigned long bp_ctrl; unsigned long start, end; struct regcache *regcache; unsigned long bp_d_regs[12]; /* Breakpoint/watchpoint types: 0 = memory breakpoint for instructions (not supported; done via memory write instead) 1 = hardware breakpoint for instructions (not supported) 2 = write watchpoint (supported) 3 = read watchpoint (supported) 4 = access watchpoint (supported). */ if (type < '2' || type > '4') return -1; regcache = get_thread_regcache (current_inferior, 1); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == '3') type = '4'; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* Try to find a watchpoint that is configured for the specified range, then check that read/write also matches. */ /* Ugly pointer arithmetic, since I cannot rely on a single switch (addr) as there may be several watchpoints with the same start address for example. */ /* Get all range registers to simplify search. */ collect_register_by_name (regcache, "s3", &bp_d_regs[0]); collect_register_by_name (regcache, "s4", &bp_d_regs[1]); collect_register_by_name (regcache, "s5", &bp_d_regs[2]); collect_register_by_name (regcache, "s6", &bp_d_regs[3]); collect_register_by_name (regcache, "s7", &bp_d_regs[4]); collect_register_by_name (regcache, "s8", &bp_d_regs[5]); collect_register_by_name (regcache, "s9", &bp_d_regs[6]); collect_register_by_name (regcache, "s10", &bp_d_regs[7]); collect_register_by_name (regcache, "s11", &bp_d_regs[8]); collect_register_by_name (regcache, "s12", &bp_d_regs[9]); collect_register_by_name (regcache, "s13", &bp_d_regs[10]); collect_register_by_name (regcache, "s14", &bp_d_regs[11]); for (bp = 0; bp < 6; bp++) { if (bp_d_regs[bp * 2] == addr && bp_d_regs[bp * 2 + 1] == (addr + len - 1)) { /* Matching range. */ int bitpos = 2 + bp * 4; int rw_bits; /* Read/write bits for this BP. */ rw_bits = (bp_ctrl & (0x3 << bitpos)) >> bitpos; if ((type == '3' && rw_bits == 0x1) || (type == '2' && rw_bits == 0x2) || (type == '4' && rw_bits == 0x3)) { /* Read/write matched. */ break; } } }
static int cris_insert_point (char type, CORE_ADDR addr, int len) { int bp; unsigned long bp_ctrl; unsigned long start, end; unsigned long ccs; struct regcache *regcache; /* Breakpoint/watchpoint types (GDB terminology): 0 = memory breakpoint for instructions (not supported; done via memory write instead) 1 = hardware breakpoint for instructions (not supported) 2 = write watchpoint (supported) 3 = read watchpoint (supported) 4 = access watchpoint (supported). */ if (type < '2' || type > '4') { /* Unsupported. */ return 1; } regcache = get_thread_regcache (current_inferior, 1); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == '3') type = '4'; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* The watchpoint allocation scheme is the simplest possible. For example, if a region is watched for read and a write watch is requested, a new watchpoint will be used. Also, if a watch for a region that is already covered by one or more existing watchpoints, a new watchpoint will be used. */ /* First, find a free data watchpoint. */ for (bp = 0; bp < 6; bp++) { /* Each data watchpoint's control registers occupy 2 bits (hence the 3), starting at bit 2 for D0 (hence the 2) with 4 bits between for each watchpoint (yes, the 4). */ if (!(bp_ctrl & (0x3 << (2 + (bp * 4))))) break; } if (bp > 5) { /* We're out of watchpoints. */ return -1; } /* Configure the control register first. */ if (type == '3' || type == '4') { /* Trigger on read. */ bp_ctrl |= (1 << (2 + bp * 4)); } if (type == '2' || type == '4') { /* Trigger on write. */ bp_ctrl |= (2 << (2 + bp * 4)); } /* Setup the configuration register. */ supply_register_by_name (regcache, "s0", &bp_ctrl); /* Setup the range. */ start = addr; end = addr + len - 1; /* Configure the watchpoint register. */ cris_write_data_breakpoint (regcache, bp, start, end); collect_register_by_name (regcache, "ccs", &ccs); /* Set the S1 flag to enable watchpoints. */ ccs |= (1 << 19); supply_register_by_name (regcache, "ccs", &ccs); return 0; }
static int cris_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len, struct raw_breakpoint *bp) { int bp; unsigned long bp_ctrl; unsigned long start, end; struct regcache *regcache; unsigned long bp_d_regs[12]; regcache = get_thread_regcache (current_thread, 1); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == raw_bkpt_type_read_wp) type = raw_bkpt_type_access_wp; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* Try to find a watchpoint that is configured for the specified range, then check that read/write also matches. */ /* Ugly pointer arithmetic, since I cannot rely on a single switch (addr) as there may be several watchpoints with the same start address for example. */ /* Get all range registers to simplify search. */ collect_register_by_name (regcache, "s3", &bp_d_regs[0]); collect_register_by_name (regcache, "s4", &bp_d_regs[1]); collect_register_by_name (regcache, "s5", &bp_d_regs[2]); collect_register_by_name (regcache, "s6", &bp_d_regs[3]); collect_register_by_name (regcache, "s7", &bp_d_regs[4]); collect_register_by_name (regcache, "s8", &bp_d_regs[5]); collect_register_by_name (regcache, "s9", &bp_d_regs[6]); collect_register_by_name (regcache, "s10", &bp_d_regs[7]); collect_register_by_name (regcache, "s11", &bp_d_regs[8]); collect_register_by_name (regcache, "s12", &bp_d_regs[9]); collect_register_by_name (regcache, "s13", &bp_d_regs[10]); collect_register_by_name (regcache, "s14", &bp_d_regs[11]); for (bp = 0; bp < 6; bp++) { if (bp_d_regs[bp * 2] == addr && bp_d_regs[bp * 2 + 1] == (addr + len - 1)) { /* Matching range. */ int bitpos = 2 + bp * 4; int rw_bits; /* Read/write bits for this BP. */ rw_bits = (bp_ctrl & (0x3 << bitpos)) >> bitpos; if ((type == raw_bkpt_type_read_wp && rw_bits == 0x1) || (type == raw_bkpt_type_write_wp && rw_bits == 0x2) || (type == raw_bkpt_type_access_wp && rw_bits == 0x3)) { /* Read/write matched. */ break; } } }
static int cris_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int len, struct raw_breakpoint *bp) { int bp; unsigned long bp_ctrl; unsigned long start, end; unsigned long ccs; struct regcache *regcache; regcache = get_thread_regcache (current_thread, 1); /* Read watchpoints are set as access watchpoints, because of GDB's inability to deal with pure read watchpoints. */ if (type == raw_bkpt_type_read_wp) type = raw_bkpt_type_access_wp; /* Get the configuration register. */ collect_register_by_name (regcache, "s0", &bp_ctrl); /* The watchpoint allocation scheme is the simplest possible. For example, if a region is watched for read and a write watch is requested, a new watchpoint will be used. Also, if a watch for a region that is already covered by one or more existing watchpoints, a new watchpoint will be used. */ /* First, find a free data watchpoint. */ for (bp = 0; bp < 6; bp++) { /* Each data watchpoint's control registers occupy 2 bits (hence the 3), starting at bit 2 for D0 (hence the 2) with 4 bits between for each watchpoint (yes, the 4). */ if (!(bp_ctrl & (0x3 << (2 + (bp * 4))))) break; } if (bp > 5) { /* We're out of watchpoints. */ return -1; } /* Configure the control register first. */ if (type == raw_bkpt_type_read_wp || type == raw_bkpt_type_access_wp) { /* Trigger on read. */ bp_ctrl |= (1 << (2 + bp * 4)); } if (type == raw_bkpt_type_write_wp || type == raw_bkpt_type_access_wp) { /* Trigger on write. */ bp_ctrl |= (2 << (2 + bp * 4)); } /* Setup the configuration register. */ supply_register_by_name (regcache, "s0", &bp_ctrl); /* Setup the range. */ start = addr; end = addr + len - 1; /* Configure the watchpoint register. */ cris_write_data_breakpoint (regcache, bp, start, end); collect_register_by_name (regcache, "ccs", &ccs); /* Set the S1 flag to enable watchpoints. */ ccs |= (1 << 19); supply_register_by_name (regcache, "ccs", &ccs); return 0; }
static void i386_linux_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signal) { int pid = ptid_get_pid (ptid); int request; if (catch_syscall_enabled () > 0) request = PTRACE_SYSCALL; else request = PTRACE_CONT; if (step) { struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid)); struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST pc; gdb_byte buf[LINUX_SYSCALL_LEN]; request = PTRACE_SINGLESTEP; regcache_cooked_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc); /* Returning from a signal trampoline is done by calling a special system call (sigreturn or rt_sigreturn, see i386-linux-tdep.c for more information). This system call restores the registers that were saved when the signal was raised, including %eflags. That means that single-stepping won't work. Instead, we'll have to modify the signal context that's about to be restored, and set the trace flag there. */ /* First check if PC is at a system call. */ if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) { ULONGEST syscall; regcache_cooked_read_unsigned (regcache, LINUX_SYSCALL_REGNUM, &syscall); /* Then check the system call number. */ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) { ULONGEST sp, addr; unsigned long int eflags; regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp); if (syscall == SYS_rt_sigreturn) addr = read_memory_unsigned_integer (sp + 8, 4, byte_order) + 20; else addr = sp; /* Set the trace flag in the context that's about to be restored. */ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; read_memory (addr, (gdb_byte *) &eflags, 4); eflags |= 0x0100; write_memory (addr, (gdb_byte *) &eflags, 4); } } } if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); }