Beispiel #1
0
static int parse_vmstructs(jvm_agent_t* J) {
  VMStructEntry  vmVar;
  VMStructEntry* vmp = &vmVar;
  uint64_t gHotSpotVMStructs;
  psaddr_t sym_addr;
  uint64_t base;
  int err;

  /* Clear *vmp now in case we jump to fail: */
  memset(vmp, 0, sizeof(VMStructEntry));

  err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
  CHECK_FAIL(err);
  err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
  CHECK_FAIL(err);
  base = gHotSpotVMStructs;

  err = PS_OK;
  while (err == PS_OK) {
    memset(vmp, 0, sizeof(VMStructEntry));
    err = parse_vmstruct_entry(J, base, vmp);
    if (err != PS_OK || vmp->typeName == NULL) {
      break;
    }

    if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
      /* Read _heaps field of type GrowableArray<CodeHeaps*>*      */
      if (strcmp("_heaps", vmp->fieldName) == 0) {
        err = read_pointer(J, vmp->address, &J->CodeCache_heaps_address);
      }
    } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
      if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
        J->Universe_narrow_oop_base_address = vmp->address;
      }
      if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
        J->Universe_narrow_oop_shift_address = vmp->address;
      }
    }
    CHECK_FAIL(err);

    base += SIZE_VMStructEntry;
    if (vmp->typeName != NULL) free((void*)vmp->typeName);
    if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
  }

  return PS_OK;

 fail:
  if (vmp->typeName != NULL) free((void*)vmp->typeName);
  if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
  return -1;
}
Beispiel #2
0
static int is_method(jvm_agent_t* J, uint64_t methodPtr) {
  uint64_t klass;
  int err = read_pointer(J, methodPtr, &klass);
  if (err != PS_OK) goto fail;
  return klass == J->Method_vtbl;

 fail:
  return 0;
}
Beispiel #3
0
/* t = m_pos0 + (now - m_t0) * m_Tf
 */
int64_t TimeInterpolator::get_stream_usecs()
{
    int64_t now;
    double dt;
    int64_t t_media;

    m_mutex.lock();
    now = get_system_usecs();

    if (m_state == PAUSED) {
        t_media = m_pos0;
        goto end;
    }

    dt = m_Tf * double(now - m_t0);
    if (dt < 0.0) dt = 0.0;
    t_media = m_pos0 + int64_t(dt);
    if (t_media < m_last) {
        ALOGW("time is rewinding: %lld Tf=%g t0=%lld pos0=%lld dt=%g "
             "now=%lld last=%lld now_last=%lld",
             t_media - m_last, m_Tf, m_t0, m_pos0, dt,
             now, m_last, m_now_last);
    }
    if (t_media >= read_pointer()) {
        if (m_state == ROLLING) {
            t_media = read_pointer();
            ALOGE("UNDERRUN in %s", __func__);
            err_underrun();
        }
    }

    m_last = t_media;
    m_now_last = now;

end:
    /* t_media += m_latency; */
    m_mutex.unlock();
    ALOGV("%s == %lld (t0=%lld, pos0=%lld, Tf=%g, read=%lld, queued=%lld "
         "latency=%lld now=%lld, ",
         __func__, t_media, m_t0, m_pos0, m_Tf, m_read, m_queued,
         m_latency, now);
    return t_media;
}
Beispiel #4
0
static void read_field(FILE *f, const save_field_t *field, void *base)
{
    void *p = (byte *)base + field->ofs;
    int i;

    switch (field->type) {
    case F_BYTE:
        read_data(p, field->size, f);
        break;
    case F_SHORT:
        for (i = 0; i < field->size; i++) {
            ((short *)p)[i] = read_short(f);
        }
        break;
    case F_INT:
        for (i = 0; i < field->size; i++) {
            ((int *)p)[i] = read_int(f);
        }
        break;
    case F_FLOAT:
        for (i = 0; i < field->size; i++) {
            ((float *)p)[i] = read_float(f);
        }
        break;
    case F_VECTOR:
        read_vector(f, (vec_t *)p);
        break;

    case F_LSTRING:
        *(char **)p = read_string(f);
        break;
    case F_ZSTRING:
        read_zstring(f, (char *)p, field->size);
        break;

    case F_EDICT:
        *(edict_t **)p = read_index(f, sizeof(edict_t), g_edicts, game.maxentities - 1);
        break;
    case F_CLIENT:
        *(gclient_t **)p = read_index(f, sizeof(gclient_t), game.clients, game.maxclients - 1);
        break;
    case F_ITEM:
        *(gitem_t **)p = read_index(f, sizeof(gitem_t), itemlist, game.num_items - 1);
        break;

    case F_POINTER:
        *(void **)p = read_pointer(f, field->size);
        break;

    default:
        gi.error("%s: unknown field type", __func__);
    }
}
Beispiel #5
0
static int read_volatiles(jvm_agent_t* J) {
  uint64_t ptr;
  int err;

  err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
  if (err == PS_OK) {
    err = ps_pread(J->P,  J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
    CHECK_FAIL(err);
  } else {
    J->Use_Compressed_Oops = 0;
  }

  err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
  CHECK_FAIL(err);
  err = ps_pread(J->P,  J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
  CHECK_FAIL(err);

  err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
                     OFFSET_VirtualSpace_low, &J->CodeCache_low);
  CHECK_FAIL(err);
  err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
                     OFFSET_VirtualSpace_high, &J->CodeCache_high);
  CHECK_FAIL(err);
  err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
                     OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low);
  CHECK_FAIL(err);
  err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
                     OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high);
  CHECK_FAIL(err);

  err = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size,
                 &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
  CHECK_FAIL(err);

  return PS_OK;

 fail:
  return err;
}
static signed fde_pointer_type(const u32 *cie)
{
	const u8 *ptr = (const u8 *)(cie + 2);
	unsigned version = *ptr;

	if (version != 1)
		return -1; /* unsupported */
	if (*++ptr) {
		const char *aug;
		const u8 *end = (const u8 *)(cie + 1) + *cie;
		uleb128_t len;

		/* check if augmentation size is first (and thus present) */
		if (*ptr != 'z')
			return -1;
		/* check if augmentation string is nul-terminated */
		if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL)
			return -1;
		++ptr; /* skip terminator */
		get_uleb128(&ptr, end); /* skip code alignment */
		get_sleb128(&ptr, end); /* skip data alignment */
		/* skip return address column */
		version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end);
		len = get_uleb128(&ptr, end); /* augmentation length */
		if (ptr + len < ptr || ptr + len > end)
			return -1;
		end = ptr + len;
		while (*++aug) {
			if (ptr >= end)
				return -1;
			switch(*aug) {
			case 'L':
				++ptr;
				break;
			case 'P': {
					signed ptrType = *ptr++;

					if (!read_pointer(&ptr, end, ptrType) || 					     ptr > end)
						return -1;
				}
				break;
			case 'R':
				return *ptr;
			default:
				return -1;
			}
		}
	}
	return DW_EH_PE_native|DW_EH_PE_abs;
}
Beispiel #7
0
void mr_push_kp_range(char* buf, int pos, int bound, int end, couchfile_modify_result *dst)
{
    DBG("Moving items %d - %d into result.\r\n", bound, end);
    int current = 0;
    ei_decode_list_header(buf, &pos, NULL);
    while(current < end)
    {
        if(current >= bound)
        {
            DBG("   .... %d\r\n", current);
            mr_push_pointerinfo(read_pointer(buf,pos), dst);
        }
        ei_skip_term(buf, &pos);
        current++;
    }
}
Beispiel #8
0
static int read_string_pointer(jvm_agent_t* J, uint64_t base, const char ** stringp) {
  uint64_t ptr;
  int err;
  char buffer[1024];

  *stringp = NULL;
  err = read_pointer(J, base, &ptr);
  CHECK_FAIL(err);
  if (ptr != 0) {
    err = read_string(J->P, buffer, sizeof(buffer), ptr);
    CHECK_FAIL(err);
    *stringp = strdup(buffer);
  }
  return PS_OK;

 fail:
  return err;
}
Beispiel #9
0
static int parse_vmstruct_entry(jvm_agent_t* J, uint64_t base, VMStructEntry* vmp) {
  uint64_t ptr;
  int err;

  err = read_string_pointer(J, base + OFFSET_VMStructEntrytypeName, &vmp->typeName);
  CHECK_FAIL(err);
  err = read_string_pointer(J, base + OFFSET_VMStructEntryfieldName, &vmp->fieldName);
  CHECK_FAIL(err);
  err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address);
  CHECK_FAIL(err);

  return PS_OK;

 fail:
  if (vmp->typeName != NULL) free((void*)vmp->typeName);
  if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
  return err;
}
Beispiel #10
0
char *str_ulong_vec(struct supersect *ss, const unsigned long *const *datap,
		    const unsigned long *sizep)
{
	struct supersect *data_ss;
	const unsigned long *data =
	    read_pointer(ss, (void *const *)datap, &data_ss);
	unsigned long size = read_num(ss, sizep);

	char *buf = NULL;
	size_t bufsize = 0;
	FILE *fp = open_memstream(&buf, &bufsize);
	fprintf(fp, "[ ");
	size_t i;
	for (i = 0; i < size; ++i)
		fprintf(fp, "%lx ", read_num(data_ss, &data[i]));
	fprintf(fp, "]");
	fclose(fp);
	return buf;
}
Beispiel #11
0
const char *str_ksplice_patch_type(struct supersect *ss,
				   const struct ksplice_patch *kpatch)
{
	const char *const *strp;
	struct supersect *data_ss;
	switch(kpatch->type) {
	case KSPLICE_PATCH_TEXT:
		return strprintf("text\n  repladdr: %s", str_pointer
				 (ss, (void *const *)&kpatch->repladdr));
	case KSPLICE_PATCH_DATA:
		return strprintf("data\n  size: %x", kpatch->size);
	case KSPLICE_PATCH_EXPORT:
		strp = read_pointer(ss, &kpatch->contents, &data_ss);
		return strprintf("export\n  newname: %s",
				 read_string(data_ss, strp));
	default:
		return "unknown";
	}
}
Beispiel #12
0
static void *
extract_cie_info (fde *f, struct cie_info *c)
{
  void *p;
  int i;

  c->augmentation = get_cie (f)->augmentation;

  if (strcmp (c->augmentation, "") != 0
      && strcmp (c->augmentation, "eh") != 0
      && c->augmentation[0] != 'z')
    return 0;

  p = c->augmentation + strlen (c->augmentation) + 1;

  if (strcmp (c->augmentation, "eh") == 0)
    {
      c->eh_ptr = read_pointer (p);
      p += sizeof (void *);
    }
  else
    c->eh_ptr = 0;

  p = decode_uleb128 (p, &c->code_align);
  p = decode_sleb128 (p, &c->data_align);
  c->ra_regno = *(unsigned char *)p++;

  /* If the augmentation starts with 'z', we now see the length of the
     augmentation fields.  */
  if (c->augmentation[0] == 'z')
    {
      p = decode_uleb128 (p, &i);
      p += i;
    }

  return p;
}
Beispiel #13
0
void show_ksplice_reloc(struct supersect *ss,
			const struct ksplice_reloc *kreloc)
{
	struct supersect *khowto_ss;
	const struct ksplice_reloc_howto *khowto =
	    read_pointer(ss, (void *const *)&kreloc->howto, &khowto_ss);
	printf("  blank_addr: %s  size: %x\n"
	       "  type: %s\n"
	       "  symbol: %s\n"
	       "  insn_addend: %lx\n"
	       "  target_addend: %lx\n"
	       "  pcrel: %x  dst_mask: %lx  rightshift: %x  signed_addend: %x\n"
	       "\n",
	       str_pointer(ss, (void *const *)&kreloc->blank_addr),
	       read_num(khowto_ss, &khowto->size),
	       str_howto_type(khowto),
	       str_ksplice_symbolp(ss, &kreloc->symbol),
	       read_num(ss, &kreloc->insn_addend),
	       read_num(ss, &kreloc->target_addend),
	       read_num(khowto_ss, &khowto->pcrel),
	       read_num(khowto_ss, &khowto->dst_mask),
	       read_num(khowto_ss, &khowto->rightshift),
	       read_num(khowto_ss, &khowto->signed_addend));
}
Beispiel #14
0
static int read_volatiles(jvm_agent_t* J) {
  int i;
  uint64_t array_data;
  uint64_t code_heap_address;
  int err;

  err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
  if (err == PS_OK) {
    err = ps_pread(J->P,  J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
    CHECK_FAIL(err);
  } else {
    J->Use_Compressed_Oops = 0;
  }

  err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
  CHECK_FAIL(err);
  err = ps_pread(J->P,  J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
  CHECK_FAIL(err);

  /* CodeCache_heaps_address points to GrowableArray<CodeHeaps*>, read _data field
     pointing to the first entry of type CodeCache* in the array */
  err = read_pointer(J, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_data, &array_data);
  /* Read _len field containing the number of code heaps */
  err = ps_pread(J->P, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_len,
                 &J->Number_of_heaps, sizeof(J->Number_of_heaps));

  /* Allocate memory for heap configurations */
  J->Heap_low         = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
  J->Heap_high        = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
  J->Heap_segmap_low  = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
  J->Heap_segmap_high = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));

  /* Read code heap configurations */
  for (i = 0; i < J->Number_of_heaps; ++i) {
    /* Read address of heap */
    err = read_pointer(J, array_data, &code_heap_address);
    CHECK_FAIL(err);

    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
                       OFFSET_VirtualSpace_low, &J->Heap_low[i]);
    CHECK_FAIL(err);
    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
                       OFFSET_VirtualSpace_high, &J->Heap_high[i]);
    CHECK_FAIL(err);
    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
                       OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]);
    CHECK_FAIL(err);
    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
                       OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]);
    CHECK_FAIL(err);

    /* Increment pointer to next entry */
    array_data = array_data + POINTER_SIZE;
  }

  err = ps_pread(J->P, code_heap_address + OFFSET_CodeHeap_log2_segment_size,
                 &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
  CHECK_FAIL(err);

  return PS_OK;

 fail:
  return err;
}
Beispiel #15
0
static void _stp_filename_lookup(struct _stp_module *mod, char ** filename,
                                 uint8_t *dirsecp, uint8_t *enddirsecp,
                                 unsigned fileidx, int user, int compat_task)
{
  uint8_t *linep = dirsecp;
  static char fullpath [MAXSTRINGLEN];
  char *dirname_entry = NULL, *filename_entry = NULL;
  unsigned diridx = 0, i, j;

  // skip past the directory table in the debug_line info
  while (*linep != 0 && linep < enddirsecp)
    {
      char *entry = (char *) linep;
      uint8_t *endnamep = (uint8_t *) memchr (entry, '\0', (size_t) (enddirsecp-linep));
      if (endnamep == NULL || (endnamep + 1) > enddirsecp)
        return;
      linep = endnamep + 1;
    }

  if ((char) linep[0] != '\0')
    return;
  ++linep;

  // at the filename table
  for (i = 1; *linep != 0 && linep < enddirsecp; ++i)
    {
      uint8_t *endnamep = NULL;
      filename_entry = (char *) linep;
      endnamep = (uint8_t *) memchr (filename_entry, '\0', (size_t) (enddirsecp-linep));
      if (endnamep == NULL || (endnamep + 1) > enddirsecp)
        return;

      // move the line pointer past the file name. account for the null byte
      linep = endnamep + 1;

      // save the directory index
      diridx = read_pointer ((const uint8_t **) &linep, enddirsecp, DW_EH_PE_leb128, user, compat_task);

      if (linep > enddirsecp)
        return;
      if (i == fileidx)
        break;

      filename_entry = NULL;

      // modification time
      read_pointer ((const uint8_t **) &linep, enddirsecp, DW_EH_PE_leb128, user, compat_task);
      // length of a file
      read_pointer ((const uint8_t **) &linep, enddirsecp, DW_EH_PE_leb128, user, compat_task);
      // check that nothing went wrong with reading the ulebs
      if (linep > enddirsecp)
        return;
    }

  if (filename_entry == NULL)
    return; // return just the linenumber

  // if  dirid == 0, it's the compilation directory. otherwise retrieve the
  // directory path if the file path was relative
  if (diridx != 0 && filename_entry[0] != '/')
    {
      linep = dirsecp;
      for (j = 1; *linep != 0 && linep < enddirsecp; j++)
        {
          uint8_t *endnamep = NULL;
          dirname_entry = (char *) linep;
          endnamep = (uint8_t *) memchr (dirname_entry, '\0', (size_t) (enddirsecp-linep));
          if (endnamep == NULL || (endnamep + 1) > enddirsecp)
            return;

          if (j == diridx)
            break;

          dirname_entry = NULL;
          linep = endnamep + 1;
        }

      if (dirname_entry == NULL)
        return;
    }

  // bring it all together
  // the filename was the full path
  if (filename_entry[0] == '/')
    *filename = filename_entry;
  // relative filename, and the dir corresponds to the compilation dir
  else if (diridx == 0)
    {
      char *slash = strrchr (mod->path, '/');
      strlcpy(fullpath, mod->path, (size_t) (2 + slash - mod->path));
      strlcat(fullpath, filename_entry, MAXSTRINGLEN);
      *filename = fullpath;
    }
  // relative filename and a directory from the table in the debug line data
  else
    {
      strlcpy(fullpath, dirname_entry, MAXSTRINGLEN);
      strlcat(fullpath, "/", MAXSTRINGLEN);
      strlcat(fullpath, filename_entry, MAXSTRINGLEN);
      *filename = fullpath;
    }
}
Beispiel #16
0
unsigned long _stp_linenumber_lookup(unsigned long addr, struct task_struct *task, char ** filename, int need_filename)
{
  struct _stp_module *m;
  struct _stp_section *sec;
  const char *modname = NULL;
  uint8_t *linep, *enddatap;
  int compat_task = _stp_is_compat_task();
  int user = (task ? 1 : 0);

// the portion below is encased in this conditional because some of the functions
// and constants needed are encased in a similar condition
#ifdef STP_NEED_LINE_DATA
  if (addr == 0)
      return 0;

  if (task)
    {
	    unsigned long vm_start = 0;
	    unsigned long vm_end = 0;
#ifdef CONFIG_COMPAT
      /* Handle 32bit signed values in 64bit longs, chop off top bits. */
      if (test_tsk_thread_flag(task, TIF_32BIT))
        addr &= ((compat_ulong_t) ~0);
#endif
	    m = _stp_umod_lookup(addr, task, &modname, &vm_start, &vm_end);
    }
  else
    m = _stp_kmod_sec_lookup(addr, &sec);

  if (m == NULL || m->debug_line == NULL)
    return 0;

  // if addr is a kernel address, it will need to be adjusted
  if (!task)
    {
      int i;
      unsigned long offset = 0;
      // have to factor in the load_offset of (specifically) the .text section
      for (i=0; i<m->num_sections; i++)
        if (!strcmp(m->sections[i].name, ".text"))
          {
            offset = (m->sections[i].static_addr - m->sections[i].sec_load_offset);
            break;
          }

      if (addr < offset)
        return 0;
      addr = addr - offset;
    }


  linep = m->debug_line;
  enddatap = m->debug_line + m->debug_line_len;

  while (linep < enddatap)
    {
      // similar to print_debug_line_section() in elfutils
      unsigned int length = 4, curr_file_idx = 1, prev_file_idx = 1;
      unsigned int skip_to_seq_end = 0, op_index = 0;
      uint64_t unit_length, hdr_length, curr_addr = 0;
      uint8_t *endunitp, *endhdrp, *dirsecp, *stdopcode_lens_secp;
      uint16_t version;
      uint8_t opcode_base, line_range, min_instr_len = 0, max_ops = 1;
      unsigned long curr_linenum = 1;
      int8_t line_base;
      long cumm_line_adv = 0;

      unit_length = (uint64_t) read_pointer ((const uint8_t **) &linep, enddatap, DW_EH_PE_data4, user, compat_task);
      if (unit_length == 0xffffffff)
        {
          if (unlikely (linep + 8 > enddatap))
            return 0;
          unit_length = (uint64_t) read_pointer ((const uint8_t **) &linep, enddatap, DW_EH_PE_data8, user, compat_task);
          length = 8;
        }
      if (unit_length < (length + 2) || (linep + unit_length) > enddatap)
        return 0;

      endunitp = linep + unit_length;

      version = read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data2, user, compat_task);

      if (length == 4)
        hdr_length = (uint64_t) read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data4, user, compat_task);
      else
        hdr_length = (uint64_t) read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data8, user, compat_task);

      if ((linep + hdr_length) > endunitp || hdr_length < (version >= 4 ? 6 : 5))
        return 0;

      endhdrp = linep + hdr_length;

      // minimum instruction length
      min_instr_len = *linep++;
      // max operations per instruction
      if (version >= 4)
        {
          max_ops = *linep++;
          if (max_ops == 0)
              return 0; // max operations per instruction is supposed to > 0;
        }
      // default value of the is_stmt register
      ++linep;
      // line base. this is a signed value.
      line_base = *linep++;
      // line range
      line_range = *linep++;
      if (line_range == 0)
        return 0;
      // opcode base
      opcode_base = *linep++;
      // opcodes
      stdopcode_lens_secp = linep - 1;
      // need this check if the header length check covers this region?
      if ((linep + opcode_base - 1) >= endhdrp)
        return 0;
      linep += opcode_base - 1;

      // at the directory table. don't need an other information from the header
      // in order to find the desired line number, so we will save a pointer to
      // this point and skip ahead to the end of the header. this portion of the
      // header will be visited again after a line number has been found if a
      // filename is needed.
      dirsecp = linep;
      linep = endhdrp;

      // iterating through the opcodes. will deal with three defined types of
      // opcode: special, extended and standard. there is also a portion at
      // the end of this loop that will deal with unknown (standard) opcodes.
      while (linep < endunitp)
        {
          uint8_t opcode = *linep++;
          long addr_adv = 0;

          if (opcode >= opcode_base) // special opcode
            {
              // line range was checked before this point. this variable is not altered after it is initialized.
              cumm_line_adv += (line_base + ((opcode - opcode_base) % line_range));
              addr_adv = ((opcode - opcode_base) / line_range);
            }

          else if (opcode == 0) // extended opcode
            {
              int len;
              uint8_t subopcode;

              if (linep + 1 > endunitp)
                return 0;

              len = *linep++;
              if (linep + len > endunitp || len < 1)
                return 0;

              subopcode = *linep++; // the sub opcode
              switch (subopcode)
                {
                  case DW_LNE_end_sequence:
                    // reset the line and address.
                    cumm_line_adv = 1 - curr_linenum;
                    addr_adv = 0 - curr_addr;
                    skip_to_seq_end = 0;
                    op_index = 0;
                    break;
                  case DW_LNE_set_address:
                    if ((len - 1) == 4) // account for the opcode (the -1)
                      curr_addr = (uint64_t) read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data4, user, compat_task);
                    else if ((len - 1) == 8)
                      curr_addr = (uint64_t) read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data8, user, compat_task);
                    else
                      return 0;

                    // if the set address is past the address we want, iterate
                    // to the end of the sequence without doing more address
                    // and linenumber calcs than necessary
                    if (curr_addr > addr)
                      skip_to_seq_end = 1;
                    op_index = 0;
                    break;
                  default: // advance the ptr by the specified amount
                    linep += len-1;
                    break;
                }
            }
          else if (opcode <= DW_LNS_set_isa) // known standard opcode
            {
              uint8_t *linep_before = linep;
              switch (opcode)
                {
                  case DW_LNS_advance_pc:
                    addr_adv = read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128, user, compat_task);
                    break;
                  case DW_LNS_fixed_advance_pc:
                    addr_adv = read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_data2, user, compat_task);
                    if (linep_before == linep) // the read failed
                      return 0;
                    op_index = 0;
                    break;
                  case DW_LNS_advance_line:
                    cumm_line_adv += read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128+DW_EH_PE_signed, user, compat_task);
                    break;
                  case DW_LNS_set_file:
                    curr_file_idx = read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128, user, compat_task);
                    break;
                  case DW_LNS_set_column:
                    read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128, user, compat_task);
                    break;
                  case DW_LNS_const_add_pc:
                    addr_adv = ((255 - opcode_base) / line_range);
                    break;
                  case DW_LNS_set_isa:
                    read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128, user, compat_task);
                    break;
                }
                if (linep > endunitp) // reading in the leb128 failed
                  return 0;
            }
          else
            {
              int i;
              for (i=stdopcode_lens_secp[opcode]; i>0; --i)
                {
                  read_pointer ((const uint8_t **) &linep, endunitp, DW_EH_PE_leb128, user, compat_task);
                  if (linep > endunitp)
                    return 0;
                }
            }

          // don't worry about doing line/address advances since we are waiting
          // till we hit the end of the sequence or the end of the unit at which
          // point the address and linenumber will be reset
          if (skip_to_seq_end == 1)
            continue;

          // calculate actual address advance
          if (opcode != 0 && opcode != DW_LNS_fixed_advance_pc)
            {
              addr_adv = min_instr_len * (op_index + addr_adv) / max_ops;
              op_index =  (op_index + addr_adv) % max_ops;
            }

          // found an address that at least sort of matches the address we
          // were looking for
          if ((curr_addr <= addr && addr < (curr_addr + addr_adv))
              || (curr_addr == addr && addr_adv != 0))
            {

              if (need_filename)
                _stp_filename_lookup(m, filename, dirsecp, endhdrp,
                                     prev_file_idx, user, compat_task);
              return curr_linenum;
            }

          // update the linenumber and file index if the curr_addr is to be updated
          if (addr_adv != 0)
            {
              prev_file_idx = curr_file_idx;
            }
          if (prev_file_idx == curr_file_idx)
          {
              curr_linenum += cumm_line_adv;
              cumm_line_adv = 0;
            }

          curr_addr += addr_adv;
        }
    }
#endif /* STP_NEED_LINE_DATA */

  // no linenumber was found otherwise this function would have returned before this point
  return 0;
}
Beispiel #17
0
uint32_t* read_uintptr(char *id)
{
	return((uint32_t*) read_pointer(id));
}
Beispiel #18
0
static couchstore_error_t modify_node(couchfile_modify_request *rq,
                                      node_pointer *nptr,
                                      int start, int end,
                                      couchfile_modify_result *dst)
{
    char *nodebuf = NULL;  // FYI, nodebuf is a malloced block, not in the arena
    int bufpos = 1;
    int nodebuflen = 0;
    int errcode = 0;
    couchfile_modify_result *local_result = NULL;

    if (start == end) {
        return 0;
    }

    if (nptr) {
        if ((nodebuflen = pread_compressed(rq->db, nptr->pointer, (char **) &nodebuf)) < 0) {
            error_pass(COUCHSTORE_ERROR_READ);
        }
    }

    local_result = make_modres(dst->arena, rq);
    error_unless(local_result, COUCHSTORE_ERROR_ALLOC_FAIL);

    if (nptr == NULL || nodebuf[0] == 1) { //KV Node
        local_result->node_type = KV_NODE;
        while (bufpos < nodebuflen) {
            sized_buf cmp_key, val_buf;
            bufpos += read_kv(nodebuf + bufpos, &cmp_key, &val_buf);
            int advance = 0;
            while (!advance && start < end) {
                advance = 1;
                int cmp_val = rq->cmp.compare(&cmp_key, rq->actions[start].key);

                if (cmp_val < 0) { //Key less than action key
                    mr_push_item(&cmp_key, &val_buf, local_result);
                } else if (cmp_val > 0) { //Key greater than action key
                    switch (rq->actions[start].type) {
                    case ACTION_INSERT:
                        local_result->modified = 1;
                        mr_push_item(rq->actions[start].key, rq->actions[start].value.data, local_result);
                        break;

                    case ACTION_REMOVE:
                        local_result->modified = 1;
                        break;

                    case ACTION_FETCH:
                        if (rq->fetch_callback) {
                            //not found
                            (*rq->fetch_callback)(rq, rq->actions[start].key, NULL, rq->actions[start].value.arg);
                        }
                    }
                    start++;
                    //Do next action on same item in the node, as our action was
                    //not >= it.
                    advance = 0;
                } else if (cmp_val == 0) { //Node key is equal to action key
                    switch (rq->actions[start].type) {
                    case ACTION_INSERT:
                        local_result->modified = 1;
                        mr_push_item(rq->actions[start].key, rq->actions[start].value.data, local_result);
                        break;

                    case ACTION_REMOVE:
                        local_result->modified = 1;
                        break;

                    case ACTION_FETCH:
                        if (rq->fetch_callback) {
                            (*rq->fetch_callback)(rq, rq->actions[start].key, &val_buf, rq->actions[start].value.arg);
                        }
                        //Do next action on same item in the node, as our action was a fetch
                        //and there may be an equivalent insert or remove
                        //following.
                        advance = 0;
                    }
                    start++;
                }
            }
            if (start == end && !advance) {
                //If we've exhausted actions then just keep this key
                mr_push_item(&cmp_key, &val_buf, local_result);
            }
        }
        while (start < end) {
            //We're at the end of a leaf node.
            switch (rq->actions[start].type) {
            case ACTION_INSERT:
                local_result->modified = 1;
                mr_push_item(rq->actions[start].key, rq->actions[start].value.data, local_result);
                break;

            case ACTION_REMOVE:
                local_result->modified = 1;
                break;

            case ACTION_FETCH:
                if (rq->fetch_callback) {
                    //not found
                    (*rq->fetch_callback)(rq, rq->actions[start].key, NULL, rq->actions[start].value.arg);
                }
                break;
            }
            start++;
        }
    } else if (nodebuf[0] == 0) { //KP Node
        local_result->node_type = KP_NODE;
        while (bufpos < nodebuflen && start < end) {
            sized_buf cmp_key, val_buf;
            bufpos += read_kv(nodebuf + bufpos, &cmp_key, &val_buf);
            int cmp_val = rq->cmp.compare(&cmp_key, rq->actions[start].key);
            if (bufpos == nodebuflen) {
                //We're at the last item in the kpnode, must apply all our
                //actions here.
                node_pointer *desc = read_pointer(dst->arena, &cmp_key, val_buf.buf);
                if (!desc) {
                    errcode = COUCHSTORE_ERROR_ALLOC_FAIL;
                    goto cleanup;
                }

                errcode = modify_node(rq, desc, start, end, local_result);
                if (errcode != COUCHSTORE_SUCCESS) {
                    goto cleanup;
                }
                break;
            }

            if (cmp_val < 0) {
                //Key in node item less than action item and not at end
                //position, so just add it and continue.
                node_pointer *add = read_pointer(dst->arena, &cmp_key, val_buf.buf);
                if (!add) {
                    errcode = COUCHSTORE_ERROR_ALLOC_FAIL;
                    goto cleanup;
                }

                errcode = mr_push_pointerinfo(add, local_result);
                if (errcode != COUCHSTORE_SUCCESS) {
                    goto cleanup;
                }
            } else if (cmp_val >= 0) {
                //Found a key in the node greater than the one in the current
                //action. Descend into the pointed node with as many actions as
                //are less than the key here.
                int range_end = start;
                while (range_end < end &&
                        rq->cmp.compare(rq->actions[range_end].key, &cmp_key) <= 0) {
                    range_end++;
                }

                node_pointer *desc = read_pointer(dst->arena, &cmp_key, val_buf.buf);
                if (!desc) {
                    errcode = COUCHSTORE_ERROR_ALLOC_FAIL;
                    goto cleanup;
                }

                errcode = modify_node(rq, desc, start, range_end, local_result);
                start = range_end;
                if (errcode != COUCHSTORE_SUCCESS) {
                    goto cleanup;
                }
            }
        }
        while (bufpos < nodebuflen) {
            sized_buf cmp_key, val_buf;
            bufpos += read_kv(nodebuf + bufpos, &cmp_key, &val_buf);
            node_pointer *add = read_pointer(dst->arena, &cmp_key, val_buf.buf);
            if (!add) {
                errcode = COUCHSTORE_ERROR_ALLOC_FAIL;
                goto cleanup;
            }

            errcode = mr_push_pointerinfo(add, local_result);
            if (errcode != COUCHSTORE_SUCCESS) {
                goto cleanup;
            }
        }
    } else {
        errcode = COUCHSTORE_ERROR_CORRUPT;
        goto cleanup;
    }
    //If we've done modifications, write out the last leaf node.
    error_pass(flush_mr(local_result));
    if (!local_result->modified && nptr != NULL) {
        //If we didn't do anything, give back the pointer to the original
        mr_push_pointerinfo(nptr, dst);
    } else {
        //Otherwise, give back the pointers to the nodes we've created.
        dst->modified = 1;
        error_pass(mr_move_pointers(local_result, dst));
    }
cleanup:
    if (nodebuf) {
        free(nodebuf);
    }

    return errcode;
}
Beispiel #19
0
static int
name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t size)
{
  short nameIndex;
  short signatureIndex;
  uint64_t constantPool;
  uint64_t constMethod;
  uint64_t nameSymbol;
  uint64_t signatureSymbol;
  uint64_t klassPtr;
  uint64_t klassSymbol;
  short klassSymbolLength;
  short nameSymbolLength;
  short signatureSymbolLength;
  char * nameString = NULL;
  char * klassString = NULL;
  char * signatureString = NULL;
  int err;

  err = read_pointer(J, methodPtr + OFFSET_Method_constMethod, &constMethod);
  CHECK_FAIL(err);
  err = read_pointer(J, constMethod + OFFSET_ConstMethod_constants, &constantPool);
  CHECK_FAIL(err);

  /* To get name string */
  err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_name_index, &nameIndex, 2);
  CHECK_FAIL(err);
  err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_ConstantPool, &nameSymbol);
  CHECK_FAIL(err);
  // The symbol is a CPSlot and has lower bit set to indicate metadata
  nameSymbol &= (~1); // remove metadata lsb
  err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2);
  CHECK_FAIL(err);
  nameString = (char*)calloc(nameSymbolLength + 1, 1);
  err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength);
  CHECK_FAIL(err);

  /* To get signature string */
  err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2);
  CHECK_FAIL(err);
  err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol);
  CHECK_FAIL(err);
  signatureSymbol &= (~1);  // remove metadata lsb
  err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2);
  CHECK_FAIL(err);
  signatureString = (char*)calloc(signatureSymbolLength + 1, 1);
  err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength);
  CHECK_FAIL(err);

  /* To get klass string */
  err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr);
  CHECK_FAIL(err);
  err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol);
  CHECK_FAIL(err);
  err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2);
  CHECK_FAIL(err);
  klassString = (char*)calloc(klassSymbolLength + 1, 1);
  err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength);
  CHECK_FAIL(err);

  result[0] = '\0';
  if (snprintf(result, size,
    "%s.%s%s",
    klassString,
    nameString,
    signatureString) >= size) {
    // truncation
    goto fail;
  }

  if (nameString != NULL) free(nameString);
  if (klassString != NULL) free(klassString);
  if (signatureString != NULL) free(signatureString);

  return PS_OK;

 fail:
  if (debug) {
      fprintf(stderr, "name_for_methodPtr: FAIL \n\n");
  }
  if (nameString != NULL) free(nameString);
  if (klassString != NULL) free(klassString);
  if (signatureString != NULL) free(signatureString);
  return -1;
}
Beispiel #20
0
int modify_node(couchfile_modify_request *rq, couchfile_pointer_info *nptr,
                int start, int end, couchfile_modify_result *dst)
{
    eterm_buf current_node;
    int curnode_pos = 0;
    int read_size = 0;
    int list_start_pos = 0;
    int node_len = 0;
    int node_bound = 0;
    int errcode = 0;
    int kpos = 0;

    char node_type[MAXATOMLEN + 1];
    node_type[0] = 0;

    DBG("Enter modify_node. %d - %d\r\n", start, end);

    if(start == end)
    {
        return 0;
    }

    if(nptr == NULL)
    {
        current_node = empty_root;
    }
    else
    {
        if((read_size = pread_bin(rq->fd, nptr->pointer, &current_node.buf)) < 0)
        {
            return ERROR_READ_FILE;
        }
        current_node.size = read_size;
        DBG("... read node from %d\r\n", nptr->pointer);
        curnode_pos++; //Skip over 131.
    }

    couchfile_modify_result *local_result = make_modres(rq);

    ei_decode_tuple_header(current_node.buf, &curnode_pos, NULL);
    if(ei_decode_atom(current_node.buf, &curnode_pos, node_type) < 0)
    {
        errcode = ERROR_PARSE;
        goto cleanup;
    }
    list_start_pos = curnode_pos;
    if(ei_decode_list_header(current_node.buf, &curnode_pos, &node_len) < 0)
    {
        errcode = ERROR_PARSE;
        goto cleanup;
    }

    if(strcmp("kv_node", node_type) == 0)
    {
        local_result->node_type = KV_NODE;
        while(start < end)
        {
            DBG("act on kvnode item\r\n");
            if(node_bound >= node_len)
            { //We're at the end of a leaf node.
                DBG("   ... exec action at end!\r\n");
                switch(rq->actions[start].type)
                {
                    case ACTION_INSERT:
                        local_result->modified = 1;
                        mr_push_action(&rq->actions[start], local_result);
                    break;

                    case ACTION_REMOVE:
                        local_result->modified = 1;
                    break;

                    case ACTION_FETCH:
                        if(rq->fetch_callback)
                        {
                            //not found
                            (*rq->fetch_callback)(rq, rq->actions[start].key, NULL);
                        }
                    break;
                }
                start++;
            }
            else
            {
                kpos = find_first_gteq(current_node.buf, list_start_pos,
                        rq->actions[start].cmp_key,
                        &rq->cmp, node_bound);

                if(kpos < 0)
                {
                    errcode = ERROR_PARSE;
                    goto cleanup;
                }

                //Add items from node_bound up to but not including the current
                mr_push_kv_range(current_node.buf, list_start_pos, node_bound,
                        rq->cmp.list_pos, local_result);

                if(rq->cmp.last_cmp_val > 0) // Node key > action key
                {
                    DBG("   Inserting action before\r\n");
                    switch(rq->actions[start].type)
                    {
                        case ACTION_INSERT:
                            local_result->modified = 1;
                            mr_push_action(&rq->actions[start], local_result);
                        break;

                        case ACTION_REMOVE:
                            local_result->modified = 1;
                        break;

                        case ACTION_FETCH:
                            if(rq->fetch_callback)
                            {
                                //not found
                                (*rq->fetch_callback)(rq, rq->actions[start].key, NULL);
                            }
                        break;
                    }

                    start++;
                    node_bound = rq->cmp.list_pos;
                }
                else if(rq->cmp.last_cmp_val < 0) // Node key < action key
                {
                    DBG("   -- Continue with this action\r\n");
                    node_bound = rq->cmp.list_pos + 1;
                    mr_push_kv_range(current_node.buf, list_start_pos, node_bound - 1,
                            node_bound, local_result);
                }
                else //Node key == action key
                {
                    DBG("   Replacing value with action\r\n");
                    switch(rq->actions[start].type)
                    {
                        case ACTION_INSERT:
                            local_result->modified = 1;
                            mr_push_action(&rq->actions[start], local_result);
                            node_bound = rq->cmp.list_pos + 1;
                        break;

                        case ACTION_REMOVE:
                            local_result->modified = 1;
                            node_bound = rq->cmp.list_pos + 1;
                        break;

                        case ACTION_FETCH:
                            if(rq->fetch_callback)
                            {
                                eterm_buf cb_tmp;
                                int cb_vpos = kpos;
                                ei_decode_tuple_header(current_node.buf, &cb_vpos, NULL);
                                ei_skip_term(current_node.buf, &cb_vpos);
                                cb_tmp.buf = current_node.buf + cb_vpos;
                                cb_tmp.size = cb_vpos;
                                ei_skip_term(current_node.buf, &cb_vpos);
                                cb_tmp.size = cb_vpos - cb_tmp.size;
                                (*rq->fetch_callback)(rq, rq->actions[start].key, &cb_tmp);
                            }
                            node_bound = rq->cmp.list_pos;
                        break;
                    }
                    start++;
                }
            }
        }
        //Push any items past the end of what we dealt with onto result.
        if(node_bound < node_len)
        {
            mr_push_kv_range(current_node.buf, list_start_pos, node_bound,
                    node_len, local_result);
        }
    }
    else if(strcmp("kp_node", node_type) == 0)
    {
        local_result->node_type = KP_NODE;
        while(start < end)
        {
            kpos = find_first_gteq(current_node.buf, list_start_pos,
                    rq->actions[start].cmp_key,
                    &rq->cmp, node_bound);

            if(kpos < 0)
            {
                errcode = ERROR_PARSE;
                goto cleanup;
            }

            if(rq->cmp.list_pos == (node_len - 1)) //got last item in kp_node
            {
                //Push all items in node onto mr
                mr_push_kp_range(current_node.buf, list_start_pos, node_bound,
                        rq->cmp.list_pos, local_result);
                DBG("  ...descending into final item of kpnode\r\n");
                couchfile_pointer_info *desc = read_pointer(current_node.buf, kpos);
                errcode = modify_node(rq, desc, start, end, local_result);
                if(local_result->values_end->value.pointer != desc)
                {
                        free(desc);
                }

                if(errcode < 0)
                {
                    goto cleanup;
                }
                node_bound = node_len;
                break;
            }
            else
            {
                //Get all actions with key <= the key of the current item in the
                //kp_node

                //Push items in node up to but not including current onto mr
                mr_push_kp_range(current_node.buf, list_start_pos, node_bound,
                        rq->cmp.list_pos - 1, local_result);
                int range_end = start;
                while(range_end < end &&
                      ((*rq->cmp.compare)(rq->actions[range_end].cmp_key, rq->cmp.last_cmp_key) <= 0))
                {
                    range_end++;
                }

                DBG("  ...descending into item %d of kpnode\r\n", rq->cmp.list_pos);
                node_bound = rq->cmp.list_pos + 1;
                couchfile_pointer_info *desc = read_pointer(current_node.buf, kpos);
                errcode = modify_node(rq, desc, start, range_end, local_result);
                if(local_result->values_end->value.pointer != desc)
                {
                        free(desc);
                }
                if(errcode < 0)
                {
                    goto cleanup;
                }
                start = range_end;
            }
        }
        DBG(".. Finished kp node, up to %d\r\n", node_bound);
        if(node_bound < node_len)
        {
            //Processed all the actions but haven't exhausted this kpnode.
            //push the rest of it onto the mr.
            mr_push_kp_range(current_node.buf, list_start_pos, node_bound, node_len,
                    local_result);
        }
    }
    else
    {
        errcode = ERROR_PARSE;
        goto cleanup;
    }
    //If we've done modifications, write out the last leaf node.
    errcode = flush_mr(local_result);
    if(errcode == 0)
    {
        if(!local_result->modified && nptr != NULL)
        {
            //If we didn't do anything, give back the pointer to the original
            mr_push_pointerinfo(nptr, dst);
        }
        else
        {
            //Otherwise, give back the pointers to the nodes we've created.
            dst->modified = 1;
            errcode = mr_move_pointers(local_result, dst);
        }
    }
cleanup:
    free_modres(local_result);

    if(current_node.buf != empty_root.buf)
    {
        free(current_node.buf);
    }

    return errcode;
}
Beispiel #21
0
int start(void)
#endif
{
  int i;
  uint32_t apl;
  float ong;
  uint64_t apl64;
  uint16_t apl16;
  uint8_t apl8;
  void* ptr;
  double ong64;
  
  for (i = 0; i < 10; ++i) {
    apl64 = read_uint64("apples64");
    #ifdef RUN
    fprintf(stderr, "\n(%d.a) got a 64 bit apple: %llu..", i, apl64);
    #endif
    
    ong64 = (double)apl64;
    write_float64("oranges64", ong64);
    #ifdef RUN
    fprintf(stderr, "\nsent a (double) orange: %le.", ong64);
    #endif

    apl = read_uint32("apples32");
    #ifdef RUN
    fprintf(stderr, "\n(%d.b) got a 32-bit apple: %d.", i, apl);
    #endif
    
    ong = (float)apl;
    write_float32("oranges32", ong);
    #ifdef RUN
    fprintf(stderr, "\nsent a (float) orange: %f.", ong);
    #endif

    apl16 = read_uint16("apples16");
    #ifdef RUN
    fprintf(stderr, "\n(%d.c) got a 16-bit apple: %d.", i, apl16);
    #endif
    
    apl8 = (uint8_t)apl;
    write_uint8("oranges8", apl8);
    #ifdef RUN
    fprintf(stderr, "\nsent an 8-bit orange: %d.", apl8);
    #endif

    ptr = read_pointer("apples32");
    #ifdef RUN
    fprintf(stderr, "\n(%d.d) got a pointer apple: %d.", i, (unsigned int) ptr);
    #endif
    
    write_pointer("oranges32", ptr);
    #ifdef RUN
    fprintf(stderr, "\nsent a pointer orange: %d.", (unsigned int) ptr);
    #endif
  }

  #ifdef RUN
  fprintf(stderr, "\n");
  #endif
  return 0;
}
/* Unwind to previous to frame.  Returns 0 if successful, negative
 * number in case of an error. */
int 
unwind(struct unwind_frame_info *frame, int is_ehframe)
{
#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
	const u32 *fde = NULL, *cie = NULL;
	const u8 *ptr = NULL, *end = NULL;
	unsigned long startLoc = 0, endLoc = 0, cfa;
	unsigned i;
	signed ptrType = -1;
	uleb128_t retAddrReg = 0;
//	struct unwind_table *table;
	void *unwind_table;
	struct local_unwind_table *table;
	struct unwind_state state;
	u64 reg_ptr = 0;


	if (UNW_PC(frame) == 0)
		return -EINVAL;

	if ((table = find_table(UNW_PC(frame)))) {
//		unsigned long tableSize = unwind_table_size;
		unsigned long tableSize = table->size;

		unwind_table = table->address;

		for (fde = unwind_table;
		     tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
		     tableSize -= sizeof(*fde) + *fde,
		     fde += 1 + *fde / sizeof(*fde)) {
			if (!*fde || (*fde & (sizeof(*fde) - 1)))
				break;
			if (is_ehframe && !fde[1])
				continue; /* this is a CIE */
			else if (fde[1] == 0xffffffff)
				continue; /* this is a CIE */
			if ((fde[1] & (sizeof(*fde) - 1))
			    || fde[1] > (unsigned long)(fde + 1)
			                - (unsigned long)unwind_table)
				continue; /* this is not a valid FDE */
			if (is_ehframe)
				cie = fde + 1 - fde[1] / sizeof(*fde);
			else
				cie = unwind_table + fde[1];
			if (*cie <= sizeof(*cie) + 4
			    || *cie >= fde[1] - sizeof(*fde)
			    || (*cie & (sizeof(*cie) - 1))
			    || (cie[1] != 0xffffffff && cie[1])
			    || (ptrType = fde_pointer_type(cie)) < 0) {
				cie = NULL; /* this is not a (valid) CIE */
				continue;
			}
			ptr = (const u8 *)(fde + 2);
			startLoc = read_pointer(&ptr,
			                        (const u8 *)(fde + 1) + *fde,
			                        ptrType);
			endLoc = startLoc
			         + read_pointer(&ptr,
			                        (const u8 *)(fde + 1) + *fde,
			                        ptrType & DW_EH_PE_indirect
			                        ? ptrType
			                        : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
			if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc)
				break;
			cie = NULL;
		}
	}
	if (cie != NULL) {
		memset(&state, 0, sizeof(state));
		state.cieEnd = ptr; /* keep here temporarily */
		ptr = (const u8 *)(cie + 2);
		end = (const u8 *)(cie + 1) + *cie;
		if ((state.version = *ptr) != 1)
			cie = NULL; /* unsupported version */
		else if (*++ptr) {
			/* check if augmentation size is first (and thus present) */
			if (*ptr == 'z') {
				/* check for ignorable (or already handled)
				 * nul-terminated augmentation string */
				while (++ptr < end && *ptr)
					if (strchr("LPR", *ptr) == NULL)
						break;
			}
			if (ptr >= end || *ptr)
				cie = NULL;
		}
		++ptr;
	}
	if (cie != NULL) {
		/* get code aligment factor */
		state.codeAlign = get_uleb128(&ptr, end);
		/* get data aligment factor */
		state.dataAlign = get_sleb128(&ptr, end);
		if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
			cie = NULL;
		else {
			retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
			/* skip augmentation */
			if (((const char *)(cie + 2))[1] == 'z')
				ptr += get_uleb128(&ptr, end);
			if (ptr > end
			   || retAddrReg >= ARRAY_SIZE(reg_info)
			   || REG_INVALID(retAddrReg)
			   || reg_info[retAddrReg].width != sizeof(unsigned long))
				cie = NULL;
		}
	}
	if (cie != NULL) {
		state.cieStart = ptr;
		ptr = state.cieEnd;
		state.cieEnd = end;
		end = (const u8 *)(fde + 1) + *fde;
		/* skip augmentation */
		if (((const char *)(cie + 2))[1] == 'z') {
			uleb128_t augSize = get_uleb128(&ptr, end);

			if ((ptr += augSize) > end)
				fde = NULL;
		}
	}
	if (cie == NULL || fde == NULL)
		return -ENXIO;

	state.org = startLoc;
	memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
	/* process instructions */
	if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state)
	   || state.loc > endLoc
	   || state.regs[retAddrReg].where == Nowhere
	   || state.cfa.reg >= ARRAY_SIZE(reg_info)
	   || reg_info[state.cfa.reg].width != sizeof(unsigned long)
	   || state.cfa.offs % sizeof(unsigned long)) {
		return -EIO;
		}
	/* update frame */
	cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
	startLoc = min((unsigned long)UNW_SP(frame), cfa);
	endLoc = max((unsigned long)UNW_SP(frame), cfa);
	if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
		startLoc = min(STACK_LIMIT(cfa), cfa);
		endLoc = max(STACK_LIMIT(cfa), cfa);
	}
#ifndef CONFIG_64BIT
# define CASES CASE(8); CASE(16); CASE(32)
#else
# define CASES CASE(8); CASE(16); CASE(32); CASE(64)
#endif
	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
		if (REG_INVALID(i)) {
			if (state.regs[i].where == Nowhere)
				continue;
			return -EIO;
		}
		switch(state.regs[i].where) {
		default:
			break;
		case Register:
			if (state.regs[i].value >= ARRAY_SIZE(reg_info)
			   || REG_INVALID(state.regs[i].value)
			   || reg_info[i].width > reg_info[state.regs[i].value].width){
				return -EIO;
	}
			switch(reg_info[state.regs[i].value].width) {
#define CASE(n) \
			case sizeof(u##n): \
				state.regs[i].value = FRAME_REG(state.regs[i].value, \
				                                const u##n); \
				break
			CASES;
#undef CASE
			default:
				return -EIO;
			}
			break;
		}
	}
	for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
		if (REG_INVALID(i))
			continue;
		switch(state.regs[i].where) {
		case Nowhere:
			if (reg_info[i].width != sizeof(UNW_SP(frame))
			   || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
			      != &UNW_SP(frame))
				continue;
			UNW_SP(frame) = cfa;
			break;
		case Register:
			switch(reg_info[i].width) {
#define CASE(n) case sizeof(u##n): \
				FRAME_REG(i, u##n) = state.regs[i].value; \
				break
			CASES;
#undef CASE
			default:
				return -EIO;
			}
			break;
		case Value:
			if (reg_info[i].width != sizeof(unsigned long)){
				return -EIO;}
			FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
			                                    * state.dataAlign;
			break;
		case Memory: {
				unsigned long addr = cfa + state.regs[i].value
				                           * state.dataAlign;
				if ((state.regs[i].value * state.dataAlign)
				    % sizeof(unsigned long)
				    || addr < startLoc
				    || addr + sizeof(unsigned long) < addr
				    || addr + sizeof(unsigned long) > endLoc){
					return -EIO;}
				switch(reg_info[i].width) {
#define CASE(n)     case sizeof(u##n): \
					readmem(addr, KVADDR, &reg_ptr,sizeof(u##n), "register", RETURN_ON_ERROR|QUIET); \
					FRAME_REG(i, u##n) = (u##n)reg_ptr;\
					break
				CASES;
#undef CASE
				default:
					return -EIO;
				}
			}
			break;
		}
	}
	return 0;
#undef CASES
#undef FRAME_REG
}
Beispiel #23
0
static void *
execute_cfa_insn (void *p, struct frame_state_internal *state,
		  struct cie_info *info, void **pc)
{
  unsigned insn = *(unsigned char *)p++;
  unsigned reg;
  int offset;

  if (insn & DW_CFA_advance_loc)
    *pc += ((insn & 0x3f) * info->code_align);
  else if (insn & DW_CFA_offset)
    {
      reg = (insn & 0x3f);
      p = decode_uleb128 (p, &offset);
      offset *= info->data_align;
      state->s.saved[reg] = REG_SAVED_OFFSET;
      state->s.reg_or_offset[reg] = offset;
    }
  else if (insn & DW_CFA_restore)
    {
      reg = (insn & 0x3f);
      state->s.saved[reg] = REG_UNSAVED;
    }
  else switch (insn)
    {
    case DW_CFA_set_loc:
      *pc = read_pointer (p);
      p += sizeof (void *);
      break;
    case DW_CFA_advance_loc1:
      *pc += read_1byte (p);
      p += 1;
      break;
    case DW_CFA_advance_loc2:
      *pc += read_2byte (p);
      p += 2;
      break;
    case DW_CFA_advance_loc4:
      *pc += read_4byte (p);
      p += 4;
      break;

    case DW_CFA_offset_extended:
      p = decode_uleb128 (p, &reg);
      p = decode_uleb128 (p, &offset);
      offset *= info->data_align;
      state->s.saved[reg] = REG_SAVED_OFFSET;
      state->s.reg_or_offset[reg] = offset;
      break;
    case DW_CFA_restore_extended:
      p = decode_uleb128 (p, &reg);
      state->s.saved[reg] = REG_UNSAVED;
      break;

    case DW_CFA_undefined:
    case DW_CFA_same_value:
    case DW_CFA_nop:
      break;

    case DW_CFA_register:
      {
	unsigned reg2;
	p = decode_uleb128 (p, &reg);
	p = decode_uleb128 (p, &reg2);
	state->s.saved[reg] = REG_SAVED_REG;
	state->s.reg_or_offset[reg] = reg2;
      }
      break;

    case DW_CFA_def_cfa:
      p = decode_uleb128 (p, &reg);
      p = decode_uleb128 (p, &offset);
      state->s.cfa_reg = reg;
      state->s.cfa_offset = offset;
      break;
    case DW_CFA_def_cfa_register:
      p = decode_uleb128 (p, &reg);
      state->s.cfa_reg = reg;
      break;
    case DW_CFA_def_cfa_offset:
      p = decode_uleb128 (p, &offset);
      state->s.cfa_offset = offset;
      break;
      
    case DW_CFA_remember_state:
      {
	struct frame_state_internal *save =
	  (struct frame_state_internal *)
	  malloc (sizeof (struct frame_state_internal));
	memcpy (save, state, sizeof (struct frame_state_internal));
	state->saved_state = save;
      }
      break;
    case DW_CFA_restore_state:
      {
	struct frame_state_internal *save = state->saved_state;
	memcpy (state, save, sizeof (struct frame_state_internal));
	free (save);
      }
      break;

      /* FIXME: Hardcoded for SPARC register window configuration.  */
    case DW_CFA_GNU_window_save:
      for (reg = 16; reg < 32; ++reg)
	{
	  state->s.saved[reg] = REG_SAVED_OFFSET;
	  state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *);
	}
      break;

    case DW_CFA_GNU_args_size:
      p = decode_uleb128 (p, &offset);
      state->s.args_size = offset;
      break;

    default:
      abort ();
    }
  return p;
}
Beispiel #24
0
static int
init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
  Debugger* dbg = (Debugger*) cd;
  JNIEnv*   env = dbg->env;
  jobject this_obj = dbg->this_obj;
  const char* jvm_name = 0;
  if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL) {
    jvm_name = obj_name;
  } else {
    return 0;
  }

  struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);

  // initialize classes.jsa file descriptor field.
  dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);

  // check whether class sharing is on by reading variable "UseSharedSpaces"
  psaddr_t useSharedSpacesAddr = 0;
  ps_pglobal_lookup(ph, jvm_name, USE_SHARED_SPACES_SYM, &useSharedSpacesAddr);
  if (useSharedSpacesAddr == 0) {
    THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'UseSharedSpaces' flag\n", 1);
  }

  // read the value of the flag "UseSharedSpaces"
  // Since hotspot types are not available to build this library. So
  // equivalent type "jboolean" is used to read the value of "UseSharedSpaces"
  // which is same as hotspot type "bool".
  jboolean value = 0;
  if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) {
    THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
  } else if ((int)value == 0) {
    print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
    return 1;
  }

  char classes_jsa[PATH_MAX];
  psaddr_t sharedArchivePathAddrAddr = 0;
  ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
  if (sharedArchivePathAddrAddr == 0) {
    print_debug("can't find symbol 'Arguments::SharedArchivePath'\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  uintptr_t sharedArchivePathAddr = 0;
  if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
    print_debug("can't find read pointer 'Arguments::SharedArchivePath'\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
    print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  print_debug("looking for %s\n", classes_jsa);

  // open the classes.jsa
  int fd = libsaproc_open(classes_jsa, O_RDONLY);
  if (fd < 0) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  } else {
    print_debug("opened shared archive file %s\n", classes_jsa);
  }

  // parse classes.jsa
  struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
  if (pheader == NULL) {
    close(fd);
    THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
  }

  memset(pheader, 0, sizeof(struct FileMapHeader));
  // read FileMapHeader
  size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
  if (n != sizeof(struct FileMapHeader)) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  // check file magic
  if (pheader->_magic != 0xf00baba2) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
                   classes_jsa, pheader->_magic);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  // check version
  if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
                   classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  if (_libsaproc_debug) {
    for (int m = 0; m < NUM_SHARED_MAPS; m++) {
       print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
          pheader->_space[m]._file_offset, pheader->_space[m]._base,
          pheader->_space[m]._used, pheader->_space[m]._read_only);
    }
  }

  // FIXME: For now, omitting other checks such as VM version etc.

  // store class archive file fd and map header in debugger object fields
  dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
  dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
  return 1;
}
Beispiel #25
0
int start (void)
#endif
{
    uint64_t apl64;
    uint32_t i, apl;
    uint16_t apl16;
    uint8_t apl8,my_apl8;
    void *sptr, *rptr;
    double ong64, my_ong64;
    float ong, my_ong;
    int failure = 0;

    i = 0;

    while (i < 10) {
#ifdef RUN
        apl = rand();
#else
        apl = i + 1;
#endif
        my_ong = (float)apl;
        my_ong64 = (double)apl;
        apl64  = (uint64_t)apl;
        apl16  = (uint16_t)apl;
        my_apl8  = (uint8_t)apl16;

        write_uint64("apples64", apl64);
#ifdef RUN
        fprintf(stderr, "\n(%d.a) sent a 64-bit apple: %llu..", i, apl64);
#endif

        ong64 = read_float64("oranges64");

#ifdef RUN
        fprintf(stderr, "\ngot a (double) orange: %le.", ong64);
#endif

        failure |= (my_ong64 != ong64);

        write_uint32("apples32", apl);
#ifdef RUN
        fprintf(stderr, "\n(%d.b) sent a 32-bit apple: %d.", i, apl);
#endif

        ong = read_float32("oranges32");
#ifdef RUN
        fprintf(stderr, "\ngot a (float) orange: %f.", ong);
#endif

        failure |= (my_ong != ong);

        write_uint16("apples16", apl16);
#ifdef RUN
        fprintf(stderr, "\n(%d.c) sent a 16-bit apple: %d.", i, apl16);
#endif

        apl8 = read_uint8("oranges8");
#ifdef RUN
        fprintf(stderr, "\ngot an 8-bit orange: %d.", apl8);
#endif

        sptr = (void*) &apl;
        write_pointer("apples32", sptr);
#ifdef RUN
        fprintf(stderr, "\n(%d.d) sent a pointer apple: %d.", i, (unsigned int)sptr);
#endif

        rptr = read_pointer("oranges32");
#ifdef RUN
        fprintf(stderr, "\ngot a pointer orange: %d.",(unsigned int) rptr);
#endif

        failure |= (sptr != rptr);
        ++i;
    }

#ifdef RUN
    if (failure == 0)
        fprintf(stderr, "\nAll conversions successful.\n");
    else
        fprintf(stderr, "\nSome conversion(s) failed.\n");
#endif

    return failure;
}
Beispiel #26
0
void gdb_save_stacktrace(const char *text_in, const char *text_out){
	FILE *fin;
	FILE *fout;
	int number = 0;
	size_t nbytes = 300;
	fout = fopen(text_out, "w+");
	fin = fopen(text_in, "r");
	str = (char *) malloc (nbytes + 1);
	
	while(1){
		size = getline (&str, &nbytes, fin);
		if (size == -1) break;
		if (size == 0) break;
		str[size-1] = '\0';
		poz = 4;
		if(get_char(poz) == '0'){
			read_pointer();
			poz += 4;
		}
		char *func = read_name();
		poz += 1;
		int tmppoz = poz;
		if (strcmp(func, "gdb_die") == 0) {
			fprintf(fout, "%s\n", c_rt_lib0get_die_additional_info());
			while(get_char(tmppoz) != '"' && get_char(tmppoz) != '\0') ++tmppoz;
			fprintf(fout, "\"");
			while(1){
				char tmp = get_char(++tmppoz);
				if(tmp == '"') break;
				if(tmp == '\0') break;
				if(tmp == '\\') tmp = get_char(++tmppoz);
				if(tmp == '"') fprintf(fout, "\"");
				fprintf(fout, "%c", tmp);
			}
			fprintf(fout, "\"\n");
			fflush(fout);
		}
		tmppoz = size-3;
		while(is_num(get_char(tmppoz))) --tmppoz;
		int line = atoi(str+tmppoz+1);
		if(get_char(tmppoz) == ':') str[tmppoz] = '\0';
		while(get_char(tmppoz)!=')') --tmppoz;
		tmppoz += 5;
		fprintf(fout, "%d	%s	%s	%d", number, func, str+tmppoz, line);
		int param = 0;
		while(1) {
			if(get_char(poz) == ',') {
				poz +=2;
			} else if(get_char(poz) == '(') {
				poz +=1;
				if(get_char(poz) == ')') break;
			} else if(get_char(poz) == ')') {
				break;
			} else {
				break;
			}
			char *name = read_name();
			void *ptr = NULL;
			if(get_char(poz) == '='){
				++poz;
				ptr = read_pointer();
			}
			if(startsWith("___nl__", name) && ptr != NULL){
				ImmT saved = dfile0ssave(ptr);
				NlString* p = toStringIfSim(saved);
				fprintf(fout, "	\"p%d ", param);
				fprintString(fout, p->s, p->length);
				fprintf(fout, "\"");
			} else if(startsWith("___ref___", name) && ptr != NULL && *(ImmT*)ptr != NULL){
				ImmT saved = dfile0ssave(*(ImmT*)ptr);
				NlString* p = toStringIfSim(saved);
				fprintf(fout, "	\"p%d REF ", param);
				fprintString(fout, p->s, p->length);
				fprintf(fout, "\"");
			} else {
				fprintf(fout, "	p%d %s=%p", param, name, ptr);
			}
			fflush(fout);
			++param;
		}
		fprintf(fout, "\n");
		fflush(fout);
		++number;
	}
	free(str);
	fclose(fin);
	fclose(fout);
}
Beispiel #27
0
static bool init_classsharing_workaround(struct ps_prochandle* ph) {
   lib_info* lib = ph->libs;
   while (lib != NULL) {
      // we are iterating over shared objects from the core dump. look for
      // libjvm.so.
      const char *jvm_name = 0;
      if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0) {
         char classes_jsa[PATH_MAX];
         struct FileMapHeader header;
         size_t n = 0;
         int fd = -1, m = 0;
         uintptr_t base = 0, useSharedSpacesAddr = 0;
         uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
         jboolean useSharedSpaces = 0;
         map_info* mi = 0;

         memset(classes_jsa, 0, sizeof(classes_jsa));
         jvm_name = lib->name;
         useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
         if (useSharedSpacesAddr == 0) {
            print_debug("can't lookup 'UseSharedSpaces' flag\n");
            return false;
         }

         // Hotspot vm types are not exported to build this library. So
         // using equivalent type jboolean to read the value of
         // UseSharedSpaces which is same as hotspot type "bool".
         if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
            print_debug("can't read the value of 'UseSharedSpaces' flag\n");
            return false;
         }

         if ((int)useSharedSpaces == 0) {
            print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
            return true;
         }

         sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
         if (sharedArchivePathAddrAddr == 0) {
            print_debug("can't lookup shared archive path symbol\n");
            return false;
         }

         if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
            print_debug("can't read shared archive path pointer\n");
            return false;
         }

         if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
            print_debug("can't read shared archive path value\n");
            return false;
         }

         print_debug("looking for %s\n", classes_jsa);
         // open the class sharing archive file
         fd = pathmap_open(classes_jsa);
         if (fd < 0) {
            print_debug("can't open %s!\n", classes_jsa);
            ph->core->classes_jsa_fd = -1;
            return false;
         } else {
            print_debug("opened %s\n", classes_jsa);
         }

         // read FileMapHeader from the file
         memset(&header, 0, sizeof(struct FileMapHeader));
         if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
              != sizeof(struct FileMapHeader)) {
            print_debug("can't read shared archive file map header from %s\n", classes_jsa);
            close(fd);
            return false;
         }

         // check file magic
         if (header._magic != 0xf00baba2) {
            print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
                        classes_jsa, header._magic);
            close(fd);
            return false;
         }

         // check version
         if (header._version != CURRENT_ARCHIVE_VERSION) {
            print_debug("%s has wrong shared archive file version %d, expecting %d\n",
                        classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
            close(fd);
            return false;
         }

         ph->core->classes_jsa_fd = fd;
         // add read-only maps from classes.jsa to the list of maps
         for (m = 0; m < NUM_SHARED_MAPS; m++) {
            if (header._space[m]._read_only) {
               base = (uintptr_t) header._space[m]._base;
               // no need to worry about the fractional pages at-the-end.
               // possible fractional pages are handled by core_read_data.
               add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
                         base, (size_t) header._space[m]._used);
               print_debug("added a share archive map at 0x%lx\n", base);
            }
         }
         return true;
      }
      lib = lib->next;
   }
   return true;
}
Beispiel #28
0
static int nmethod_info(Nmethod_t *N)
{
    jvm_agent_t *J = N->J;
    uint64_t    nm = N->nm;
    int32_t err;

    if (debug > 2 )
        fprintf(stderr, "\t nmethod_info: BEGIN \n");

    /* Instructions */
    err = read_pointer(J, nm + OFFSET_CodeBlob_code_begin, &N->instrs_beg);
    CHECK_FAIL(err);
    err = read_pointer(J, nm + OFFSET_CodeBlob_code_end, &N->instrs_end);
    CHECK_FAIL(err);
    err = read_pointer(J, nm + OFFSET_nmethod_deopt_handler_begin, &N->deopt_beg);
    CHECK_FAIL(err);
    err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32);
    CHECK_FAIL(err);

    /* Metadata */
    err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32);
    CHECK_FAIL(err);
    err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->metadata_end, SZ32);
    CHECK_FAIL(err);

    /* scopes_pcs */
    err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32);
    CHECK_FAIL(err);
    err = ps_pread(J->P, nm + OFFSET_nmethod_dependencies_offset, &N->scopes_pcs_end, SZ32);
    CHECK_FAIL(err);

    /* scopes_data */
    err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->scopes_data_beg, POINTER_SIZE);
    CHECK_FAIL(err);

    if (debug > 2 ) {
        N->scopes_data_end = N->scopes_pcs_beg;

        fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n",
                N->instrs_beg, N->instrs_end);

        fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n",
                N->deopt_beg);

        fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n",
                N->orig_pc_offset);

        fprintf(stderr, "\t nmethod_info: metadata_beg: %#x, metadata_end: %#x\n",
                N->metadata_beg, N->metadata_end);

        fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n",
                N->scopes_data_beg, N->scopes_data_end);

        fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n",
                N->scopes_pcs_beg, N->scopes_pcs_end);

        fprintf(stderr, "\t nmethod_info: END \n\n");
    }
    return PS_OK;

fail:
    return err;
}
static int processCFI(const u8 *start,
                      const u8 *end,
                      unsigned long targetLoc,
                      signed ptrType,
                      struct unwind_state *state)
{
	union {
		const u8 *p8;
		const u16 *p16;
		const u32 *p32;
	} ptr;
	int result = 1;

	if (start != state->cieStart) {
		state->loc = state->org;
		result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state);
		if (targetLoc == 0 && state->label == NULL)
			return result;
	}
	for (ptr.p8 = start; result && ptr.p8 < end; ) {
		switch(*ptr.p8 >> 6) {
			uleb128_t value;

		case 0:
			switch(*ptr.p8++) {
			case DW_CFA_nop:
				break;
			case DW_CFA_set_loc:
				if ((state->loc = read_pointer(&ptr.p8, end,
								ptrType)) == 0)
					result = 0;
				break;
			case DW_CFA_advance_loc1:
				result = ptr.p8 < end && advance_loc(*ptr.p8++, state);
				break;
			case DW_CFA_advance_loc2:
				result = ptr.p8 <= end + 2
				         && advance_loc(*ptr.p16++, state);
				break;
			case DW_CFA_advance_loc4:
				result = ptr.p8 <= end + 4
				         && advance_loc(*ptr.p32++, state);
				break;
			case DW_CFA_offset_extended:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Memory,
					get_uleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_val_offset:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Value,
					get_uleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_offset_extended_sf:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Memory,
					get_sleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_val_offset_sf:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Value,
					get_sleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_restore_extended:
			case DW_CFA_undefined:
			case DW_CFA_same_value:
				set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0,	state);
				break;
			case DW_CFA_register:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Register,
				         get_uleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_remember_state:
				if (ptr.p8 == state->label) {
					state->label = NULL;
					return 1;
				}
				if (state->stackDepth >= MAX_STACK_DEPTH)
					return 0;
				state->stack[state->stackDepth++] = ptr.p8;
				break;
			case DW_CFA_restore_state:
				if (state->stackDepth) {
					const uleb128_t loc = state->loc;
					const u8 *label = state->label;

					state->label = state->stack[state->stackDepth - 1];
					memcpy(&state->cfa, &badCFA, sizeof(state->cfa));
					memset(state->regs, 0, sizeof(state->regs));
					state->stackDepth = 0;
					result = processCFI(start, end, 0, ptrType, state);
					state->loc = loc;
					state->label = label;
				} else
					return 0;
				break;
			case DW_CFA_def_cfa:
				state->cfa.reg = get_uleb128(&ptr.p8, end);
				/*nobreak*/
			case DW_CFA_def_cfa_offset:
				state->cfa.offs = get_uleb128(&ptr.p8, end);
				break;
			case DW_CFA_def_cfa_sf:
				state->cfa.reg = get_uleb128(&ptr.p8, end);
				/*nobreak*/
			case DW_CFA_def_cfa_offset_sf:
				state->cfa.offs = get_sleb128(&ptr.p8, end)
				                  * state->dataAlign;
				break;
			case DW_CFA_def_cfa_register:
				state->cfa.reg = get_uleb128(&ptr.p8, end);
				break;
			/*todo case DW_CFA_def_cfa_expression: */
			/*todo case DW_CFA_expression: */
			/*todo case DW_CFA_val_expression: */
			case DW_CFA_GNU_args_size:
				get_uleb128(&ptr.p8, end);
				break;
			case DW_CFA_GNU_negative_offset_extended:
				value = get_uleb128(&ptr.p8, end);
				set_rule(value, Memory, (uleb128_t)0 -
				         get_uleb128(&ptr.p8, end), state);
				break;
			case DW_CFA_GNU_window_save:
			default:
				result = 0;
				break;
			}
			break;
		case 1:
			result = advance_loc(*ptr.p8++ & 0x3f, state);
			break;
		case 2:
			value = *ptr.p8++ & 0x3f;
			set_rule(value, Memory, get_uleb128(&ptr.p8, end),
				 state);
			break;
		case 3:
			set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
			break;
		}
		if (ptr.p8 > end)
			result = 0;
		if (result && targetLoc != 0 && targetLoc < state->loc)
			return 1;
	}

	return result
	   && ptr.p8 == end
	   && (targetLoc == 0
	    || (/*todo While in theory this should apply, gcc in practice omits
	          everything past the function prolog, and hence the location
	          never reaches the end of the function.
	        targetLoc < state->loc &&*/ state->label == NULL));
}