static CORE_ADDR
i386_linux_sigcontext_addr (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR pc;
  CORE_ADDR sp;
  gdb_byte buf[4];

  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
  sp = extract_unsigned_integer (buf, 4, byte_order);

  pc = i386_linux_sigtramp_start (this_frame);
  if (pc)
    {
      /* The sigcontext structure lives on the stack, right after
	 the signum argument.  We determine the address of the
	 sigcontext structure by looking at the frame's stack
	 pointer.  Keep in mind that the first instruction of the
	 sigtramp code is "pop %eax".  If the PC is after this
	 instruction, adjust the returned value accordingly.  */
      if (pc == get_frame_pc (this_frame))
	return sp + 4;
      return sp;
    }

  pc = i386_linux_rt_sigtramp_start (this_frame);
  if (pc)
    {
      CORE_ADDR ucontext_addr;

      /* The sigcontext structure is part of the user context.  A
	 pointer to the user context is passed as the third argument
	 to the signal handler.  */
      read_memory (sp + 8, buf, 4);
      ucontext_addr = extract_unsigned_integer (buf, 4, byte_order);
      return ucontext_addr + I386_LINUX_UCONTEXT_SIGCONTEXT_OFFSET;
    }

  error (_("Couldn't recognize signal trampoline."));
  return 0;
}
Example #2
0
static CORE_ADDR
arm_linux_syscall_next_pc (struct frame_info *frame)
{
  CORE_ADDR pc = get_frame_pc (frame);
  CORE_ADDR return_addr = 0;
  int is_thumb = arm_frame_is_thumb (frame);
  ULONGEST svc_number = 0;

  if (is_thumb)
    {
      svc_number = get_frame_register_unsigned (frame, 7);
      return_addr = pc + 2;
    }
  else
    {
      struct gdbarch *gdbarch = get_frame_arch (frame);
      enum bfd_endian byte_order_for_code = 
	gdbarch_byte_order_for_code (gdbarch);
      unsigned long this_instr = 
	read_memory_unsigned_integer (pc, 4, byte_order_for_code);

      unsigned long svc_operand = (0x00ffffff & this_instr);
      if (svc_operand)  /* OABI.  */
	{
	  svc_number = svc_operand - 0x900000;
	}
      else /* EABI.  */
	{
	  svc_number = get_frame_register_unsigned (frame, 7);
	}

      return_addr = pc + 4;
    }

  arm_linux_sigreturn_return_addr (frame, svc_number, &return_addr, &is_thumb);

  /* Addresses for calling Thumb functions have the bit 0 set.  */
  if (is_thumb)
    return_addr |= 1;

  return return_addr;
}
Example #3
0
static CORE_ADDR
arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  ULONGEST indirect;
  struct bound_minimal_symbol indsym;
  const char *symname;
  CORE_ADDR next_pc;

  /* The format of an ARM DLL trampoline is:

       ldr  ip, [pc]
       ldr  pc, [ip]
       .dw __imp_<func>

  */

  if (pc == 0
      || read_memory_unsigned_integer (pc + 0, 4, byte_order) != 0xe59fc000
      || read_memory_unsigned_integer (pc + 4, 4, byte_order) != 0xe59cf000)
    return 0;

  indirect = read_memory_unsigned_integer (pc + 8, 4, byte_order);
  if (indirect == 0)
    return 0;

  indsym = lookup_minimal_symbol_by_pc (indirect);
  if (indsym.minsym == NULL)
    return 0;

  symname = MSYMBOL_LINKAGE_NAME (indsym.minsym);
  if (symname == NULL || !startswith (symname, "__imp_"))
    return 0;

  next_pc = read_memory_unsigned_integer (indirect, 4, byte_order);
  if (next_pc != 0)
    return next_pc;

  /* Check with the default arm gdbarch_skip_trampoline.  */
  return arm_skip_stub (frame, pc);
}
Example #4
0
static struct trad_frame_cache *
ppcfbsd_trapframe_cache (struct frame_info *this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR base;
  int i, regnum;

  if (*this_cache)
    return *this_cache;

  cache = trad_frame_cache_zalloc (this_frame);
  *this_cache = cache;

  base = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch));
  if (tdep->wordsize == 8)
    base += 48;
  else
    base += 8;

  for (i = 0; i < ppc_num_gprs; i++)
    trad_frame_set_reg_addr (cache, tdep->ppc_gp0_regnum + i, base
			     + (OFF_FIXREG + i) * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_lr_regnum, base
			   + OFF_LR * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_cr_regnum, base
			   + OFF_CR * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_xer_regnum, base
			   + OFF_XER * tdep->wordsize);
  trad_frame_set_reg_addr (cache, tdep->ppc_ctr_regnum, base
			   + OFF_CTR * tdep->wordsize);
  /* SRR0?  */
  trad_frame_set_reg_addr (cache, gdbarch_pc_regnum (gdbarch), base
			   + OFF_SRR0 * tdep->wordsize);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (cache, frame_id_build (base, get_frame_func (this_frame)));
  
  return cache;
}
Example #5
0
static int
tilegx_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR jb_addr;
  gdb_byte buf[8];

  jb_addr = get_frame_register_unsigned (frame, TILEGX_R0_REGNUM);

  /* TileGX jmp_buf contains 32 elements of type __uint_reg_t which
     has a size of 8 bytes.  The return address is stored in the 25th
     slot.  */
  if (target_read_memory (jb_addr + 25 * 8, buf, 8))
    return 0;

  *pc = extract_unsigned_integer (buf, 8, byte_order);

  return 1;
}
static CORE_ADDR
amd64_darwin_sigcontext_addr (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR rbx;
  CORE_ADDR si;
  gdb_byte buf[8];

  /* A pointer to the ucontext is passed as the fourth argument
     to the signal handler, which is saved in rbx.  */
  get_frame_register (this_frame, AMD64_RBX_REGNUM, buf);
  rbx = extract_unsigned_integer (buf, 8, byte_order);

  /* The pointer to mcontext is at offset 48.  */
  read_memory (rbx + 48, buf, 8);

  /* First register (rax) is at offset 16.  */
  return extract_unsigned_integer (buf, 8, byte_order) + 16;
}
Example #7
0
static void
m68k_value_to_register (struct frame_info *frame, int regnum,
			struct type *type, const gdb_byte *from)
{
  gdb_byte to[M68K_MAX_REGISTER_SIZE];
  struct type *fpreg_type = register_type (get_frame_arch (frame),
					   M68K_FP0_REGNUM);

  /* We only support floating-point values.  */
  if (TYPE_CODE (type) != TYPE_CODE_FLT)
    {
      warning (_("Cannot convert non-floating-point type "
	       "to floating-point register value."));
      return;
    }

  /* Convert from TYPE.  */
  convert_typed_floating (from, type, to, fpreg_type);
  put_frame_register (frame, regnum, to);
}
static int
mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR jb_addr;
  char *buf;

  buf = alloca (NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch));

  jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);

  if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET (gdbarch), buf,
  			  NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch)))
    return 0;

  *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE (gdbarch),
				  byte_order);
  return 1;
}
static void
i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
			      struct frame_info *this_frame,
			      struct trad_frame_cache *this_cache,
			      CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
  CORE_ADDR base;
  int *reg_offset;
  int num_regs;
  int i;

  if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
    {
      reg_offset = i386nbsd_sc_reg_offset;
      num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);

      /* Read in the sigcontext address */
      base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
    }
  else
    {
      reg_offset = i386nbsd_mc_reg_offset;
      num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);

      /* Read in the ucontext address */
      base = read_memory_unsigned_integer (sp + 8, 4, byte_order);
      /* offsetof(ucontext_t, uc_mcontext) == 36 */
      base += 36;
    }

  for (i = 0; i < num_regs; i++)
    if (reg_offset[i] != -1)
      trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
}
Example #10
0
static int
ppcobsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
				struct frame_info *this_frame,
				void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR start_pc = (pc & ~(ppcobsd_page_size - 1));
  const int *offset;
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (name)
    return 0;

  for (offset = ppcobsd_sigreturn_offset; *offset != -1; offset++)
    {
      gdb_byte buf[2 * PPC_INSN_SIZE];
      unsigned long insn;

      if (!safe_frame_unwind_memory (this_frame, start_pc + *offset,
				     buf, sizeof buf))
	continue;

      /* Check for "li r0,SYS_sigreturn".  */
      insn = extract_unsigned_integer (buf, PPC_INSN_SIZE, byte_order);
      if (insn != 0x38000067)
	continue;

      /* Check for "sc".  */
      insn = extract_unsigned_integer (buf + PPC_INSN_SIZE,
				       PPC_INSN_SIZE, byte_order);
      if (insn != 0x44000002)
	continue;

      return 1;
    }

  return 0;
}
Example #11
0
static struct msp430_prologue *
msp430_analyze_frame_prologue (struct frame_info *this_frame,
			       void **this_prologue_cache)
{
  if (!*this_prologue_cache)
    {
      CORE_ADDR func_start, stop_addr;

      *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct msp430_prologue);

      func_start = get_frame_func (this_frame);
      stop_addr = get_frame_pc (this_frame);

      /* If we couldn't find any function containing the PC, then
         just initialize the prologue cache, but don't do anything.  */
      if (!func_start)
	stop_addr = func_start;

      msp430_analyze_prologue (get_frame_arch (this_frame), func_start,
			       stop_addr, *this_prologue_cache);
    }
static struct value *
value_of_builtin_frame_pc_reg (struct frame_info *frame, const void *baton)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);

  if (gdbarch_pc_regnum (gdbarch) >= 0)
    return value_of_register (gdbarch_pc_regnum (gdbarch), frame);
  else
    {
      struct type *func_ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
      struct value *val = allocate_value (func_ptr_type);
      gdb_byte *buf = value_contents_raw (val);

      if (frame == NULL)
	memset (buf, 0, TYPE_LENGTH (value_type (val)));
      else
	gdbarch_address_to_pointer (gdbarch, func_ptr_type,
				    buf, get_frame_pc (frame));
      return val;
    }
}
Example #13
0
static int
m68k_register_to_value (struct frame_info *frame, int regnum,
			struct type *type, gdb_byte *to,
			int *optimizedp, int *unavailablep)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  gdb_byte from[M68K_MAX_REGISTER_SIZE];
  struct type *fpreg_type = register_type (gdbarch, M68K_FP0_REGNUM);

  gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLT);

  /* Convert to TYPE.  */
  if (!get_frame_register_bytes (frame, regnum, 0,
				 register_size (gdbarch, regnum),
				 from, optimizedp, unavailablep))
    return 0;

  target_float_convert (from, fpreg_type, to, type);
  *optimizedp = *unavailablep = 0;
  return 1;
}
Example #14
0
const struct frame_unwind *
frame_unwind_find_by_frame (struct frame_info *next_frame)
{
  int i;
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
  struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
  if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES && legacy_frame_p (gdbarch))
    /* Seriously old code.  Don't even try to use this new mechanism.
       (Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not
       the dummy frame mechanism.  All architectures should be using
       generic dummy frames).  */
    return legacy_saved_regs_unwind;
  for (i = 0; i < table->nr; i++)
    {
      const struct frame_unwind *desc;
      desc = table->sniffer[i] (next_frame);
      if (desc != NULL)
	return desc;
    }
  return legacy_saved_regs_unwind;
}
static int
mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  CORE_ADDR jb_addr;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  char buf[gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT];

  jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);

  if (target_read_memory (jb_addr
			    + MIPS_LINUX_JB_PC * MIPS_LINUX_JB_ELEMENT_SIZE,
			  buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
    return 0;

  *pc = extract_unsigned_integer (buf,
				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT,
				  byte_order);

  return 1;
}
Example #16
0
static void
bfin_linux_sigframe_init (const struct tramp_frame *self,
			  struct frame_info *this_frame,
			  struct trad_frame_cache *this_cache,
			  CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR sp = get_frame_sp (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET;
  const int *reg_offset = bfin_linux_sigcontext_reg_offset;
  int i;

  for (i = 0; i < BFIN_NUM_REGS; i++)
    if (reg_offset[i] != -1)
      trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]);

  /* This would come after the LINK instruction in the ret_from_signal
     function, hence the frame id would be SP + 8.  */
  trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc));
}
Example #17
0
static void
arm_linux_restart_syscall_init (const struct tramp_frame *self,
				struct frame_info *this_frame,
				struct trad_frame_cache *this_cache,
				CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
  CORE_ADDR pc = get_frame_memory_unsigned (this_frame, sp, 4);
  CORE_ADDR cpsr = get_frame_register_unsigned (this_frame, ARM_PS_REGNUM);
  ULONGEST t_bit = arm_psr_thumb_bit (gdbarch);
  int sp_offset;

  /* There are two variants of this trampoline; with older kernels, the
     stub is placed on the stack, while newer kernels use the stub from
     the vector page.  They are identical except that the older version
     increments SP by 12 (to skip stored PC and the stub itself), while
     the newer version increments SP only by 4 (just the stored PC).  */
  if (self->insn[1].bytes == ARM_LDR_PC_SP_4)
    sp_offset = 4;
  else
    sp_offset = 12;

  /* Update Thumb bit in CPSR.  */
  if (pc & 1)
    cpsr |= t_bit;
  else
    cpsr &= ~t_bit;

  /* Remove Thumb bit from PC.  */
  pc = gdbarch_addr_bits_remove (gdbarch, pc);

  /* Save previous register values.  */
  trad_frame_set_reg_value (this_cache, ARM_SP_REGNUM, sp + sp_offset);
  trad_frame_set_reg_value (this_cache, ARM_PC_REGNUM, pc);
  trad_frame_set_reg_value (this_cache, ARM_PS_REGNUM, cpsr);

  /* Save a frame ID.  */
  trad_frame_set_id (this_cache, frame_id_build (sp, func));
}
Example #18
0
static int
sparc64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  CORE_ADDR jb_addr;
  gdb_byte buf[8];

  jb_addr = get_frame_register_unsigned (frame, SPARC_O0_REGNUM);

  /* setjmp and longjmp in SPARC64 are implemented in glibc using the
     setcontext and getcontext system calls respectively.  These
     system calls operate on ucontext_t structures, which happen to
     partially have the same structure than jmp_buf.  However the
     ucontext returned by getcontext, and thus the jmp_buf structure
     returned by setjmp, contains the context of the trap instruction
     in the glibc __[sig]setjmp wrapper, not the context of the user
     code calling setjmp.

     %o7 in the jmp_buf structure is stored at offset 18*8 in the
     mc_gregs array, which is itself located at offset 32 into
     jmp_buf.  See bits/setjmp.h.  This register contains the address
     of the 'call setjmp' instruction in user code.

     In order to determine the longjmp target address in the
     initiating frame we need to examine the call instruction itself,
     in particular whether the annul bit is set.  If it is not set
     then we need to jump over the instruction at the delay slot.  */

  if (target_read_memory (jb_addr + 32 + (18 * 8), buf, 8))
    return 0;

  *pc = extract_unsigned_integer (buf, 8, gdbarch_byte_order (gdbarch));

  if (!sparc_is_annulled_branch_insn (*pc))
      *pc += 4; /* delay slot insn  */
  *pc += 4; /* call insn  */

  return 1;
}
Example #19
0
static CORE_ADDR
ppc64_plt_entry_point (struct frame_info *frame, CORE_ADDR plt_off)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  CORE_ADDR tocp;

  if (execution_direction == EXEC_REVERSE)
    {
      /* If executing in reverse, r2 will have been stored to the stack.  */
      CORE_ADDR sp = get_frame_register_unsigned (frame,
						  tdep->ppc_gp0_regnum + 1);
      unsigned int sp_off = tdep->elf_abi == POWERPC_ELF_V1 ? 40 : 24;
      tocp = read_memory_unsigned_integer (sp + sp_off, 8, byte_order);
    }
  else
    tocp = get_frame_register_unsigned (frame, tdep->ppc_gp0_regnum + 2);

  /* The first word of the PLT entry is the function entry point.  */
  return read_memory_unsigned_integer (tocp + plt_off, 8, byte_order);
}
static CORE_ADDR 
gnuv3_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
{
  CORE_ADDR real_stop_pc, method_stop_pc;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct minimal_symbol *thunk_sym, *fn_sym;
  struct obj_section *section;
  char *thunk_name, *fn_name;
  
  real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
  if (real_stop_pc == 0)
    real_stop_pc = stop_pc;

  /* Find the linker symbol for this potential thunk.  */
  thunk_sym = lookup_minimal_symbol_by_pc (real_stop_pc);
  section = find_pc_section (real_stop_pc);
  if (thunk_sym == NULL || section == NULL)
    return 0;

  /* The symbol's demangled name should be something like "virtual
     thunk to FUNCTION", where FUNCTION is the name of the function
     being thunked to.  */
  thunk_name = SYMBOL_DEMANGLED_NAME (thunk_sym);
  if (thunk_name == NULL || strstr (thunk_name, " thunk to ") == NULL)
    return 0;

  fn_name = strstr (thunk_name, " thunk to ") + strlen (" thunk to ");
  fn_sym = lookup_minimal_symbol (fn_name, NULL, section->objfile);
  if (fn_sym == NULL)
    return 0;

  method_stop_pc = SYMBOL_VALUE_ADDRESS (fn_sym);
  real_stop_pc = gdbarch_skip_trampoline_code
		   (gdbarch, frame, method_stop_pc);
  if (real_stop_pc == 0)
    real_stop_pc = method_stop_pc;

  return real_stop_pc;
}
Example #21
0
static void
arm_linux_rt_sigreturn_init (const struct tramp_frame *self,
			  struct frame_info *this_frame,
			  struct trad_frame_cache *this_cache,
			  CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
  ULONGEST pinfo = read_memory_unsigned_integer (sp, 4, byte_order);

  if (pinfo == sp + ARM_OLD_RT_SIGFRAME_SIGINFO)
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
			      ARM_OLD_RT_SIGFRAME_UCONTEXT
			      + ARM_UCONTEXT_SIGCONTEXT
			      + ARM_SIGCONTEXT_R0);
  else
    arm_linux_sigtramp_cache (this_frame, this_cache, func,
			      ARM_NEW_RT_SIGFRAME_UCONTEXT
			      + ARM_UCONTEXT_SIGCONTEXT
			      + ARM_SIGCONTEXT_R0);
}
static int
mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
  CORE_ADDR jb_addr;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  void *buf = alloca (gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
  int element_size = gdbarch_ptr_bit (gdbarch) == 32 ? 4 : 8;

  jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);

  if (target_read_memory (jb_addr + MIPS64_LINUX_JB_PC * element_size,
			  buf,
			  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
    return 0;

  *pc = extract_unsigned_integer (buf,
				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT,
				  byte_order);

  return 1;
}
Example #23
0
static struct trad_frame_cache *
frv_linux_sigtramp_frame_cache (struct frame_info *this_frame,
				void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct trad_frame_cache *cache;
  CORE_ADDR addr;
  gdb_byte buf[4];
  int regnum;
  CORE_ADDR sc_addr_cache_val = 0;
  struct frame_id this_id;

  if (*this_cache)
    return (struct trad_frame_cache *) *this_cache;

  cache = trad_frame_cache_zalloc (this_frame);

  /* FIXME: cagney/2004-05-01: This is is long standing broken code.
     The frame ID's code address should be the start-address of the
     signal trampoline and not the current PC within that
     trampoline.  */
  get_frame_register (this_frame, sp_regnum, buf);
  addr = extract_unsigned_integer (buf, sizeof buf, byte_order);
  this_id = frame_id_build (addr, get_frame_pc (this_frame));
  trad_frame_set_id (cache, this_id);

  for (regnum = 0; regnum < frv_num_regs; regnum++)
    {
      LONGEST reg_addr = frv_linux_sigcontext_reg_addr (this_frame, regnum,
							&sc_addr_cache_val);
      if (reg_addr != -1)
	trad_frame_set_reg_addr (cache, regnum, reg_addr);
    }

  *this_cache = cache;
  return cache;
}
Example #24
0
static CORE_ADDR
tramp_frame_start (const struct tramp_frame *tramp,
		   struct frame_info *this_frame, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int ti;

  /* Check if we can use this trampoline.  */
  if (tramp->validate && !tramp->validate (tramp, this_frame, &pc))
    return 0;

  /* Search through the trampoline for one that matches the
     instruction sequence around PC.  */
  for (ti = 0; tramp->insn[ti].bytes != TRAMP_SENTINEL_INSN; ti++)
    {
      CORE_ADDR func = pc - tramp->insn_size * ti;
      int i;

      for (i = 0; 1; i++)
	{
	  gdb_byte buf[sizeof (tramp->insn[0])];
	  ULONGEST insn;

	  if (tramp->insn[i].bytes == TRAMP_SENTINEL_INSN)
	    return func;
	  if (!safe_frame_unwind_memory (this_frame,
					 func + i * tramp->insn_size,
					 buf, tramp->insn_size))
	    break;
	  insn = extract_unsigned_integer (buf, tramp->insn_size, byte_order);
	  if (tramp->insn[i].bytes != (insn & tramp->insn[i].mask))
	    break;
	}
    }
  /* Trampoline doesn't match.  */
  return 0;
}
Example #25
0
static CORE_ADDR
sparc32_linux_step_trap (struct frame_info *frame, unsigned long insn)
{
  if (insn == 0x91d02010)
    {
      ULONGEST sc_num = get_frame_register_unsigned (frame, SPARC_G1_REGNUM);

      /* __NR_rt_sigreturn is 101 and __NR_sigreturn is 216  */
      if (sc_num == 101 || sc_num == 216)
	{
	  struct gdbarch *gdbarch = get_frame_arch (frame);
	  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

	  ULONGEST sp, pc_offset;

	  sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);

	  /* The kernel puts the sigreturn registers on the stack,
	     and this is where the signal unwinding state is take from
	     when returning from a signal.

	     For __NR_sigreturn, this register area sits 96 bytes from
	     the base of the stack.  The saved PC sits 4 bytes into the
	     sigreturn register save area.

	     For __NR_rt_sigreturn a siginfo_t, which is 128 bytes, sits
	     right before the sigreturn register save area.  */

	  pc_offset = 96 + 4;
	  if (sc_num == 101)
	    pc_offset += 128;

	  return read_memory_unsigned_integer (sp + pc_offset, 4, byte_order);
	}
    }

  return 0;
}
Example #26
0
static void
ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
			     struct frame_info *next_frame,
			     struct trad_frame_cache *this_cache,
			     CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  CORE_ADDR addr, base;
  int i;

  base = frame_unwind_register_unsigned (next_frame,
					 gdbarch_sp_regnum (current_gdbarch));
  if (self == &ppcnbsd2_sigtramp)
    addr = base + 0x10 + 2 * tdep->wordsize;
  else
    addr = base + 0x18 + 2 * tdep->wordsize;
  for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
    {
      int regnum = i + tdep->ppc_gp0_regnum;
      trad_frame_set_reg_addr (this_cache, regnum, addr);
    }
  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
  addr += tdep->wordsize;
  trad_frame_set_reg_addr (this_cache,
			   gdbarch_pc_regnum (current_gdbarch),
			   addr); /* SRR0? */
  addr += tdep->wordsize;

  /* Construct the frame ID using the function start.  */
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
Example #27
0
static CORE_ADDR
i386_darwin_sigcontext_addr (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR bp;
  CORE_ADDR si;
  gdb_byte buf[4];

  get_frame_register (this_frame, I386_EBP_REGNUM, buf);
  bp = extract_unsigned_integer (buf, 4, byte_order);

  /* A pointer to the ucontext is passed as the fourth argument
     to the signal handler.  */
  read_memory (bp + 24, buf, 4);
  si = extract_unsigned_integer (buf, 4, byte_order);

  /* The pointer to mcontext is at offset 28.  */
  read_memory (si + 28, buf, 4);

  /* First register (eax) is at offset 12.  */
  return extract_unsigned_integer (buf, 4, byte_order) + 12;
}
/* Implement the "init" routine in struct tramp_frame for the N32 ABI
   on mips-irix.  */
static void
mips_irix_n32_tramp_frame_init (const struct tramp_frame *self,
				struct frame_info *this_frame,
				struct trad_frame_cache *this_cache,
				CORE_ADDR func)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  const int num_regs = gdbarch_num_regs (gdbarch);
  int sp_cooked_regno = num_regs + MIPS_SP_REGNUM;
  const CORE_ADDR sp = get_frame_register_signed (this_frame, sp_cooked_regno);
  const CORE_ADDR sigcontext_base = sp + 48;
  const struct mips_regnum *regs = mips_regnum (gdbarch);
  int ireg;

  trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (gdbarch),
                           sigcontext_base + SIGCONTEXT_PC_OFF);

  for (ireg = 1; ireg < 32; ireg++)
    trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + num_regs,
                             sigcontext_base + SIGCONTEXT_REGS_OFF + ireg * 8);

  for (ireg = 0; ireg < 32; ireg++)
    trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + num_regs,
                             sigcontext_base + SIGCONTEXT_FPREGS_OFF
                               + ireg * 8);

  trad_frame_set_reg_addr (this_cache, regs->fp_control_status + num_regs,
                           sigcontext_base + SIGCONTEXT_FPCSR_OFF);

  trad_frame_set_reg_addr (this_cache, regs->hi + num_regs,
                           sigcontext_base + SIGCONTEXT_HI_OFF);

  trad_frame_set_reg_addr (this_cache, regs->lo + num_regs,
                           sigcontext_base + SIGCONTEXT_LO_OFF);

  trad_frame_set_id (this_cache, frame_id_build (sigcontext_base, func));
}
Example #29
0
static CORE_ADDR
alphaobsd_sigcontext_addr (struct frame_info *this_frame)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (alphaobsd_sigtramp_offset (gdbarch, pc) < 3 * ALPHA_INSN_SIZE)
    {
      /* On entry, a pointer the `struct sigcontext' is passed in %a2.  */
      return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM + 2);
    }
  else if (alphaobsd_sigtramp_offset (gdbarch, pc) < 4 * ALPHA_INSN_SIZE)
    {
      /* It is stored on the stack Before calling the signal handler.  */
      CORE_ADDR sp;
      sp = get_frame_register_unsigned (this_frame, ALPHA_SP_REGNUM);
      return get_frame_memory_unsigned (this_frame, sp, 8);
    }
  else
    {
      /* It is reloaded into %a0 for the sigreturn(2) call.  */
      return get_frame_register_unsigned (this_frame, ALPHA_A0_REGNUM);
    }
}
Example #30
0
static int
arm_linux_software_single_step (struct frame_info *frame)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct address_space *aspace = get_frame_address_space (frame);
  CORE_ADDR next_pc;

  if (arm_deal_with_atomic_sequence (frame))
    return 1;

  next_pc = arm_get_next_pc (frame, get_frame_pc (frame));

  /* 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 called as functions and return
     to the address in LR, so step to there instead.  */
  if (next_pc > 0xffff0000)
    next_pc = get_frame_register_unsigned (frame, ARM_LR_REGNUM);

  arm_insert_single_step_breakpoint (gdbarch, aspace, next_pc);

  return 1;
}