Esempio n. 1
0
static void
btrace_add_pc (struct thread_info *tp)
{
  struct btrace_data btrace;
  struct btrace_block *block;
  struct regcache *regcache;
  struct cleanup *cleanup;
  CORE_ADDR pc;

  regcache = get_thread_regcache (tp->ptid);
  pc = regcache_read_pc (regcache);

  btrace_data_init (&btrace);
  btrace.format = BTRACE_FORMAT_BTS;
  btrace.variant.bts.blocks = NULL;

  cleanup = make_cleanup_btrace_data (&btrace);

  block = VEC_safe_push (btrace_block_s, btrace.variant.bts.blocks, NULL);
  block->begin = pc;
  block->end = pc;

  btrace_compute_ftrace (tp, &btrace);

  do_cleanups (cleanup);
}
Esempio n. 2
0
static void
darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info)
{
  char *interp_name;
  CORE_ADDR load_addr = 0;
  bfd *dyld_bfd = NULL;
  struct cleanup *cleanup;

  /* This method doesn't work with an attached process.  */
  if (current_inferior ()->attach_flag)
    return;

  /* Find the program interpreter.  */
  interp_name = find_program_interpreter ();
  if (!interp_name)
    return;

  cleanup = make_cleanup (null_cleanup, NULL);

  /* Create a bfd for the interpreter.  */
  dyld_bfd = gdb_bfd_open (interp_name, gnutarget, -1);
  if (dyld_bfd)
    {
      bfd *sub;

      make_cleanup_bfd_unref (dyld_bfd);
      sub = gdb_bfd_mach_o_fat_extract
	(dyld_bfd, bfd_object, gdbarch_bfd_arch_info (target_gdbarch ()));
      if (sub)
	{
	  dyld_bfd = sub;
	  make_cleanup_bfd_unref (sub);
	}
      else
	dyld_bfd = NULL;
    }
  if (!dyld_bfd)
    {
      do_cleanups (cleanup);
      return;
    }

  /* We find the dynamic linker's base address by examining
     the current pc (which should point at the entry point for the
     dynamic linker) and subtracting the offset of the entry point.  */
  load_addr = (regcache_read_pc (get_current_regcache ())
               - bfd_get_start_address (dyld_bfd));

  /* Now try to set a breakpoint in the dynamic linker.  */
  info->all_image_addr =
    lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos");

  do_cleanups (cleanup);

  if (info->all_image_addr == 0)
    return;

  info->all_image_addr += load_addr;
}
Esempio n. 3
0
void
default_skip_permanent_breakpoint (struct regcache *regcache)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  CORE_ADDR current_pc = regcache_read_pc (regcache);
  int bp_len;

  gdbarch_breakpoint_from_pc (gdbarch, &current_pc, &bp_len);
  current_pc += bp_len;
  regcache_write_pc (regcache, current_pc);
}
Esempio n. 4
0
static void
check_event (ptid_t ptid)
{
  struct regcache *regcache = get_thread_regcache (ptid);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  td_event_msg_t msg;
  td_thrinfo_t ti;
  td_err_e err;
  CORE_ADDR stop_pc;
  int loop = 0;

  /* Bail out early if we're not at a thread event breakpoint.  */
  stop_pc = regcache_read_pc (regcache)
	    - gdbarch_decr_pc_after_break (gdbarch);
  if (stop_pc != td_create_bp_addr && stop_pc != td_death_bp_addr)
    return;
  loop = 1;

  do
    {
      err = td_ta_event_getmsg_p (thread_agent, &msg);
      if (err != TD_OK)
        {
	  if (err == TD_NOMSG)
	    return;
          error ("Cannot get thread event message: %s",
		 thread_db_err_str (err));
        }
      err = td_thr_get_info_p ((void *)(uintptr_t)msg.th_p, &ti);
      if (err != TD_OK)
        error ("Cannot get thread info: %s", thread_db_err_str (err));
      ptid = BUILD_THREAD (ti.ti_tid, GET_PID (ptid));
      switch (msg.event)
        {
        case TD_CREATE:
          /* We may already know about this thread, for instance when the
             user has issued the `info threads' command before the SIGTRAP
             for hitting the thread creation breakpoint was reported.  */
          attach_thread (ptid, (void *)(uintptr_t)msg.th_p, &ti, 1);
          break;
       case TD_DEATH:
         if (!in_thread_list (ptid))
           error ("Spurious thread death event.");
         detach_thread (ptid, 1);
         break;
       default:
          error ("Spurious thread event.");
       }
    }
  while (loop);
}
Esempio n. 5
0
/* When PC is at a syscall instruction, return the PC of the next
   instruction to be executed.  */
static CORE_ADDR
get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
{
  CORE_ADDR next_pc = 0;
  CORE_ADDR pc = regcache_read_pc (self->regcache);
  int is_thumb = arm_is_thumb_mode ();
  ULONGEST svc_number = 0;
  struct regcache *regcache = self->regcache;

  if (is_thumb)
    {
      collect_register (regcache, 7, &svc_number);
      next_pc = pc + 2;
    }
  else
    {
      unsigned long this_instr;
      unsigned long svc_operand;

      target_read_memory (pc, (unsigned char *) &this_instr, 4);
      svc_operand = (0x00ffffff & this_instr);

      if (svc_operand)  /* OABI.  */
	{
	  svc_number = svc_operand - 0x900000;
	}
      else /* EABI.  */
	{
	  collect_register (regcache, 7, &svc_number);
	}

      next_pc = pc + 4;
    }

  /* This is a sigreturn or sigreturn_rt syscall.  */
  if (svc_number == __NR_sigreturn || svc_number == __NR_rt_sigreturn)
    {
      /* SIGRETURN or RT_SIGRETURN may affect the arm thumb mode, so
	 update IS_THUMB.   */
      next_pc = arm_sigreturn_next_pc (regcache, svc_number, &is_thumb);
    }

  /* Addresses for calling Thumb functions have the bit 0 set.  */
  if (is_thumb)
    next_pc = MAKE_THUMB_ADDR (next_pc);

  return next_pc;
}
Esempio n. 6
0
static void
exec_one_dummy_insn (struct regcache *regcache)
{
#define	DUMMY_INSN_ADDR	AIX_TEXT_SEGMENT_BASE+0x200

  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int ret, status, pid;
  CORE_ADDR prev_pc;
  void *bp;

  /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address.  We
     assume that this address will never be executed again by the real
     code.  */

  bp = deprecated_insert_raw_breakpoint (gdbarch, NULL, DUMMY_INSN_ADDR);

  /* You might think this could be done with a single ptrace call, and
     you'd be correct for just about every platform I've ever worked
     on.  However, rs6000-ibm-aix4.1.3 seems to have screwed this up --
     the inferior never hits the breakpoint (it's also worth noting
     powerpc-ibm-aix4.1.3 works correctly).  */
  prev_pc = regcache_read_pc (regcache);
  regcache_write_pc (regcache, DUMMY_INSN_ADDR);
  if (ARCH64 ())
    ret = rs6000_ptrace64 (PT_CONTINUE, ptid_get_pid (inferior_ptid),
			   1, 0, NULL);
  else
    ret = rs6000_ptrace32 (PT_CONTINUE, ptid_get_pid (inferior_ptid),
			   (int *) 1, 0, NULL);

  if (ret != 0)
    perror (_("pt_continue"));

  do
    {
      pid = waitpid (ptid_get_pid (inferior_ptid), &status, 0);
    }
  while (pid != ptid_get_pid (inferior_ptid));

  regcache_write_pc (regcache, prev_pc);
  deprecated_remove_raw_breakpoint (gdbarch, bp);
}
Esempio n. 7
0
static void
save_bookmark_command (char *args, int from_tty)
{
  /* Get target's idea of a bookmark.  */
  gdb_byte *bookmark_id = target_get_bookmark (args, from_tty);
  struct bookmark *b, *b1;
  struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());

  /* CR should not cause another identical bookmark.  */
  dont_repeat ();

  if (bookmark_id == NULL)
    error (_("target_get_bookmark failed."));

  /* Set up a bookmark struct.  */
  b = xcalloc (1, sizeof (struct bookmark));
  b->number = ++bookmark_count;
  init_sal (&b->sal);
  b->pc = regcache_read_pc (get_current_regcache ());
  b->sal = find_pc_line (b->pc, 0);
  b->sal.pspace = get_frame_program_space (get_current_frame ());
  b->opaque_data = bookmark_id;
  b->next = NULL;

  /* Add this bookmark to the end of the chain, so that a list
     of bookmarks will come out in order of increasing numbers.  */

  b1 = bookmark_chain;
  if (b1 == 0)
    bookmark_chain = b;
  else
    {
      while (b1->next)
	b1 = b1->next;
      b1->next = b;
    }
  printf_filtered (_("Saved bookmark %d at %s\n"), b->number,
		     paddress (gdbarch, b->sal.pc));
}
Esempio n. 8
0
/* If the PPU thread is currently stopped on a spu_run system call,
   return to FD and ADDR the file handle and NPC parameter address
   used with the system call.  Return non-zero if successful.  */
static int
parse_spufs_run (ptid_t ptid, int *fd, CORE_ADDR *addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
  struct gdbarch_tdep *tdep;
  struct regcache *regcache;
  gdb_byte buf[4];
#ifdef ALLOW_UNUSED_VARIABLES
  CORE_ADDR pc;
#endif /* ALLOW_UNUSED_VARIABLES */
  ULONGEST regval;

  /* If we're not on PPU, there's nothing to detect.  */
  if (gdbarch_bfd_arch_info (target_gdbarch)->arch != bfd_arch_powerpc)
    return 0;

  /* Get PPU-side registers.  */
  regcache = get_thread_arch_regcache (ptid, target_gdbarch);
  tdep = new_gdbarch_tdep(target_gdbarch);

  /* Fetch instruction preceding current NIP.  */
  if (target_read_memory (regcache_read_pc (regcache) - 4, buf, 4) != 0)
    return 0;
  /* It should be a "sc" instruction.  */
  if (extract_unsigned_integer_with_byte_order(buf, 4, byte_order) != INSTR_SC)
    return 0;
  /* System call number should be NR_spu_run.  */
  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum, &regval);
  if (regval != NR_spu_run)
    return 0;

  /* Register 3 contains fd, register 4 the NPC param pointer.  */
  regcache_cooked_read_unsigned (regcache, PPC_ORIG_R3_REGNUM, &regval);
  *fd = (int) regval;
  regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 4, &regval);
  *addr = (CORE_ADDR) regval;
  return 1;
}
Esempio n. 9
0
CORE_ADDR
arm_linux_get_next_pcs_fixup (struct arm_get_next_pcs *self,
			      CORE_ADDR nextpc)
{
  /* The Linux kernel offers some user-mode helpers in a high page.  We can
     not read this page (as of 2.6.23), and even if we could then we
     couldn't set breakpoints in it, and even if we could then the atomic
     operations would fail when interrupted.  They are all (tail) called
     as functions and return to the address in LR.  However, when GDB single
     step this instruction, this instruction isn't executed yet, and LR
     may not be updated yet.  In other words, GDB can get the target
     address from LR if this instruction isn't BL or BLX.  */
  if (nextpc > 0xffff0000)
    {
      int bl_blx_p = 0;
      CORE_ADDR pc = regcache_read_pc (self->regcache);
      int pc_incr = 0;

      if (self->ops->is_thumb (self))
	{
	  unsigned short inst1
	    = self->ops->read_mem_uint (pc, 2, self->byte_order_for_code);

	  if (bits (inst1, 8, 15) == 0x47 && bit (inst1, 7))
	    {
	      /* BLX Rm */
	      bl_blx_p = 1;
	      pc_incr = 2;
	    }
	  else if (thumb_insn_size (inst1) == 4)
	    {
	      unsigned short inst2;

	      inst2 = self->ops->read_mem_uint (pc + 2, 2,
						self->byte_order_for_code);

	      if ((inst1 & 0xf800) == 0xf000 && bits (inst2, 14, 15) == 0x3)
		{
		  /* BL <label> and BLX <label> */
		  bl_blx_p = 1;
		  pc_incr = 4;
		}
	    }

	  pc_incr = MAKE_THUMB_ADDR (pc_incr);
	}
      else
	{
	  unsigned int insn
	    = self->ops->read_mem_uint (pc, 4, self->byte_order_for_code);

	  if (bits (insn, 28, 31) == INST_NV)
	    {
	      if (bits (insn, 25, 27) == 0x5) /* BLX <label> */
		bl_blx_p = 1;
	    }
	  else
	    {
	      if (bits (insn, 24, 27) == 0xb  /* BL <label> */
		  || bits (insn, 4, 27) == 0x12fff3 /* BLX Rm */)
		bl_blx_p = 1;
	    }

	  pc_incr = 4;
	}

      /* If the instruction BL or BLX, the target address is the following
	 instruction of BL or BLX, otherwise, the target address is in LR
	 already.  */
      if (bl_blx_p)
	nextpc = pc + pc_incr;
      else
	nextpc = regcache_raw_get_unsigned (self->regcache, ARM_LR_REGNUM);
    }
  return nextpc;
}