Пример #1
0
void
get16s(u16int *p, int n)
{
	while(n--)
		*p++ = get16();
}
Пример #2
0
void
loadstate(char *file)
{
	bp = Bopen(file, OREAD);
	if(bp == nil){
		message("open: %r");
		return;
	}
	Bread(bp, reg, sizeof(reg));
	Bread(bp, mem, sizeof(mem));
	Bread(bp, vram, sizeof(vram));
	Bread(bp, oam, sizeof(oam));
	Bread(bp, spcmem, sizeof(spcmem));
	Bread(bp, dsp, sizeof(dsp));
	get16s(cgram, nelem(cgram));
	ppuclock = get32();
	spcclock = get32();
	dspclock = get32();
	stimerclock = get32();
	rA = get16();
	rX = get16();
	rY = get16();
	rS = get16();
	rP = get8();
	rD = get16();
	rDB = get8()<<16;
	pc = get16();
	rPB = get8()<<16;
	emu = get8();
	irq = get8();
	nmi = get8();
	dma = get8();
	hdma = get32();
	wai = get8();
	mdr = get8();
	mdr1 = get8();
	mdr2 = get8();
	oamaddr = get16();
	vramlatch = get16();
	keylatch = get32();
	ppux = get16();
	ppuy = get16();
	htime = reg[0x4207] | reg[0x4208] << 8 & 0x100;
	vtime = reg[0x4209] | reg[0x420a] << 8 & 0x100;
	subcolor = get16();
	get16s(hofs, nelem(hofs));
	get16s(vofs, nelem(vofs));
	get16s((u16int*) m7, nelem(m7));
	sA = get8();
	sX = get8();
	sY = get8();
	sS = get8();
	sP = get8();
	dspstate = get8();
	dspcounter = get16();
	noise = get16();
	Bread(bp, spctimer, sizeof(spctimer));
	dspload();
	Bterm(bp);
}
Пример #3
0
static int
update_stats (KEYBOXBLOB blob, struct file_stats_s *s)
{
  const unsigned char *buffer;
  size_t length;
  int type;
  unsigned long n;

  buffer = _keybox_get_blob_image (blob, &length);
  if (length < 32)
    {
      s->too_short_blobs++;
      return -1;
    }

  n = get32( buffer );
  if (n > length)
    s->too_large_blobs++;
  else
    length = n;  /* ignore the rest */

  s->total_blob_count++;
  type = buffer[4];
  switch (type)
    {
    case BLOBTYPE_EMPTY:
      s->empty_blob_count++;
      return 0;
    case BLOBTYPE_HEADER:
      s->header_blob_count++;
      return 0;
    case BLOBTYPE_PGP:
      s->pgp_blob_count++;
      break;
    case BLOBTYPE_X509:
      s->x509_blob_count++;
      break;
    default:
      s->unknown_blob_count++;
      return 0;
    }

  if (length < 40)
    {
      s->too_short_blobs++;
      return -1;
    }

  n = get16 (buffer + 6);
  if (n)
    {
      if ((n & 1))
        s->secret_flagged++;
      if ((n & 2))
        s->ephemeral_flagged++;
    }
  else
    s->non_flagged++;

  return 0;
}
Пример #4
0
int
loadstl(FILE *fp, char *comment, float **vertp, vertex_t *nvertp, vertex_t **trip, uint16_t **attrp, triangle_t *ntrip)
{
	uint8_t buf[128];
	triangle_t i, ti;
	vertex_t *tris;
	triangle_t ntris;
	vertex_t *vht, vi, nverts, vhtcap;
	uint32_t *verts;
	uint16_t *attrs;

	// the comment and triangle count
	if(fread(buf, 84, 1, fp) != 1){
		fprintf(stderr, "loadstl: short read at header\n");
		return -1;
	}

	if(comment != NULL)
		memcpy(comment, buf, 80);

	ntris = get32(buf+80);

	tris = malloc(ntris * 3*sizeof tris[0]);
	attrs = malloc(ntris * sizeof attrs[0]);
	verts = malloc(3*ntris * 3*sizeof verts[0]);

	vhtcap = nextpow2(4*ntris);
	vht = malloc(vhtcap * sizeof vht[0]);
	memset(vht, 0, vhtcap * sizeof vht[0]);

	fprintf(stderr, "loadstl: number of triangles: %u, vhtcap %d\n", ntris, vhtcap);

	nverts = 0;
	for(i = 0; i < ntris; i++){
		if(fread(buf, 50, 1, fp) != 1){
			fprintf(stderr, "loadstl: short read at triangle %d/%d\n", i, ntris);
			goto exit_fail;
		}
		// there's a normal vector at buf[0..11] which we are ignoring
		for(ti = 0; ti < 3; ti++){
			uint32_t vert[3];
			vert[0] = get32(buf+12 + 4*3*ti);
			vert[1] = get32(buf+12 + 4*3*ti+4);
			vert[2] = get32(buf+12 + 4*3*ti+8);
			vi = vertex(verts, nverts, vht, vhtcap, vert);
			if(vi == ~(uint32_t)0){
				fprintf(stderr, "loadstl: vertex hash full at triangle %d/%d\n", i, ntris);
				goto exit_fail;
			}
			if(vi == nverts){
				copy96(verts + 3*nverts, vert);
				nverts++;
			} else {
			}
			tris[3*i+ti] = vi;
		}
		attrs[i] = get16(buf + 48);
	}

	fprintf(stderr, "loadstl: number of verts: %u\n", nverts);
	free(vht);
	verts = realloc(verts, nverts * 3*sizeof verts[0]);
	*vertp = (float *)verts;
	*nvertp = nverts;
	*trip = tris;
	*attrp = attrs;
	*ntrip = ntris;
	return 0;

exit_fail:
	free(vht);
	free(verts);
	free(tris);
	free(attrs);
	return -1;
}
Пример #5
0
/* Dump one block to FP */
int
_keybox_dump_blob (KEYBOXBLOB blob, FILE *fp)
{
  const byte *buffer;
  size_t length;
  int type;
  ulong n, nkeys, keyinfolen;
  ulong nuids, uidinfolen;
  ulong nsigs, siginfolen;
  ulong rawdata_off, rawdata_len;
  ulong nserial;
  const byte *p;

  buffer = _keybox_get_blob_image (blob, &length);

  if (length < 32)
    {
      fprintf (fp, "[blob too short]\n");
      return -1;
    }

  n = get32( buffer );
  if (n > length)
    fprintf (fp, "[blob larger than length - output truncated]\n");
  else
    length = n;  /* ignore the rest */

  fprintf (fp, "Length: %lu\n", n );
  type = buffer[4];
  switch (type)
    {
    case BLOBTYPE_EMPTY:
      fprintf (fp, "Type:   Empty\n");
      return 0;

    case BLOBTYPE_HEADER:
      fprintf (fp, "Type:   Header\n");
      return dump_header_blob (buffer, length, fp);
    case BLOBTYPE_PGP:
      fprintf (fp, "Type:   OpenPGP\n");
      break;
    case BLOBTYPE_X509:
      fprintf (fp, "Type:   X.509\n");
      break;
    default:
      fprintf (fp, "Type:   %d\n", type);
      fprintf (fp, "[can't dump this blob type]\n");
      return 0;
    }
  fprintf (fp, "Version: %d\n", buffer[5]);

  if (length < 40)
    {
      fprintf (fp, "[blob too short]\n");
      return -1;
    }

  n = get16 (buffer + 6);
  fprintf( fp, "Blob-Flags: %04lX", n);
  if (n)
    {
      int any = 0;

      fputs (" (", fp);
      if ((n & 1))
        {
          fputs ("secret", fp);
          any++;
        }
      if ((n & 2))
        {
          if (any)
            putc (',', fp);
          fputs ("ephemeral", fp);
          any++;
        }
      putc (')', fp);
    }
  putc ('\n', fp);

  rawdata_off = get32 (buffer + 8);
  rawdata_len = get32 (buffer + 12);

  fprintf( fp, "Data-Offset: %lu\n", rawdata_off );
  fprintf( fp, "Data-Length: %lu\n", rawdata_len );
  if (rawdata_off > length || rawdata_len > length
      || rawdata_off+rawdata_off > length)
    fprintf (fp, "[Error: raw data larger than blob]\n");

  nkeys = get16 (buffer + 16);
  fprintf (fp, "Key-Count: %lu\n", nkeys );
  if (!nkeys)
    fprintf (fp, "[Error: no keys]\n");
  if (nkeys > 1 && type == BLOBTYPE_X509)
    fprintf (fp, "[Error: only one key allowed for X509]\n");

  keyinfolen = get16 (buffer + 18 );
  fprintf (fp, "Key-Info-Length: %lu\n", keyinfolen);
  /* fixme: check bounds */
  p = buffer + 20;
  for (n=0; n < nkeys; n++, p += keyinfolen)
    {
      int i;
      ulong kidoff, kflags;

      fprintf (fp, "Key-Fpr[%lu]: ", n );
      for (i=0; i < 20; i++ )
        fprintf (fp, "%02X", p[i]);
      kidoff = get32 (p + 20);
      fprintf (fp, "\nKey-Kid-Off[%lu]: %lu\n", n, kidoff );
      fprintf (fp, "Key-Kid[%lu]: ", n );
      /* fixme: check bounds */
      for (i=0; i < 8; i++ )
        fprintf (fp, "%02X", buffer[kidoff+i] );
      kflags = get16 (p + 24 );
      fprintf( fp, "\nKey-Flags[%lu]: %04lX\n", n, kflags);
    }

  /* serial number */
  fputs ("Serial-No: ", fp);
  nserial = get16 (p);
  p += 2;
  if (!nserial)
    fputs ("none", fp);
  else
    {
      for (; nserial; nserial--, p++)
        fprintf (fp, "%02X", *p);
    }
  putc ('\n', fp);

  /* user IDs */
  nuids = get16 (p);
  fprintf (fp, "Uid-Count: %lu\n", nuids );
  uidinfolen = get16  (p + 2);
  fprintf (fp, "Uid-Info-Length: %lu\n", uidinfolen);
  /* fixme: check bounds */
  p += 4;
  for (n=0; n < nuids; n++, p += uidinfolen)
    {
      ulong uidoff, uidlen, uflags;

      uidoff = get32( p );
      uidlen = get32( p+4 );
      if (type == BLOBTYPE_X509 && !n)
        {
          fprintf (fp, "Issuer-Off: %lu\n", uidoff );
          fprintf (fp, "Issuer-Len: %lu\n", uidlen );
          fprintf (fp, "Issuer: \"");
        }
      else if (type == BLOBTYPE_X509 && n == 1)
        {
          fprintf (fp, "Subject-Off: %lu\n", uidoff );
          fprintf (fp, "Subject-Len: %lu\n", uidlen );
          fprintf (fp, "Subject: \"");
        }
      else
        {
          fprintf (fp, "Uid-Off[%lu]: %lu\n", n, uidoff );
          fprintf (fp, "Uid-Len[%lu]: %lu\n", n, uidlen );
          fprintf (fp, "Uid[%lu]: \"", n );
        }
      print_string (fp, buffer+uidoff, uidlen, '\"');
      fputs ("\"\n", fp);
      uflags = get16 (p + 8);
      if (type == BLOBTYPE_X509 && !n)
        {
          fprintf (fp, "Issuer-Flags: %04lX\n", uflags );
          fprintf (fp, "Issuer-Validity: %d\n", p[10] );
        }
      else if (type == BLOBTYPE_X509 && n == 1)
        {
          fprintf (fp, "Subject-Flags: %04lX\n", uflags );
          fprintf (fp, "Subject-Validity: %d\n", p[10] );
        }
      else
        {
          fprintf (fp, "Uid-Flags[%lu]: %04lX\n", n, uflags );
          fprintf (fp, "Uid-Validity[%lu]: %d\n", n, p[10] );
        }
    }

  nsigs = get16 (p);
  fprintf (fp, "Sig-Count: %lu\n", nsigs );
  siginfolen = get16 (p + 2);
  fprintf (fp, "Sig-Info-Length: %lu\n", siginfolen );
  /* fixme: check bounds  */
  p += 4;
  for (n=0; n < nsigs; n++, p += siginfolen)
    {
      ulong sflags;

      sflags = get32 (p);
      fprintf (fp, "Sig-Expire[%lu]: ", n );
      if (!sflags)
        fputs ("[not checked]", fp);
      else if (sflags == 1 )
        fputs ("[missing key]", fp);
      else if (sflags == 2 )
        fputs ("[bad signature]", fp);
      else if (sflags < 0x10000000)
        fprintf (fp, "[bad flag %0lx]", sflags);
      else if (sflags == 0xffffffff)
        fputs ("0", fp );
      else
        fputs ("a time"/*strtimestamp( sflags )*/, fp );
      putc ('\n', fp );
    }

  fprintf (fp, "Ownertrust: %d\n", p[0] );
  fprintf (fp, "All-Validity: %d\n", p[1] );
  p += 4;
  n = get32 (p); p += 4;
  fprintf (fp, "Recheck-After: %lu\n", n );
  n = get32 (p ); p += 4;
  fprintf( fp, "Latest-Timestamp: %lu\n", n );
  n = get32 (p ); p += 4;
  fprintf (fp, "Created-At: %lu\n", n );
  n = get32 (p ); p += 4;
  fprintf (fp, "Reserved-Space: %lu\n", n );

  /* check that the keyblock is at the correct offset and other bounds */
  /*fprintf (fp, "Blob-Checksum: [MD5-hash]\n");*/
  return 0;
}
Пример #6
0
/* Pull TCP header off mbuf */
int
ntohtcp(
struct tcp *tcph,
struct mbuf **bpp
){
	int hdrlen,i,optlen,kind;
	register int flags;
	uint8 hdrbuf[TCPLEN],*cp;
	uint8 options[TCP_MAXOPT];

	memset(tcph,0,sizeof(struct tcp));
	i = pullup(bpp,hdrbuf,TCPLEN);
	/* Note that the results will be garbage if the header is too short.
	 * We don't check for this because returned ICMP messages will be
	 * truncated, and we at least want to get the port numbers.
	 */
	tcph->source = get16(&hdrbuf[0]);
	tcph->dest = get16(&hdrbuf[2]);
	tcph->seq = get32(&hdrbuf[4]);
	tcph->ack = get32(&hdrbuf[8]);
	hdrlen = (hdrbuf[12] & 0xf0) >> 2;
	flags = hdrbuf[13];
	tcph->flags.congest = (flags & 64) ? 1 : 0;
	tcph->flags.urg = (flags & 32) ? 1 : 0;
	tcph->flags.ack = (flags & 16) ? 1 : 0;
	tcph->flags.psh = (flags & 8) ? 1 : 0;
	tcph->flags.rst = (flags & 4) ? 1 : 0;
	tcph->flags.syn = (flags & 2) ? 1 : 0;
	tcph->flags.fin = (flags & 1) ? 1 : 0;
	tcph->wnd = get16(&hdrbuf[14]);
	tcph->checksum = get16(&hdrbuf[16]);
	tcph->up = get16(&hdrbuf[18]);
	optlen = hdrlen - TCPLEN;

	/* Check for option field */
	if(i < TCPLEN || hdrlen < TCPLEN)
		return -1;	/* Header smaller than legal minimum */
	if(optlen == 0)
		return (int)hdrlen;	/* No options, all done */

	if(optlen > len_p(*bpp)){
		/* Remainder too short for options length specified */
		return -1;
	}
	pullup(bpp,options,optlen);	/* "Can't fail" */
	/* Process options */
	for(cp=options,i=optlen; i > 0;){
		kind = *cp++;
		i--;
		/* Process single-byte options */
		switch(kind){
		case EOL_KIND:
			return (int)hdrlen;	/* End of options list */
		case NOOP_KIND:
			continue;	/* Go look for next option */
		}
		/* All other options have a length field */
		optlen = *cp++;

		/* Process valid multi-byte options */
		switch(kind){
		case MSS_KIND:
			if(optlen == MSS_LENGTH){
				tcph->mss = get16(cp);
				tcph->flags.mss = 1;
			}
			break;
		case WSCALE_KIND:
			if(optlen == WSCALE_LENGTH){
				tcph->wsopt = *cp;
				tcph->flags.wscale = 1;
			}
			break;
		case TSTAMP_KIND:
			if(optlen == TSTAMP_LENGTH){
				tcph->tsval = get32(cp);
				tcph->tsecr = get32(cp+4);
				tcph->flags.tstamp = 1;
			}
			break;
		}
		optlen = max(2,optlen);	/* Enforce legal minimum */
		i -= optlen;
		cp += optlen - 2;
	}
	return (int)hdrlen;
}
Пример #7
0
static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type;
    char *name, *provider_name;

#ifdef DEBUG
    dprintf(ts->stream, "SDT:\n");
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif

    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;
    if (h->tid != SDT_TID)
        return;
    onid = get16(&p, p_end);
    if (onid < 0)
        return;
    val = get8(&p, p_end);
    if (val < 0)
        return;
    for(;;) {
        sid = get16(&p, p_end);
        if (sid < 0)
            break;
        val = get8(&p, p_end);
        if (val < 0)
            break;
        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            desc_len = get8(&p, desc_list_end);
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;

            dprintf(ts->stream, "tag: 0x%02x len=%d\n",
                   desc_tag, desc_len);

            switch(desc_tag) {
            case 0x48:
                service_type = get8(&p, p_end);
                if (service_type < 0)
                    break;
                provider_name = getstr8(&p, p_end);
                if (!provider_name)
                    break;
                name = getstr8(&p, p_end);
                if (name) {
                    AVProgram *program = av_new_program(ts->stream, sid);
                    if(program) {
                        av_metadata_set(&program->metadata, "name", name);
                        av_metadata_set(&program->metadata, "provider_name", provider_name);
                    }
                }
                av_free(name);
                av_free(provider_name);
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;
    }
}
Пример #8
0
static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len)
{
    MpegTSContext *ts = filter->u.section_filter.opaque;
    SectionHeader h1, *h = &h1;
    PESContext *pes;
    AVStream *st;
    const uint8_t *p, *p_end, *desc_list_end, *desc_end;
    int program_info_length, pcr_pid, pid, stream_type;
    int desc_list_len, desc_len, desc_tag;
    int comp_page, anc_page;
    char language[4];
    uint32_t prog_reg_desc = 0; /* registration descriptor */

#ifdef DEBUG
    dprintf(ts->stream, "PMT: len %i\n", section_len);
    av_hex_dump_log(ts->stream, AV_LOG_DEBUG, (uint8_t *)section, section_len);
#endif

    p_end = section + section_len - 4;
    p = section;
    if (parse_section_header(h, &p, p_end) < 0)
        return;

    dprintf(ts->stream, "sid=0x%x sec_num=%d/%d\n",
           h->id, h->sec_num, h->last_sec_num);

    if (h->tid != PMT_TID)
        return;

    clear_program(ts, h->id);
    pcr_pid = get16(&p, p_end) & 0x1fff;
    if (pcr_pid < 0)
        return;
    add_pid_to_pmt(ts, h->id, pcr_pid);

    dprintf(ts->stream, "pcr_pid=0x%x\n", pcr_pid);

    program_info_length = get16(&p, p_end) & 0xfff;
    if (program_info_length < 0)
        return;
    while(program_info_length >= 2) {
        uint8_t tag, len;
        tag = get8(&p, p_end);
        len = get8(&p, p_end);
        if(len > program_info_length - 2)
            //something else is broken, exit the program_descriptors_loop
            break;
        program_info_length -= len + 2;
        if(tag == 0x05 && len >= 4) { // registration descriptor
            prog_reg_desc = bytestream_get_le32(&p);
            len -= 4;
        }
        p += len;
    }
    p += program_info_length;
    if (p >= p_end)
        return;

    // stop parsing after pmt, we found header
    if (!ts->stream->nb_streams)
        ts->stop_parse = 1;

    for(;;) {
        st = 0;
        stream_type = get8(&p, p_end);
        if (stream_type < 0)
            break;
        pid = get16(&p, p_end) & 0x1fff;
        if (pid < 0)
            break;

        /* now create ffmpeg stream */
        if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) {
            pes = ts->pids[pid]->u.pes_filter.opaque;
            st = pes->st;
        } else {
            if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably
            pes = add_pes_stream(ts, pid, pcr_pid, stream_type);
            if (pes)
                st = new_pes_av_stream(pes, prog_reg_desc, 0);
        }

        if (!st)
            return;

        add_pid_to_pmt(ts, h->id, pid);

        av_program_add_stream_index(ts->stream, h->id, st->index);

        desc_list_len = get16(&p, p_end) & 0xfff;
        if (desc_list_len < 0)
            break;
        desc_list_end = p + desc_list_len;
        if (desc_list_end > p_end)
            break;
        for(;;) {
            desc_tag = get8(&p, desc_list_end);
            if (desc_tag < 0)
                break;
            desc_len = get8(&p, desc_list_end);
            if (desc_len < 0)
                break;
            desc_end = p + desc_len;
            if (desc_end > desc_list_end)
                break;

            dprintf(ts->stream, "tag: 0x%02x len=%d\n",
                   desc_tag, desc_len);

            if (st->codec->codec_id == CODEC_ID_NONE &&
                stream_type == STREAM_TYPE_PRIVATE_DATA)
                mpegts_find_stream_type(st, desc_tag, DESC_types);

            switch(desc_tag) {
            case 0x59: /* subtitling descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                get8(&p, desc_end);
                comp_page = get16(&p, desc_end);
                anc_page = get16(&p, desc_end);
                st->codec->sub_id = (anc_page << 16) | comp_page;
                av_metadata_set(&st->metadata, "language", language);
                break;
            case 0x0a: /* ISO 639 language descriptor */
                language[0] = get8(&p, desc_end);
                language[1] = get8(&p, desc_end);
                language[2] = get8(&p, desc_end);
                language[3] = 0;
                av_metadata_set(&st->metadata, "language", language);
                break;
            case 0x05: /* registration descriptor */
                st->codec->codec_tag = bytestream_get_le32(&p);
                dprintf(ts->stream, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag);
                if (st->codec->codec_id == CODEC_ID_NONE &&
                    stream_type == STREAM_TYPE_PRIVATE_DATA)
                    mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types);
                break;
            default:
                break;
            }
            p = desc_end;
        }
        p = desc_list_end;
    }
    /* all parameters are there */
    mpegts_close_filter(ts, filter);
}
Пример #9
0
LocalAddressSpace::pint_t
LocalAddressSpace::getEncodedP(pint_t& addr, pint_t end, uint8_t encoding)
{
	pint_t startAddr = addr;
	const uint8_t* p = (uint8_t*)addr;
	pint_t result;
	
	// first get value
	switch (encoding & 0x0F) {
		case DW_EH_PE_ptr:
			result = getP(addr);
			p += sizeof(pint_t);
			addr = (pint_t)p;
			break;
		case DW_EH_PE_uleb128:
			result = getULEB128(addr, end);
			break;
		case DW_EH_PE_udata2:
			result = get16(addr);
			p += 2;
			addr = (pint_t)p;
			break;
		case DW_EH_PE_udata4:
			result = get32(addr);
			p += 4;
			addr = (pint_t)p;
			break;
		case DW_EH_PE_udata8:
			result = get64(addr);
			p += 8;
			addr = (pint_t)p;
			break;
		case DW_EH_PE_sleb128:
			result = getSLEB128(addr, end);
			break;
		case DW_EH_PE_sdata2:
			result = (int16_t)get16(addr);
			p += 2;
			addr = (pint_t)p;
			break;
		case DW_EH_PE_sdata4:
			result = (int32_t)get32(addr);
			p += 4;
			addr = (pint_t)p;
			break;
		case DW_EH_PE_sdata8:
			result = get64(addr);
			p += 8;
			addr = (pint_t)p;
			break;
		default:
			ABORT("unknown pointer encoding");
	}
	
	// then add relative offset
	switch ( encoding & 0x70 ) {
		case DW_EH_PE_absptr:
			// do nothing
			break;
		case DW_EH_PE_pcrel:
			result += startAddr;
			break;
		case DW_EH_PE_textrel:
			ABORT("DW_EH_PE_textrel pointer encoding not supported");
			break;
		case DW_EH_PE_datarel:
			ABORT("DW_EH_PE_datarel pointer encoding not supported");
			break;
		case DW_EH_PE_funcrel:
			ABORT("DW_EH_PE_funcrel pointer encoding not supported");
			break;
		case DW_EH_PE_aligned:
			ABORT("DW_EH_PE_aligned pointer encoding not supported");
			break;
		default:
			ABORT("unknown pointer encoding");
			break;
	}
	
	if ( encoding & DW_EH_PE_indirect )
		result = getP(result);
	
	return result;
}