Exemplo n.º 1
0
  pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
                     const unw_proc_info_t *ctx) {
    pint_t startAddr = addr;
    const uint8_t *p = (uint8_t *)addr;
    pint_t result;

    if (encoding == DW_EH_PE_omit)
      return 0;
    if (encoding == DW_EH_PE_aligned) {
      addr = (addr + sizeof(pint_t) - 1) & sizeof(pint_t);
      return getP(addr);
    }

    // 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;
    case DW_EH_PE_omit:
      result = 0;
      break;
    default:
      assert(0 && "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:
      assert(0 && "DW_EH_PE_textrel pointer encoding not supported");
      break;
    case DW_EH_PE_datarel:
      assert(ctx != NULL && "DW_EH_PE_datarel without context");
      if (ctx)
        result += ctx->data_base;
      break;
    case DW_EH_PE_funcrel:
      assert(ctx != NULL && "DW_EH_PE_funcrel without context");
      if (ctx)
        result += ctx->start_ip;
      break;
    case DW_EH_PE_aligned:
      __builtin_unreachable();
    default:
      assert(0 && "unknown pointer encoding");
      break;
    }

    if (encoding & DW_EH_PE_indirect)
      result = getP(result);

    return result;
  }
Exemplo n.º 2
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;
}