Пример #1
0
static CORE_ADDR
tilegx_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  CORE_ADDR func_start, end_pc;
  struct obj_section *s;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, NULL))
    {
      CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_start);

      if (post_prologue_pc != 0)
        return max (start_pc, post_prologue_pc);
    }

  /* Don't straddle a section boundary.  */
  s = find_pc_section (start_pc);
  end_pc = start_pc + 8 * TILEGX_BUNDLE_SIZE_IN_BYTES;
  if (s != NULL)
    end_pc = min (end_pc, obj_section_endaddr (s));

  /* Otherwise, try to skip prologue the hard way.  */
  return tilegx_analyze_prologue (gdbarch,
				  start_pc,
				  end_pc,
				  NULL, NULL);
}
Пример #2
0
CORE_ADDR
microblaze_skip_prologue (CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;
  CORE_ADDR start_pc = 0;
  CORE_ADDR ostart_pc = 0;

  /* If we have line debugging information, then the end of the
     prologue should the first assembly instruction of  the first
     source line */
  /* Debugging info does not always give the right answer since 
     parameters are stored on stack after this.  Always analyze the prologue */
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);
      if (sal.end && sal.end < func_end)
	start_pc = sal.end;
    }
  ostart_pc = microblaze_analyze_prologue (NULL, pc);
  if (ostart_pc > start_pc)
    return ostart_pc;
  else
    return start_pc;
}
Пример #3
0
static int
vaxobsd_sigtramp_sniffer (const struct frame_unwind *self,
			  struct frame_info *this_frame,
			  void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR start_pc = (pc & ~(vaxobsd_page_size - 1));
  CORE_ADDR sigreturn_addr = start_pc + vaxobsd_sigreturn_offset;
  gdb_byte *buf;
  const char *name;

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

  buf = alloca(sizeof vaxobsd_sigreturn);
  if (!safe_frame_unwind_memory (this_frame, sigreturn_addr,
				 buf, sizeof vaxobsd_sigreturn))
    return 0;

  if (memcmp(buf, vaxobsd_sigreturn, sizeof vaxobsd_sigreturn) == 0)
    return 1;

  return 0;
}
Пример #4
0
bool
find_function_entry_range_from_pc (CORE_ADDR pc, const char **name,
				   CORE_ADDR *address, CORE_ADDR *endaddr)
{
  const struct block *block;
  bool status = find_pc_partial_function (pc, name, address, endaddr, &block);

  if (status && block != nullptr && !BLOCK_CONTIGUOUS_P (block))
    {
      CORE_ADDR entry_pc = BLOCK_ENTRY_PC (block);

      for (int i = 0; i < BLOCK_NRANGES (block); i++)
        {
	  if (BLOCK_RANGE_START (block, i) <= entry_pc
	      && entry_pc < BLOCK_RANGE_END (block, i))
	    {
	      if (address != nullptr)
	        *address = BLOCK_RANGE_START (block, i);

	      if (endaddr != nullptr)
	        *endaddr = BLOCK_RANGE_END (block, i);

	      return status;
	    }
	}

      /* It's an internal error if we exit the above loop without finding
         the range.  */
      internal_error (__FILE__, __LINE__,
                      _("Entry block not found in find_function_entry_range_from_pc"));
    }

  return status;
}
Пример #5
0
/* Simple frame_unwind_cache.  
   This finds the "extra info" for the frame.  */
struct trad_frame_cache *
mn10300_frame_unwind_cache (struct frame_info *next_frame,
			    void **this_prologue_cache)
{
  struct trad_frame_cache *cache;
  CORE_ADDR pc, start, end;

  if (*this_prologue_cache)
    return (*this_prologue_cache);

  cache = trad_frame_cache_zalloc (next_frame);
  pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
  mn10300_analyze_prologue (next_frame, (void **) &cache, pc);
  if (find_pc_partial_function (pc, NULL, &start, &end))
    trad_frame_set_id (cache, 
		       frame_id_build (trad_frame_get_this_base (cache), 
				       start));
  else
    trad_frame_set_id (cache, 
		       frame_id_build (trad_frame_get_this_base (cache), 
				       frame_func_unwind (next_frame)));

  (*this_prologue_cache) = cache;
  return cache;
}
Пример #6
0
static int
i386nbsd_trapframe_sniffer (const struct frame_unwind *self,
			    struct frame_info *this_frame,
			    void **this_prologue_cache)
{
  ULONGEST cs;
  const char *name;

  /* Check Current Privilege Level and bail out if we're not executing
     in kernel space.  */
  cs = get_frame_register_unsigned (this_frame, I386_CS_REGNUM);
  if ((cs & I386_SEL_RPL) == I386_SEL_UPL)
    return 0;


  find_pc_partial_function (get_frame_pc (this_frame), &name, NULL, NULL);
  return (name && ((strcmp (name, "alltraps") == 0)
		   || (strcmp (name, "calltrap") == 0)
		   || (strncmp (name, "Xtrap", 5) == 0)
		   || (strcmp (name, "syscall1") == 0)
		   || (strcmp (name, "Xsyscall") == 0)
		   || (strncmp (name, "Xintr", 5) == 0)
		   || (strncmp (name, "Xresume", 7) == 0)
		   || (strncmp (name, "Xstray", 6) == 0)
		   || (strncmp (name, "Xrecurse", 8) == 0)
		   || (strncmp (name, "Xsoft", 5) == 0)
		   || (strncmp (name, "Xdoreti", 5) == 0)));
}
Пример #7
0
static struct mdebug_extra_func_info *
find_proc_desc (CORE_ADDR pc)
{
  struct block *b = block_for_pc (pc);
  struct mdebug_extra_func_info *proc_desc = NULL;
  struct symbol *sym = NULL;

  if (b)
    {
      CORE_ADDR startaddr;
      find_pc_partial_function (pc, NULL, &startaddr, NULL);

      if (startaddr > BLOCK_START (b))
	/* This is the "pathological" case referred to in a comment in
	   print_frame_info.  It might be better to move this check into
	   symbol reading.  */
	sym = NULL;
      else
	sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL);
    }

  if (sym)
    {
      proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE (sym);

      /* If we never found a PDR for this function in symbol reading,
	 then examine prologues to find the information.  */
      if (proc_desc->pdr.framereg == -1)
	proc_desc = NULL;
    }

  return proc_desc;
}
Пример #8
0
static CORE_ADDR
lm32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr, limit_pc;
  struct symtab_and_line sal;
  struct lm32_frame_cache frame_info;
  struct trad_frame_saved_reg saved_regs[SIM_LM32_NUM_REGS];

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return max (pc, post_prologue_pc);
    }

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  */

  /* Find an upper limit on the function prologue using the debug
     information.  If the debug information could not be used to provide
     that bound, then use an arbitrary large number as the upper bound.  */
  limit_pc = skip_prologue_using_sal (gdbarch, pc);
  if (limit_pc == 0)
    limit_pc = pc + 100;	/* Magic.  */

  frame_info.saved_regs = saved_regs;
  return lm32_analyze_prologue (gdbarch, pc, limit_pc, &frame_info);
}
Пример #9
0
static int
tramp_frame_sniffer (const struct frame_unwind *self,
		     struct frame_info *next_frame,
		     void **this_cache)
{
  const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  CORE_ADDR func;
  char *name;
  struct tramp_frame_cache *tramp_cache;

  /* If the function has a valid symbol name, it isn't a
     trampoline.  */
  find_pc_partial_function (pc, &name, NULL, NULL);
  if (name != NULL)
    return 0;
  /* If the function lives in a valid section (even without a starting
     point) it isn't a trampoline.  */
  if (find_pc_section (pc) != NULL)
    return 0;
  /* Finally, check that the trampoline matches at PC.  */
  func = tramp_frame_start (tramp, next_frame, pc);
  if (func == 0)
    return 0;
  tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
  tramp_cache->func = func;
  tramp_cache->tramp_frame = tramp;
  (*this_cache) = tramp_cache;
  return 1;
}
Пример #10
0
static CORE_ADDR
d10v_skip_prologue (CORE_ADDR pc)
{
  unsigned long op;
  unsigned short op1, op2;
  CORE_ADDR func_addr, func_end;
  struct symtab_and_line sal;

  /* If we have line debugging information, then the end of the prologue
     should be the first assembly instruction of the first source line.  */
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    {
      sal = find_pc_line (func_addr, 0);
      if (sal.end && sal.end < func_end)
	return sal.end;
    }

  if (target_read_memory (pc, (char *) &op, 4))
    return pc;			/* Can't access it -- assume no prologue.  */

  while (1)
    {
      op = (unsigned long) read_memory_integer (pc, 4);
      if ((op & 0xC0000000) == 0xC0000000)
	{
	  /* long instruction */
	  if (((op & 0x3FFF0000) != 0x01FF0000) &&	/* add3 sp,sp,n */
	      ((op & 0x3F0F0000) != 0x340F0000) &&	/* st  rn, @(offset,sp) */
	      ((op & 0x3F1F0000) != 0x350F0000))	/* st2w  rn, @(offset,sp) */
	    break;
	}
      else
	{
	  /* short instructions */
	  if ((op & 0xC0000000) == 0x80000000)
	    {
	      op2 = (op & 0x3FFF8000) >> 15;
	      op1 = op & 0x7FFF;
	    }
	  else
	    {
	      op1 = (op & 0x3FFF8000) >> 15;
	      op2 = op & 0x7FFF;
	    }
	  if (check_prologue (op1))
	    {
	      if (!check_prologue (op2))
		{
		  /* If the previous opcode was really part of the
		     prologue and not just a NOP, then we want to
		     break after both instructions.  */
		  if (op1 != 0x5E00)
		    pc += 4;
		  break;
		}
	    }
	  else
	    break;
	}
Пример #11
0
static int
i386nto_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return name && strcmp ("__signalstub", name) == 0;
}
Пример #12
0
static int
amd64nbsd_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return nbsd_pc_in_sigtramp (pc, name);
}
Пример #13
0
static int
amd64_sol2_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return (name && (strcmp ("sigacthandler", name) == 0
		   || strcmp (name, "ucbsigvechandler") == 0));
}
Пример #14
0
static int
nios2_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr;

  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    return nios2_in_epilogue_p (gdbarch, pc, func_addr);

  return 0;
}
Пример #15
0
static int
i386nbsd_sigtramp_p (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return (nbsd_pc_in_sigtramp (pc, name)
	  || i386nbsd_sigtramp_offset (next_frame) >= 0);
}
Пример #16
0
static int
i386_sol2_sigtramp_p (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return (name && (strcmp ("sigacthandler", name) == 0
		   || strcmp (name, "ucbsigvechandler") == 0));
}
Пример #17
0
void
microblaze_pop_frame (struct frame_info *fi)
{
  int rn;
  CORE_ADDR func_addr, func_end, addr;
  enum microblaze_instr op;
  int insn, rd, ra, rb, imm;
  int status;
  char *name;
  int offset = 0;	/* offset that the return instruction specifies */

  /* Find the start and end of this function. */
  /* siva/9/19/05: pop frame was not computing this offset. copied code from
     microblaze_fix_call_dummy to find the return insn & the offset */
  status = find_pc_partial_function (fi->pc, &name, &func_addr, &func_end);

  for (addr = func_addr; addr < func_end; addr += INST_WORD_SIZE) {
	  /* Start decoding the function looking for rtsd */
	  insn = get_insn (addr);
	  op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);

	  /* Check for return. */
	  if (IS_RETURN(op)) {
		  offset = imm;
		  break; 
	  }
  }

  if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
    generic_pop_dummy_frame ();
  else
    {
      /* Write out the PC we saved. */
      write_register (PC_REGNUM, FRAME_SAVED_PC (fi) + offset);

      /* Restore any saved registers. */
      for (rn = 0; rn < NUM_REGS; rn++)
	{
	  if (fi->saved_regs[rn] != 0)
	    {
	      ULONGEST value;

	      value = read_memory_unsigned_integer (fi->saved_regs[rn],
						    REGISTER_SIZE);
	      write_register (rn, value);
	    }
	}

      /* Actually cut back the stack. */
      write_register (SP_REGNUM, FRAME_FP (fi));
    }

  /* Finally, throw away any cached frame information. */
  flush_cached_frames ();
}
Пример #18
0
/*
   **    _getFuncNameFromFrame().
 */
static char *
_getFuncNameFromFrame (struct frame_info *frameInfo)
{
  char *funcName = (char *) NULL;

  find_pc_partial_function (frameInfo->pc,
			    &funcName,
			    (CORE_ADDR *) NULL,
			    (CORE_ADDR *) NULL);
  return funcName;
}				/* _getFuncNameFromFrame */
Пример #19
0
static const struct frame_unwind *
sparc64_sol2_sigtramp_frame_sniffer (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (sparc_sol2_pc_in_sigtramp (pc, name))
    return &sparc64_sol2_sigtramp_frame_unwind;

  return NULL;
}
Пример #20
0
static int
mips_sde_frame_sniffer (const struct frame_unwind *self,
			struct frame_info *this_frame,
			void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  return (name
	  && (strcmp (name, "_xcptcall") == 0
	      || strcmp (name, "_sigtramp") == 0));
}
Пример #21
0
static int
amd64fbsd_trapframe_sniffer (const struct frame_unwind *self,
                             struct frame_info *this_frame,
                             void **this_prologue_cache)
{
    const char *name;

    find_pc_partial_function (get_frame_func (this_frame), &name, NULL, NULL);
    return (name && ((strcmp (name, "calltrap") == 0)
                     || (strcmp (name, "fork_trampoline") == 0)
                     || (strcmp (name, "nmi_calltrap") == 0)
                     || (name[0] == 'X' && name[1] != '_')));
}
Пример #22
0
static int
ppcfbsd_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 = (enum bfd_endian)gdbarch_byte_order(gdbarch);
  CORE_ADDR pc = get_frame_pc(this_frame);
  CORE_ADDR start_pc = (pc & ~(ppcfbsd_page_size - 1));
  const int *offset;
  const char *name;

  /* A stack trampoline is detected if no name is associated
   to the current pc and if it points inside a trampoline
   sequence.  */

  find_pc_partial_function (pc, &name, NULL, NULL);

  /* If we have a name, we have no trampoline, return.  */
  if (name)
    return 0;

  for (offset = ppcfbsd_sigreturn_offset; *offset != -1; offset++)
    {
#ifdef PPC_INSN_SIZE
      gdb_byte buf[2 * PPC_INSN_SIZE];
#else
      gdb_byte buf[2 * sizeof(unsigned long)];
#endif /* 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 != 0x380001a1)
	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;
}
Пример #23
0
static CORE_ADDR
moxie_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr = 0, func_end = 0;
  char *func_name;

  /* See if we can determine the end of the prologue via the symbol table.
     If so, then return either PC, or the PC after the prologue, whichever
     is greater.  */
  if (find_pc_partial_function (pc, &func_name, &func_addr, &func_end))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      if (post_prologue_pc != 0)
	return max (pc, post_prologue_pc);
      else
	{
	  /* Can't determine prologue from the symbol table, need to examine
	     instructions.  */
	  struct symtab_and_line sal;
	  struct symbol *sym;
	  struct moxie_frame_cache cache;
	  CORE_ADDR plg_end;
	  
	  memset (&cache, 0, sizeof cache);
	  
	  plg_end = moxie_analyze_prologue (func_addr, 
					    func_end, &cache, NULL);
	  /* Found a function.  */
	  sym = lookup_symbol (func_name, NULL, VAR_DOMAIN, NULL);
	  /* Don't use line number debug info for assembly source
	     files. */
	  if (sym && SYMBOL_LANGUAGE (sym) != language_asm)
	    {
	      sal = find_pc_line (func_addr, 0);
	      if (sal.end && sal.end < func_end)
		{
		  /* Found a line number, use it as end of
		     prologue.  */
		  return sal.end;
		}
	    }
	  /* No useable line symbol.  Use result of prologue parsing
	     method.  */
	  return plg_end;
	}
    }

  /* No function symbol -- just return the PC.  */
  return (CORE_ADDR) pc;
}
Пример #24
0
static struct trad_frame_cache *
amd64fbsd_trapframe_cache (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);
    struct trad_frame_cache *cache;
    CORE_ADDR addr, func, pc, sp;
    const char *name;
    int i;

    if (*this_cache != NULL)
        return (*this_cache);

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

    func = get_frame_func (this_frame);
    sp = get_frame_register_unsigned (this_frame, AMD64_RSP_REGNUM);

    find_pc_partial_function (func, &name, NULL, NULL);
    if (strcmp(name, "fork_trampoline") == 0 && get_frame_pc (this_frame) == func)
    {
        /* fork_exit hasn't been called (kthread has never run), so %rsp
        in the pcb points to the trapframe.  GDB has auto-adjusted
         %rsp for this frame to account for the "call" into
         fork_trampoline, so "undo" the adjustment.  */
        sp += 8;
    }

    for (i = 0; i < ARRAY_SIZE (amd64fbsd_trapframe_offset); i++)
        if (amd64fbsd_trapframe_offset[i] != -1)
            trad_frame_set_reg_addr (cache, i, sp + amd64fbsd_trapframe_offset[i]);

    /* Read %rip from trap frame.  */
    addr = sp + amd64fbsd_trapframe_offset[AMD64_RIP_REGNUM];
    pc = read_memory_unsigned_integer (addr, 8, byte_order);

    if (pc == 0 && strcmp(name, "fork_trampoline") == 0)
    {
        /* Initial frame of a kthread; terminate backtrace.  */
        trad_frame_set_id (cache, outer_frame_id);
    }
    else
    {
        /* Construct the frame ID using the function start.  */
        trad_frame_set_id (cache, frame_id_build (sp + TRAPFRAME_SIZE, func));
    }

    return cache;
}
static int
sparc64_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
				     struct frame_info *this_frame,
				     void **this_cache)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (sparc_sol2_pc_in_sigtramp (pc, name))
    return 1;

  return 0;
}
Пример #26
0
/* Implement the "skip_prologue" gdbarch method.  */
static CORE_ADDR
rx_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  const char *name;
  CORE_ADDR func_addr, func_end;
  struct rx_prologue p;

  /* Try to find the extent of the function that contains PC.  */
  if (!find_pc_partial_function (pc, &name, &func_addr, &func_end))
    return pc;

  rx_analyze_prologue (pc, func_end, &p);
  return p.prologue_end;
}
Пример #27
0
static CORE_ADDR
sparc32_skip_prologue (CORE_ADDR start_pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end;
  struct sparc_frame_cache cache;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end
	  && start_pc <= sal.end)
	return sal.end;
    }

  start_pc = sparc_analyze_prologue (start_pc, 0xffffffffUL, &cache);

  /* The psABI says that "Although the first 6 words of arguments
     reside in registers, the standard stack frame reserves space for
     them.".  It also suggests that a function may use that space to
     "write incoming arguments 0 to 5" into that space, and that's
     indeed what GCC seems to be doing.  In that case GCC will
     generate debug information that points to the stack slots instead
     of the registers, so we should consider the instructions that
     write out these incoming arguments onto the stack.  Of course we
     only need to do this if we have a stack frame.  */

  while (!cache.frameless_p)
    {
      unsigned long insn = sparc_fetch_instruction (start_pc);

      /* Recognize instructions that store incoming arguments in
         %i0...%i5 into the corresponding stack slot.  */
      if (X_OP (insn) == 3 && (X_OP3 (insn) & 0x3c) == 0x04 && X_I (insn)
	  && (X_RD (insn) >= 24 && X_RD (insn) <= 29) && X_RS1 (insn) == 30
	  && X_SIMM13 (insn) == 68 + (X_RD (insn) - 24) * 4)
	{
	  start_pc += 4;
	  continue;
	}

      break;
    }

  return start_pc;
}
Пример #28
0
static int
amd64obsd_sigtramp_p (struct frame_info *this_frame)
{
  CORE_ADDR pc = get_frame_pc (this_frame);
  CORE_ADDR start_pc = (pc & ~(amd64obsd_page_size - 1));
  const gdb_byte osigreturn[] =
  {
    0x48, 0xc7, 0xc0,
    0x67, 0x00, 0x00, 0x00,	/* movq $SYS_sigreturn, %rax */
    0xcd, 0x80			/* int $0x80 */
  };
  const gdb_byte sigreturn[] =
  {
    0x48, 0xc7, 0xc0,
    0x67, 0x00, 0x00, 0x00,	/* movq $SYS_sigreturn, %rax */
    0x0f, 0x05			/* syscall */
  };
  size_t buflen = (sizeof sigreturn) + 1;
  gdb_byte *buf;
  const char *name;

  /* If the function has a valid symbol name, it isn't a
     trampoline.  */
  find_pc_partial_function (pc, &name, NULL, NULL);
  if (name != NULL)
    return 0;

  /* If the function lives in a valid section (even without a starting
     point) it isn't a trampoline.  */
  if (find_pc_section (pc) != NULL)
    return 0;

  /* If we can't read the instructions at START_PC, return zero.  */
  buf = (gdb_byte *) alloca ((sizeof sigreturn) + 1);
  if (!safe_frame_unwind_memory (this_frame, start_pc + 6, buf, buflen))
    return 0;

  /* Check for sigreturn(2).  Depending on how the assembler encoded
     the `movq %rsp, %rdi' instruction, the code starts at offset 6 or
     7.  OpenBSD 5.0 and later use the `syscall' instruction.  Older
     versions use `int $0x80'.  Check for both.  */
  if (memcmp (buf, sigreturn, sizeof sigreturn)
      && memcmp (buf + 1, sigreturn, sizeof sigreturn)
      && memcmp (buf, osigreturn, sizeof osigreturn)
      && memcmp (buf + 1, osigreturn, sizeof osigreturn))
    return 0;

  return 1;
}
Пример #29
0
static int
frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
				  struct frame_info *this_frame,
				  void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);
  const char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (frv_linux_pc_in_sigtramp (gdbarch, pc, name))
    return 1;

  return 0;
}
Пример #30
0
static const struct frame_unwind *
sparc64nbsd_sigtramp_frame_sniffer (struct frame_info *next_frame)
{
  CORE_ADDR pc = frame_pc_unwind (next_frame);
  char *name;

  find_pc_partial_function (pc, &name, NULL, NULL);
  if (sparc64nbsd_pc_in_sigtramp (pc, name))
    {
      if (name == NULL || strncmp (name, "__sigtramp_sigcontext", 21))
	return &sparc64nbsd_sigcontext_frame_unwind;
    }

  return NULL;
}