Пример #1
0
static _Unwind_Ptr
get_ttype_entry_for (region_descriptor *region, long filter)
{
  _Unwind_Ptr ttype_entry;

  filter *= size_of_encoded_value (region->ttype_encoding);
  read_encoded_value_with_base
    (region->ttype_encoding, region->ttype_base,
     region->ttype_table - filter, &ttype_entry);

  return ttype_entry;
}
Пример #2
0
static int
get_cie_encoding (const struct dwarf_cie *cie)
{
  const unsigned char *aug, *p;
  _Unwind_Ptr dummy;
  _uleb128_t utmp;
  _sleb128_t stmp;

  aug = cie->augmentation;
  p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string.  */
  if (__builtin_expect (cie->version >= 4, 0))
    {
      if (p[0] != sizeof (void *) || p[1] != 0)
	return DW_EH_PE_omit;		/* We are not prepared to handle unexpected
					   address sizes or segment selectors.  */
      p += 2;				/* Skip address size and segment size.  */
    }

  if (aug[0] != 'z')
    return DW_EH_PE_absptr;

  p = read_uleb128 (p, &utmp);		/* Skip code alignment.  */
  p = read_sleb128 (p, &stmp);		/* Skip data alignment.  */
  if (cie->version == 1)		/* Skip return address column.  */
    p++;
  else
    p = read_uleb128 (p, &utmp);

  aug++;				/* Skip 'z' */
  p = read_uleb128 (p, &utmp);		/* Skip augmentation length.  */
  while (1)
    {
      /* This is what we're looking for.  */
      if (*aug == 'R')
	return *p;
      /* Personality encoding and pointer.  */
      else if (*aug == 'P')
	{
	  /* ??? Avoid dereferencing indirect pointers, since we're
	     faking the base address.  Gotta keep DW_EH_PE_aligned
	     intact, however.  */
	  p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
	}
      /* LSDA encoding.  */
      else if (*aug == 'L')
	p++;
      /* Otherwise end of string, or unknown augmentation.  */
      else
	return DW_EH_PE_absptr;
      aug++;
    }
}
Пример #3
0
static Class
get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i)
{
  _Unwind_Ptr ptr;

  i *= size_of_encoded_value (info->ttype_encoding);
  read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
				info->TType - i, &ptr);

  /* NULL ptr means catch-all.  */
  if (ptr)
    return objc_get_class ((const char *) ptr);
  else
    return 0;
}
Пример #4
0
static Class
get_ttype_entry (struct lsda_header_info *info, _Unwind_Word i)
{
  _Unwind_Ptr ptr;

  i *= size_of_encoded_value (info->ttype_encoding);
  read_encoded_value_with_base (info->ttype_encoding, info->ttype_base,
				info->TType - i, &ptr);

  /* NULL ptr means catch-all.  Note that if the class is not found,
     this will abort the program.  */
  if (ptr)
    return objc_getRequiredClass ((const char *) ptr);
  else
    return 0;
}
Пример #5
0
static int
get_cie_encoding (struct dwarf_cie *cie)
{
  const unsigned char *aug, *p;
  _Unwind_Ptr dummy;
  _Unwind_Word utmp;
  _Unwind_Sword stmp;

  aug = cie->augmentation;
  if (aug[0] != 'z')
    return DW_EH_PE_absptr;

  /* Skip the augmentation string.  */
  p = aug + strlen ((const char *) aug) + 1;
  p = read_uleb128 (p, &utmp);		/* Skip code alignment.  */
  p = read_sleb128 (p, &stmp);		/* Skip data alignment.  */
  p++;					/* Skip return address column.  */

  aug++;				/* Skip 'z' */
  p = read_uleb128 (p, &utmp);		/* Skip augmentation length.  */
  while (1)
    {
      /* This is what we're looking for.  */
      if (*aug == 'R')
	return *p;
      /* Personality encoding and pointer.  */
      else if (*aug == 'P')
	{
	  /* ??? Avoid dereferencing indirect pointers, since we're
	     faking the base address.  Gotta keep DW_EH_PE_aligned
	     intact, however.  */
	  p = read_encoded_value_with_base (*p & 0x7F, 0, p + 1, &dummy);
	}
      /* LSDA encoding.  */
      else if (*aug == 'L')
	p++;
      /* Otherwise end of string, or unknown augmentation.  */
      else
	return DW_EH_PE_absptr;
      aug++;
    }
}
Пример #6
0
static inline const fde *
examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
{
  const fde *result = NULL;
  struct live_images *image;

  image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);

  for (; image != NULL; image = image->next)
    if ((image->examined_p & EXAMINED_IMAGE_MASK) == 0)
      {
        char *fde = NULL;
        unsigned long sz;

        /* For ppc only check whether or not we have __DATA eh frames.  */
#ifdef __ppc__
        fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
#endif

        if (fde == NULL)
          {
#if __LP64__
            fde = getsectdatafromheader_64 ((struct mach_header_64 *) image->mh,
                                            "__TEXT", "__eh_frame", &sz);
#else
            fde = getsectdatafromheader (image->mh, "__TEXT",
                                         "__eh_frame", &sz);
#endif
            if (fde != NULL)
              image->examined_p |= IMAGE_IS_TEXT_MASK;
          }

        /* If .eh_frame is empty, don't register at all.  */
        if (fde != NULL && sz > 0)
          {
            char *real_fde = (fde + image->vm_slide);
            struct object *ob = NULL;
            struct object panicob;

            if (! dont_alloc)
              ob = calloc (1, sizeof (struct object));
            dont_alloc |= ob == NULL;
            if (dont_alloc)
              ob = &panicob;

            ob->pc_begin = (void *)-1;
            ob->tbase = 0;
            ob->dbase = 0;
            ob->u.single = (struct dwarf_fde *)real_fde;
            ob->s.i = 0;
            ob->s.b.encoding = DW_EH_PE_omit;
            ob->fde_end = real_fde + sz;

            image->fde = real_fde;

            result = search_object (ob, pc);

            if (! dont_alloc)
              {
                struct object **p;

                image->destructor = live_image_destructor;
                image->object_info = ob;

                image->examined_p |= (EXAMINED_IMAGE_MASK
                                      | DESTRUCTOR_MAY_BE_CALLED_LIVE);

                /* Insert the object into the classified list.  */
                for (p = &seen_objects; *p ; p = &(*p)->next)
                  if ((*p)->pc_begin < ob->pc_begin)
                    break;
                ob->next = *p;
                *p = ob;
              }

            if (result)
              {
                int encoding;
                _Unwind_Ptr func;

                bases->tbase = ob->tbase;
                bases->dbase = ob->dbase;

                encoding = ob->s.b.encoding;
                if (ob->s.b.mixed_encoding)
                  encoding = get_fde_encoding (result);
                read_encoded_value_with_base (encoding,
                                              base_from_object (encoding, ob),
                                              result->pc_begin, &func);
                bases->func = (void *) func;
                break;
              }
          }
        else
          image->examined_p |= EXAMINED_IMAGE_MASK;
      }

  _keymgr_unlock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);

  return result;
}
Пример #7
0
static inline const unsigned char *
read_encoded_value(struct _Unwind_Context *context, unsigned char encoding,
                   const unsigned char *p, _Unwind_Ptr *val) {
  return read_encoded_value_with_base(encoding,
           base_of_encoded_value(encoding, context), p, val);
}
Пример #8
0
enum compact_entry_type
_Unwind_Search_Compact_eh_hdr (void *pc, const unsigned char *hdr,
    struct compact_eh_bases *bases)
{
  int lo, hi, mid;
  _Unwind_Ptr p;
  _Unwind_Ptr nrec;
  const struct compact_eh_index *ind;

  bases->eh_encoding = hdr[1];
  read_encoded_value_with_base (DW_EH_PE_absptr | DW_EH_PE_udata4, 0,
				hdr + 4, &nrec);
  if (nrec == 0)
    return CET_not_found;

  ind = (const struct compact_eh_index *)(hdr + 8);

  lo = 0;
  hi = nrec - 1;
  while (1)
    {
      mid = (lo + hi) / 2;
      p = decode_index_ptr (&ind[mid].fn);
      if ((_Unwind_Ptr)pc < p)
	{
	  if (mid == 0)
	    return CET_not_found;
	  hi = mid - 1;
	}
      else
	{
	  if (mid == hi)
	    break;
	  p = decode_index_ptr (&ind[mid + 1].fn);
	  if ((_Unwind_Ptr)pc < p)
	    break;
	  lo = mid + 1;
	}
    }

  p = decode_index_ptr (&ind[mid].fn);
  bases->func = (void *)p;
  if ((ind[mid].fn & 1) == 0)
    {
      bases->entry = &ind[mid].data;
      /* If we hit the terminating CANTUNWIND entry then assume
         we're looking in the wrong table.  */
      if (mid == (int)nrec - 1 && ind[mid].data == 0x015d5d01)
	return CET_not_found;

      return CET_inline;
    }
  else
    {
      p = decode_index_ptr (&ind[mid].data);
      bases->entry = (const void *)p;
      if (ind[mid].data & 1)
	return CET_FDE;
      else
	return CET_outline;
    }
}