示例#1
0
CORE_ADDR
libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
  struct libunwind_frame_cache *cache =
    libunwind_frame_cache (next_frame, this_cache);

  return cache->base;
}
示例#2
0
void
libunwind_frame_this_id (struct frame_info *next_frame, void **this_cache,
		      struct frame_id *this_id)
{
  struct libunwind_frame_cache *cache =
    libunwind_frame_cache (next_frame, this_cache);

  (*this_id) = frame_id_build (cache->base, cache->func_addr);
}
void
libunwind_frame_this_id (struct frame_info *this_frame, void **this_cache,
		         struct frame_id *this_id)
{
  struct libunwind_frame_cache *cache =
    libunwind_frame_cache (this_frame, this_cache);

  if (cache != NULL)
    (*this_id) = frame_id_build (cache->base, cache->func_addr);
}
示例#4
0
void
libunwind_frame_prev_register (struct frame_info *next_frame, void **this_cache,
			       int regnum, int *optimizedp,
			       enum lval_type *lvalp, CORE_ADDR *addrp,
			       int *realnump, void *valuep)
{
  struct libunwind_frame_cache *cache =
    libunwind_frame_cache (next_frame, this_cache);

  void *ptr;
  unw_cursor_t *c;
  unw_save_loc_t sl;
  int i, ret;
  unw_word_t intval;
  unw_fpreg_t fpval;
  unw_regnum_t uw_regnum;
  struct libunwind_descr *descr;

  /* Convert from gdb register number to libunwind register number.  */
  descr = libunwind_descr (get_frame_arch (next_frame));
  uw_regnum = descr->gdb2uw (regnum);

  gdb_assert (regnum >= 0);

  if (!target_has_registers)
    error ("No registers.");

  *optimizedp = 0;
  *addrp = 0;
  *lvalp = not_lval;
  *realnump = -1;

  if (valuep)
    memset (valuep, 0, register_size (current_gdbarch, regnum));

  if (uw_regnum < 0)
    return;

  /* To get the previous register, we use the libunwind register APIs with
     the cursor we have already pushed back to the previous frame.  */

  if (descr->is_fpreg (uw_regnum))
    {
      ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
      ptr = &fpval;
    }
  else
    {
      ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
      ptr = &intval;
    }

  if (ret < 0)
    return;

  if (valuep)
    memcpy (valuep, ptr, register_size (current_gdbarch, regnum));

  if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
    return;

  switch (sl.type)
    {
    case UNW_SLT_NONE:
      *optimizedp = 1;
      break;

    case UNW_SLT_MEMORY:
      *lvalp = lval_memory;
      *addrp = sl.u.addr;
      break;

    case UNW_SLT_REG:
      *lvalp = lval_register;
      *realnump = regnum;
      break;
    }
} 
struct value *
libunwind_frame_prev_register (struct frame_info *this_frame,
                               void **this_cache, int regnum)
{
  struct libunwind_frame_cache *cache =
    libunwind_frame_cache (this_frame, this_cache);
  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  void *ptr;
  unw_cursor_t *c;
  unw_save_loc_t sl;
  int i, ret;
  unw_word_t intval;
  unw_fpreg_t fpval;
  unw_regnum_t uw_regnum;
  struct libunwind_descr *descr;
  struct value *val = NULL;

  if (cache == NULL)
    return frame_unwind_got_constant (this_frame, regnum, 0);
  
  /* Convert from gdb register number to libunwind register number.  */
  descr = libunwind_descr (get_frame_arch (this_frame));
  uw_regnum = descr->gdb2uw (regnum);

  gdb_assert (regnum >= 0);

  if (!target_has_registers)
    error (_("No registers."));

  if (uw_regnum < 0)
    return frame_unwind_got_constant (this_frame, regnum, 0);

  if (unw_get_saveloc_p (&cache->cursor, uw_regnum, &sl) < 0)
    return frame_unwind_got_constant (this_frame, regnum, 0);

  switch (sl.type)
    {
    case UNW_SLT_MEMORY:
      val = frame_unwind_got_memory (this_frame, regnum, sl.u.addr);
      break;

    case UNW_SLT_REG:
      val = frame_unwind_got_register (this_frame, regnum,
                                       descr->uw2gdb (sl.u.regnum));
      break;
    case UNW_SLT_NONE:
      {
        /* The register is not stored at a specific memory address nor
           inside another register.  So use libunwind to fetch the register
           value for us, and create a constant value with the result.  */
        if (descr->is_fpreg (uw_regnum))
          {
            ret = unw_get_fpreg_p (&cache->cursor, uw_regnum, &fpval);
            if (ret < 0)
              return frame_unwind_got_constant (this_frame, regnum, 0);
            val = frame_unwind_got_bytes (this_frame, regnum,
                                          (gdb_byte *) &fpval);
          }
        else
          {
            ret = unw_get_reg_p (&cache->cursor, uw_regnum, &intval);
            if (ret < 0)
              return frame_unwind_got_constant (this_frame, regnum, 0);
            val = frame_unwind_got_constant (this_frame, regnum, intval);
          }
        break;
      }
    }

  return val;
}