예제 #1
0
 /// Constructor with default number of elements.
 hash_map()
   : num_buckets_(hash_size(BAS_HASH_MAP_DEFAULT_BUCKETS)),
     num_mutexs_(hash_size(BAS_HASH_MAP_DEFAULT_MUTEXS)),
     mutexs_(NULL)
 {
   init();
 }
예제 #2
0
 /// Constructor with given number of elements.
 hash_map(const size_t num_elements,
          const size_t num_mutexs = BAS_HASH_MAP_DEFAULT_MUTEXS)
   : num_buckets_(hash_size(num_elements)),
     num_mutexs_(hash_size(num_mutexs)),
     mutexs_(NULL)
 {
   init();
 }
예제 #3
0
파일: hash_map.hpp 프로젝트: barrbrain/asio
 // Insert a new entry into the map.
 std::pair<iterator, bool> insert(const value_type& v)
 {
   if (size_ + 1 >= num_buckets_)
     rehash(hash_size(size_ + 1));
   size_t bucket = calculate_hash_value(v.first) % num_buckets_;
   iterator it = buckets_[bucket].first;
   if (it == values_.end())
   {
     buckets_[bucket].first = buckets_[bucket].last =
       values_insert(values_.end(), v);
     ++size_;
     return std::pair<iterator, bool>(buckets_[bucket].last, true);
   }
   iterator end = buckets_[bucket].last;
   ++end;
   while (it != end)
   {
     if (it->first == v.first)
       return std::pair<iterator, bool>(it, false);
     ++it;
   }
   buckets_[bucket].last = values_insert(end, v);
   ++size_;
   return std::pair<iterator, bool>(buckets_[bucket].last, true);
 }
예제 #4
0
파일: libs.c 프로젝트: clarkok/cript
static Value
_lib_sizeof(VMState *vm, Value value)
{
    Hash *args = value_to_ptr(value);
    Value query_val = hash_find(args, 1);

    if (value_is_string(query_val)) {
        CString *string = value_to_string(query_val);
        return value_from_int(string->length);
    }
    else if (value_is_ptr(query_val)) {
        Hash *hash = value_to_ptr(query_val);
        while (hash->type == HT_REDIRECT) hash = (Hash*)hash->size;
        assert(hash->type != HT_GC_LEFT);

        switch (hash->type) {
            case HT_OBJECT:
            case HT_ARRAY:
                return value_from_int(hash_size(hash));
            case HT_LIGHTFUNC:
            case HT_CLOSURE:
            case HT_USERDATA:
                return value_from_int(-1);
            default: assert(0);
        }
    }

    return value_from_int(-1);
}
예제 #5
0
void HashTable::rehash()
{
    size_t new_size, i;
    HashNode **new_buckets = NULL;

    new_size = hash_size(this->entries * 2 / (this->high + this->low));
    if (new_size == this->num_buckets)
    {
        return;
    }
    new_buckets = (HashNode **)calloc(new_size, sizeof(HashNode *));

    for (i = 0; i < this->num_buckets; i++)
    {
        HashNode *entry = this->buckets[i];
        while (entry)
        {
            HashNode *nhe = entry->next_in_bucket;
            uint32_t hv = hash_value(entry->name, new_size);
            entry->next_in_bucket = new_buckets[hv];
            new_buckets[hv] = entry;
            entry = nhe;
        }
    }

    this->num_buckets = new_size;
    free(this->buckets);
    this->buckets = new_buckets;
    this->resized_count++;
}
예제 #6
0
/** 
 * Print dependence 
 * @param obj
 */
static int	revm_dolist_dep(elfshobj_t *obj)
{
  elfshobj_t	*actual;
  char		logbuf[20];
  char		**keys;
  int		keynbr;
  int		index;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  if (!obj)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		      "Invalid argument", -1);
  
  if (hash_size(&obj->child_hash))
    {
      keys = hash_get_keys(&obj->child_hash, &keynbr);
      revm_output("DEPS = [");
      for (index = 0; index < keynbr; index++)
	{
	  actual = hash_get(&obj->child_hash, keys[index]);
	  snprintf(logbuf, sizeof(logbuf), "%s%u", 
		   (index == 0 ? "" : ","), actual->id);
	  revm_output(logbuf);
	}
      revm_output("]");
    }

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
예제 #7
0
/**
 * @brief Return the only element of this hash .
 * @param hash Hash table.
 * @return NULL on error.
 */
void		*hash_get_single(hash_t *hash)
{
  char		**keys;
  int		idx;

  if (!hash || hash_size(hash) != 1)
    return (NULL);
  keys = hash_get_keys(hash, &idx);
  return (hash_get(hash, keys[0]));
}
예제 #8
0
HashTable::HashTable(size_t size, uint32_t flags)
  : num_buckets(hash_size(size)),
    entries(0),
    flags(flags),
    high(0.75),
    low(0.25),
    resized_count(0)
{
    this->buckets = (HashNode **)calloc(num_buckets, sizeof(HashNode *));
}
예제 #9
0
/**
 * Return an element of this hash 
 * The choice is non-deterministic.
 *
 * @param hash
 * @return
 */
void*		hash_get_one(hash_t *hash)
{
  char		**keys;
  int		index;

  if (!hash || !hash_size(hash))
    return (NULL);
  keys = hash_get_keys(hash, &index);
  return (hash_get(hash, keys[0]));
}
예제 #10
0
파일: frame.c 프로젝트: chutchUCD/OS
/**
 * Allocate a new frame,
 * and return the address of the associated page.
 */
void*
vm_frame_allocate (enum palloc_flags flags, void *upage)
{
  lock_acquire (&frame_lock);

  void *frame_page = palloc_get_page (PAL_USER | flags);
  if (frame_page == NULL) {
    // page allocation failed.

    /* first, swap out the page */
    struct frame_table_entry *f_evicted = pick_frame_to_evict( thread_current()->pagedir );

#if DEBUG
    printf("f_evicted: %x th=%x, pagedir = %x, up = %x, kp = %x, hash_size=%d\n", f_evicted, f_evicted->t,
        f_evicted->t->pagedir, f_evicted->upage, f_evicted->kpage, hash_size(&frame_map));
#endif
    ASSERT (f_evicted != NULL && f_evicted->t != NULL);

    // clear the page mapping, and replace it with swap
    ASSERT (f_evicted->t->pagedir != (void*)0xcccccccc);
    pagedir_clear_page(f_evicted->t->pagedir, f_evicted->upage);

    bool is_dirty = false;
    is_dirty = is_dirty || pagedir_is_dirty(f_evicted->t->pagedir, f_evicted->upage);
    is_dirty = is_dirty || pagedir_is_dirty(f_evicted->t->pagedir, f_evicted->kpage);

    swap_index_t swap_idx = vm_swap_out( f_evicted->kpage );
    vm_supt_set_swap(f_evicted->t->supt, f_evicted->upage, swap_idx);
    vm_supt_set_dirty(f_evicted->t->supt, f_evicted->upage, is_dirty);
    vm_frame_do_free(f_evicted->kpage, true); // f_evicted is also invalidated

    frame_page = palloc_get_page (PAL_USER | flags);
    ASSERT (frame_page != NULL); // should success in this chance
  }

  struct frame_table_entry *frame = malloc(sizeof(struct frame_table_entry));
  if(frame == NULL) {
    // frame allocation failed. a critical state or panic?
    lock_release (&frame_lock);
    return NULL;
  }

  frame->t = thread_current ();
  frame->upage = upage;
  frame->kpage = frame_page;
  frame->pinned = true;         // can't be evicted yet

  // insert into hash table
  hash_insert (&frame_map, &frame->helem);
  list_push_back (&frame_list, &frame->lelem);

  lock_release (&frame_lock);
  return frame_page;
}
예제 #11
0
/* Close the memory device */
int		cmd_closemem()
{
  int		ret;
  char		buff[BUFSIZ];
  char          logbuf[BUFSIZ];
  time_t        uloadt;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Close memory */
  ret = kernsh_closemem();

  if (ret)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, 
		 "Cannot close memory", -1);

  if (libkernshworld.open_static)
    {
      /* Rip from cmd_unload */

      /* Do not unload dependences of files or objects with linkmap entry */
      if (hash_size(&libkernshworld.root->parent_hash))
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Unload parent object first", -1);
      ret = revm_unload_dep(libkernshworld.root, libkernshworld.root);
      if (!world.state.revm_quiet)
	{
	  time(&uloadt);
	  snprintf(logbuf, BUFSIZ - 1, "%s [*] Object %-40s unloaded on %s \n",
		   (ret ? "" : "\n"), libkernshworld.root->name, ctime(&uloadt));
	  revm_output(logbuf);
	}
      
      /* Clean various hash tables of this binary entry and return OK */
      hash_del(&file_hash, libkernshworld.root->name);
      if (hash_get(&world.shared_hash, libkernshworld.root->name))
	hash_del(&world.shared_hash, libkernshworld.root->name);
      else
	hash_del(&world.curjob->loaded, libkernshworld.root->name);
      elfsh_unload_obj(libkernshworld.root);

      libkernshworld.open_static = 0;
    }
    
  memset(buff, '\0', sizeof(buff));
  snprintf(buff, sizeof(buff), 
	   "%s\n\n",
	   revm_colorfieldstr("[+] CLOSE MEMORY"));
  revm_output(buff);
  revm_endline();
 
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
예제 #12
0
static void alloc_shm(size_t sz, uint32_t algo)
{
	TEEC_Result res;

	in_shm.buffer = NULL;
	in_shm.size = sz + offset;
	res = TEEC_AllocateSharedMemory(&ctx, &in_shm);
	check_res(res, "TEEC_AllocateSharedMemory");

	out_shm.buffer = NULL;
	out_shm.size = hash_size(algo);
	res = TEEC_AllocateSharedMemory(&ctx, &out_shm);
	check_res(res, "TEEC_AllocateSharedMemory");
}
예제 #13
0
/* Hash test: buffer of size byte. Run test n times. */
static void run_test(size_t size, unsigned int n, unsigned int l)
{
	uint64_t t;
	struct statistics stats;
	TEEC_Operation op;
	int n0 = n;

	alloc_shm(size, algo);

	if (!random_in)
		memset((uint8_t *)in_shm.buffer + offset, 0, size);

	memset(&op, 0, sizeof(op));
	op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_PARTIAL_INPUT,
					 TEEC_MEMREF_PARTIAL_OUTPUT,
					 TEEC_VALUE_INPUT, TEEC_NONE);
	op.params[0].memref.parent = &in_shm;
	op.params[0].memref.offset = 0;
	op.params[0].memref.size = size + offset;
	op.params[1].memref.parent = &out_shm;
	op.params[1].memref.offset = 0;
	op.params[1].memref.size = hash_size(algo);
	op.params[2].value.a = l;
	op.params[2].value.b = offset;

	verbose("Starting test: %s, size=%zu bytes, ",
		algo_str(algo), size);
	verbose("random=%s, ", yesno(random_in));
	verbose("unaligned=%s, ", yesno(offset));
	verbose("inner loops=%u, loops=%u, warm-up=%u s\n", l, n, warmup);

	if (warmup)
		do_warmup();

	memset(&stats, 0, sizeof(stats));
	while (n-- > 0) {
		t = run_test_once((uint8_t *)in_shm.buffer + offset, size, &op, l);
		update_stats(&stats, t);
		if (n % (n0/10) == 0)
			vverbose("#");
	}
	vverbose("\n");
	printf("min=%gμs max=%gμs mean=%gμs stddev=%gμs (%gMiB/s)\n",
	       stats.min/1000, stats.max/1000, stats.m/1000,
	       stddev(&stats)/1000, mb_per_sec(size, stats.m));
	free_shm();
}
예제 #14
0
파일: libs.c 프로젝트: clarkok/cript
static Value
_lib_foreach(VMState *vm, Value value)
{
    Hash *args = value_to_ptr(value);
    Hash *array = value_to_ptr(hash_find(args, 1));
    Value callback = hash_find(args, 2);

    for (size_t i = 0; i < hash_size(array); ++i) {
        Hash *cb_arg = cvm_create_array(vm, HASH_MIN_CAPACITY);

        cb_arg = cvm_set_hash(vm, cb_arg, 0, value_from_ptr(cvm_get_global(vm)));
        cb_arg = cvm_set_hash(vm, cb_arg, 1, hash_find(array, i));

        cvm_state_call_function(vm, callback, value_from_ptr(cb_arg));
    }

    return value_undefined();
}
예제 #15
0
파일: libs.c 프로젝트: clarkok/cript
static Value
_lib_print(VMState *vm, Value value)
{
    Hash *args = value_to_ptr(value);

    for (uintptr_t i = 1; i < hash_size(args); ++i) {
        Value val = hash_find(args, i);

        if (value_is_int(val)) {
            printf("%d", value_to_int(val));
        }
        else {
            CString *string = value_to_string(val);
            printf("%.*s", string->length, string->content);
        }
    }

    return value_undefined();
}
예제 #16
0
파일: frame.c 프로젝트: coweatyou/school
/* Randomly sellects a page to evict. */
struct frame *get_frame_for_eviction() {
	struct hash_iterator hi;
	struct hash_elem e;

  ASSERT(lock_held_by_current_thread(&ft_lock));

//	lock_acquire(&ft_lock);
	do {
		long index = random_ulong() % hash_size(&frame_table);
		hash_first(&hi, &frame_table);
		for(int i = 0; i < index; i++)
			hash_next(&hi);
	} while(!lock_try_acquire(&get_frame(hash_cur(&hi))->evicting));
	struct frame *f = get_frame(hash_cur(&hi));
	ASSERT(!f->page->deleting);
//	lock_release(&ft_lock);
	
  return f;
}
예제 #17
0
파일: libs.c 프로젝트: clarkok/cript
static Value
_lib_concat(VMState *vm, Value value)
{
    Hash *args = value_to_ptr(value);

    char buffer[256],
        *ptr = buffer;

    for (size_t i = 1; i < hash_size(args); ++i) {
        CString *string = value_to_string(hash_find(args, i));
        strncpy(ptr, string->content, 255 - (ptr - buffer));
        ptr += string->length;
        if (ptr - buffer >= 255) {
            ptr = buffer + 255;
            break;
        }
    }

    return value_from_string(string_pool_insert_vec(&vm->string_pool, buffer, ptr - buffer));
}
예제 #18
0
파일: frame.c 프로젝트: chutchUCD/OS
struct frame_table_entry* pick_frame_to_evict( uint32_t *pagedir )
{
  size_t n = hash_size(&frame_map);
  if(n == 0) PANIC("Frame table is empty, can't happen - there is a leak somewhere");

  size_t it;
  for(it = 0; it <= n + n; ++ it) // prevent infinite loop. 2n iterations is enough
  {
    struct frame_table_entry *e = clock_frame_next();
    // if pinned, continue
    if(e->pinned) continue;
    // if referenced, give a second chance.
    else if( pagedir_is_accessed(pagedir, e->upage)) {
      pagedir_set_accessed(pagedir, e->upage, false);
      continue;
    }

    // OK, here is the victim : unreferenced since its last chance
    return e;
  }

  PANIC ("Can't evict any frame -- Not enough memory!\n");
}
예제 #19
0
파일: cycle.c 프로젝트: cosinuz/ponyc
static size_t perceived_hash(perceived_t* per)
{
  return hash_size(per->token);
}
예제 #20
0
/*
 * Generate a section header cache made up of information derived
 * from the program headers.
 *
 * entry:
 *	file - Name of object
 *	fd - Open file handle for object
 *	elf - ELF descriptor
 *	ehdr - Elf header
 *	cache, shnum - Addresses of variables to receive resulting
 *		cache and number of sections.
 *
 * exit:
 *	On success, *cache and *shnum are set, and True (1) is returned.
 *	On failure, False (0) is returned.
 *
 * note:
 *	The cache returned by this routine must be freed using
 *	fake_shdr_cache_free(), and not by a direct call to free().
 *	Otherwise, memory will leak.
 */
int
fake_shdr_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr,
    Cache **cache, size_t *shnum)
{
	/*
	 * The C language guarantees that a structure of homogeneous
	 * items will receive exactly the same layout in a structure
	 * as a plain array of the same type. Hence, this structure, which
	 * gives us by-name or by-index access to the various section
	 * info descriptors we maintain.
	 *
	 * We use this for sections where
	 *	- Only one instance is allowed
	 *	- We need to be able to access them easily by
	 *		name (for instance, when mining the .dynamic
	 *		section for information to build them up.
	 *
	 * NOTE: These fields must be in the same order as the
	 * SINFO_T_ type codes that correspond to them. Otherwise,
	 * they will end up in the wrong order in the cache array,
	 * and the sh_link/sh_info fields may be wrong.
	 */
	struct {
		/* Note: No entry is needed for SINFO_T_NULL */
		SINFO	dyn;
		SINFO	dynstr;
		SINFO	dynsym;
		SINFO	ldynsym;

		SINFO	hash;
		SINFO	syminfo;
		SINFO	symsort;
		SINFO	tlssort;
		SINFO	verneed;
		SINFO	verdef;
		SINFO	versym;
		SINFO	interp;
		SINFO	cap;
		SINFO	capinfo;
		SINFO	capchain;
		SINFO	unwind;
		SINFO	move;
		SINFO	rel;
		SINFO	rela;
		SINFO	preinitarr;
		SINFO	initarr;
		SINFO	finiarr;
	} sec;
	static const size_t sinfo_n = sizeof (sec) / sizeof (sec.dyn);
	SINFO *secarr = (SINFO *) &sec;

	/*
	 * Doubly linked circular list, used to track sections
	 * where multiple sections of a given type can exist.
	 * seclist is the root of the list. Its sinfo field is not
	 * used --- it serves to anchor the root of the list, allowing
	 * rapid access to the first and last element in the list.
	 */
	SINFO_LISTELT	seclist;

	FSTATE		fstate;
	size_t		ndx;
	size_t		num_sinfo, num_list_sinfo;
	SINFO		*sinfo;
	SINFO_LISTELT	*sinfo_list;
	Cache		*_cache;


	fstate.file = file;
	fstate.fd = fd;
	fstate.ehdr = ehdr;
	if (elf_getphdrnum(elf, &fstate.phnum) == -1) {
		failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
		return (0);
	}
	if ((fstate.phdr = elf_getphdr(elf)) == NULL) {
		failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
		return (0);
	}

	bzero(&sec, sizeof (sec));	/* Initialize "by-name" sec info */
	seclist.next = seclist.prev = &seclist;	  /* Empty circular list */

	/*
	 * Go through the program headers and look for information
	 * we can use to synthesize section headers. By far the most
	 * valuable thing is a dynamic section, the contents of
	 * which point at all sections used by ld.so.1.
	 */
	for (ndx = 0; ndx < fstate.phnum; ndx++) {
		/*
		 * A program header with no file size does
		 * not have a backing section.
		 */
		if (fstate.phdr[ndx].p_filesz == 0)
			continue;


		switch (fstate.phdr[ndx].p_type) {
		default:
			/* Header we can't use. Move on to next one */
			continue;

		case PT_DYNAMIC:
			sec.dyn.type = SINFO_T_DYN;
			sinfo = &sec.dyn;
			break;

		case PT_INTERP:
			sec.interp.type = SINFO_T_INTERP;
			sinfo = &sec.interp;
			break;

		case PT_NOTE:
			if ((sinfo = sinfo_list_alloc(&fstate, &seclist)) ==
			    NULL)
				continue;
			sinfo->type = SINFO_T_NOTE;
			break;

		case PT_SUNW_UNWIND:
		case PT_SUNW_EH_FRAME:
			sec.unwind.type = SINFO_T_UNWIND;
			sinfo = &sec.unwind;
			break;

		case PT_SUNWCAP:
			sec.cap.type = SINFO_T_CAP;
			sinfo = &sec.cap;
			break;
		}

		/*
		 * Capture the position/extent information for
		 * the header in the SINFO struct set up by the
		 * switch statement above.
		 */
		sinfo->vaddr = fstate.phdr[ndx].p_vaddr;
		sinfo->offset = fstate.phdr[ndx].p_offset;
		sinfo->size = fstate.phdr[ndx].p_filesz;
	}

	/*
	 * If we found a dynamic section, look through it and
	 * gather information about the sections it references.
	 */
	if (sec.dyn.type == SINFO_T_DYN)
		(void) get_data(&fstate, &sec.dyn);
	if ((sec.dyn.type == SINFO_T_DYN) && (sec.dyn.data->d_buf != NULL)) {
		Dyn *dyn;
		for (dyn = sec.dyn.data->d_buf; dyn->d_tag != DT_NULL; dyn++) {
			switch (dyn->d_tag) {
			case DT_HASH:
				sec.hash.type = SINFO_T_HASH;
				sec.hash.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_STRTAB:
				sec.dynstr.type = SINFO_T_DYNSTR;
				sec.dynstr.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SYMTAB:
				sec.dynsym.type = SINFO_T_DYNSYM;
				sec.dynsym.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_RELA:
				sec.rela.type = SINFO_T_RELA;
				sec.rela.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_RELASZ:
				sec.rela.size = dyn->d_un.d_val;
				break;

			case DT_STRSZ:
				sec.dynstr.size = dyn->d_un.d_val;
				break;

			case DT_REL:
				sec.rel.type = SINFO_T_REL;
				sec.rel.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_RELSZ:
				sec.rel.size = dyn->d_un.d_val;
				break;

			case DT_INIT_ARRAY:
				sec.initarr.type = SINFO_T_INITARR;
				sec.initarr.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_INIT_ARRAYSZ:
				sec.initarr.size = dyn->d_un.d_val;
				break;

			case DT_FINI_ARRAY:
				sec.finiarr.type = SINFO_T_FINIARR;
				sec.finiarr.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_FINI_ARRAYSZ:
				sec.finiarr.size = dyn->d_un.d_val;
				break;

			case DT_PREINIT_ARRAY:
				sec.preinitarr.type = SINFO_T_PREINITARR;
				sec.preinitarr.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_PREINIT_ARRAYSZ:
				sec.preinitarr.size = dyn->d_un.d_val;
				break;

			case DT_SUNW_CAPINFO:
				sec.capinfo.type = SINFO_T_CAPINFO;
				sec.capinfo.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SUNW_CAPCHAIN:
				sec.capchain.type = SINFO_T_CAPCHAIN;
				sec.capchain.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SUNW_SYMTAB:
				sec.ldynsym.type = SINFO_T_LDYNSYM;
				sec.ldynsym.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SUNW_SYMSZ:
				sec.ldynsym.size = dyn->d_un.d_val;
				break;

			case DT_SUNW_SYMSORT:
				sec.symsort.type = SINFO_T_SYMSORT;
				sec.symsort.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SUNW_SYMSORTSZ:
				sec.symsort.size = dyn->d_un.d_val;
				break;

			case DT_SUNW_TLSSORT:
				sec.tlssort.type = SINFO_T_TLSSORT;
				sec.tlssort.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SUNW_TLSSORTSZ:
				sec.tlssort.size = dyn->d_un.d_val;
				break;

			case DT_MOVETAB:
				sec.move.type = SINFO_T_MOVE;
				sec.move.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_MOVESZ:
				sec.move.size = dyn->d_un.d_val;
				break;

			case DT_SYMINFO:
				sec.syminfo.type = SINFO_T_SYMINFO;
				sec.syminfo.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_SYMINSZ:
				sec.syminfo.size = dyn->d_un.d_val;
				break;

			case DT_VERSYM:
				sec.versym.type = SINFO_T_VERSYM;
				sec.versym.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_VERDEF:
				sec.verdef.type = SINFO_T_VERDEF;
				sec.verdef.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_VERDEFNUM:
				sec.verdef.vercnt = dyn->d_un.d_val;
				sec.verdef.size = sizeof (Verdef) *
				    dyn->d_un.d_val;
				break;

			case DT_VERNEED:
				sec.verneed.type = SINFO_T_VERNEED;
				sec.verneed.vaddr = dyn->d_un.d_ptr;
				break;

			case DT_VERNEEDNUM:
				sec.verneed.vercnt = dyn->d_un.d_val;
				sec.verneed.size = sizeof (Verneed) *
				    dyn->d_un.d_val;
				break;
			}
		}
	}

	/*
	 * Different sections depend on each other, and are meaningless
	 * without them. For instance, even if a .dynsym exists,
	 * no use can be made of it without a dynstr. These relationships
	 * fan out: Disqualifying the .dynsym will disqualify the hash
	 * section, and so forth.
	 *
	 * Disqualify sections that don't have the necessary prerequisites.
	 */

	/* Things that need the dynamic string table */
	if (sec.dynstr.size == 0)
		sec.dynstr.type = SINFO_T_NULL;
	if (sec.dynstr.type != SINFO_T_DYNSTR) {
		sinfo_free(&sec.dyn, 1);	/* Data already fetched */
		sec.dynsym.type =  SINFO_T_NULL;
		sec.dynsym.type =  SINFO_T_NULL;
		sec.verdef.type =  SINFO_T_NULL;
		sec.verneed.type =  SINFO_T_NULL;
	}

	/*
	 * The length of the hash section is encoded in its first two
	 * elements (nbucket, and nchain). The length of the dynsym,
	 * ldynsym, and versym are not given in the dynamic section,
	 * but are known to be the same as nchain.
	 *
	 * If we don't have a hash table, or cannot read nbuckets and
	 * nchain, we have to invalidate all of these.
	 */
	if (sec.hash.type == SINFO_T_HASH) {
		Word nbucket;
		Word nchain;
		size_t total;

		if (hash_size(&fstate, &sec.hash,
		    &nbucket, &nchain, &total) == 0) {
			sec.hash.type = SINFO_T_NULL;
		} else {
			/* Use these counts to set sizes for related sections */
			sec.hash.size = total * sizeof (Word);
			sec.dynsym.size = nchain * sizeof (Sym);
			sec.versym.size = nchain * sizeof (Versym);

			/*
			 * The ldynsym size received the DT_SUNW_SYMSZ
			 * value, which is the combined size of .dynsym
			 * and .ldynsym. Now that we have the dynsym size,
			 * use it to lower the ldynsym size to its real size.
			 */
			if (sec.ldynsym.size > sec.dynsym.size)
				sec.ldynsym.size  -= sec.dynsym.size;
		}
	}
	/*
	 * If the hash table is not present, or if the call to
	 * hash_size() failed, then discard the sections that
	 * need it to determine their length.
	 */
	if (sec.hash.type != SINFO_T_HASH) {
		sec.dynsym.type = SINFO_T_NULL;
		sec.ldynsym.type = SINFO_T_NULL;
		sec.versym.type = SINFO_T_NULL;
	}

	/*
	 * The runtime linker does not receive size information for
	 * Verdef and Verneed sections. We have to read their data
	 * in pieces and calculate it.
	 */
	if ((sec.verdef.type == SINFO_T_VERDEF) &&
	    (verdefneed_size(&fstate, &sec.verdef) == 0))
		sec.verdef.type = SINFO_T_NULL;
	if ((sec.verneed.type == SINFO_T_VERNEED) &&
	    (verdefneed_size(&fstate, &sec.verneed) == 0))
		sec.verneed.type = SINFO_T_NULL;

	/* Discard any section with a zero length */
	ndx = sinfo_n;
	for (sinfo = secarr; ndx-- > 0; sinfo++)
		if ((sinfo->type != SINFO_T_NULL) && (sinfo->size == 0))
			sinfo->type = SINFO_T_NULL;

	/* Things that need the dynamic symbol table */
	if (sec.dynsym.type != SINFO_T_DYNSYM) {
		sec.ldynsym.type = SINFO_T_NULL;
		sec.hash.type = SINFO_T_NULL;
		sec.syminfo.type = SINFO_T_NULL;
		sec.versym.type = SINFO_T_NULL;
		sec.move.type = SINFO_T_NULL;
		sec.rel.type = SINFO_T_NULL;
		sec.rela.type = SINFO_T_NULL;
	}

	/* Things that need the dynamic local symbol table */
	if (sec.ldynsym.type != SINFO_T_DYNSYM) {
		sec.symsort.type = SINFO_T_NULL;
		sec.tlssort.type = SINFO_T_NULL;
	}

	/*
	 * Look through the results and fetch the data for any sections
	 * we have found. At the same time, count the number.
	 */
	num_sinfo = num_list_sinfo = 0;
	ndx = sinfo_n;
	for (sinfo = secarr; ndx-- > 0; sinfo++) {
		if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL))
			(void) get_data(&fstate, sinfo);
		if (sinfo->data != NULL)
			num_sinfo++;
	}
	for (sinfo_list = seclist.next; sinfo_list != &seclist;
	    sinfo_list = sinfo_list->next) {
		sinfo = &sinfo_list->sinfo;
		if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL))
			(void) get_data(&fstate, sinfo);
		if (sinfo->data != NULL)
			num_list_sinfo++;
	}

	/*
	 * Allocate the cache array and fill it in. The cache array
	 * ends up taking all the dynamic memory we've allocated
	 * to build up sec and seclist, so on success, we have nothing
	 * left to clean up. If we can't allocate the cache array
	 * though, we have to free up everything else.
	 */
	*shnum = num_sinfo + num_list_sinfo + 1; /* Extra for 1st NULL sec. */
	if ((*cache = _cache = malloc((*shnum) * sizeof (Cache))) == NULL) {
		int err = errno;
		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
		    file, strerror(err));
		sinfo_free(secarr, num_sinfo);
		sinfo_list_free_all(&seclist);
		return (0);
	}
	*_cache = cache_init;
	_cache++;
	ndx = 1;
	for (sinfo = secarr; num_sinfo > 0; sinfo++) {
		if (sinfo->data != NULL) {
			_cache->c_scn = NULL;
			_cache->c_shdr = sinfo->shdr;
			_cache->c_data = sinfo->data;
			_cache->c_name = (char *)sinfo_data[sinfo->type].name;
			_cache->c_ndx = ndx++;
			_cache++;
			num_sinfo--;
		}
	}
	for (sinfo_list = seclist.next; num_list_sinfo > 0;
	    sinfo_list = sinfo_list->next) {
		sinfo = &sinfo_list->sinfo;
		if (sinfo->data != NULL) {
			_cache->c_scn = NULL;
			_cache->c_shdr = sinfo->shdr;
			_cache->c_data = sinfo->data;
			_cache->c_name = (char *)sinfo_data[sinfo->type].name;
			_cache->c_ndx = ndx++;
			_cache++;
			num_list_sinfo--;
		}
	}

	return (1);
}
예제 #21
0
/**
 * Need doxygen comment
 */
int		cmd_workspace()
{
  revmjob_t	*job;
  u_int		idx;
  u_int		index;
  char		logbuf[BUFSIZ];
  char		*nl;
  char		*time;
  elfshobj_t	*obj;
  char		**keys;
  int		keynbr;
  char		**loadedkeys;
  int		loadedkeynbr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  //printf("workspace argc %u \n", world.curjob->curcmd->argc);

  switch (world.curjob->curcmd->argc)
    {
      /* $ workspace */
    case 0:
      revm_output(" .::. Workspaces .::. \n");
      keys = hash_get_keys(&world.jobs, &keynbr);
      for (index = 0; index < keynbr; index++)
        {
          job = (revmjob_t *) hash_get(&world.jobs, keys[index]);
          if (revm_own_job(job))
            {
              time = ctime(&job->ws.createtime);
              nl = strchr(time, '\n');
              if (nl)
                *nl = 0x00;
              snprintf(logbuf, BUFSIZ - 1, " [%s] %s %c \n", keys[index],
                       time, (job->ws.active ? '*' : ' '));
              revm_output(logbuf);

              if (hash_size(&job->loaded))
                {
                  loadedkeys = hash_get_keys(&job->loaded, &loadedkeynbr);
                  for (idx = 0; idx < loadedkeynbr; idx++)
                    {
                      obj = hash_get(&job->loaded, loadedkeys[idx]);
                      snprintf(logbuf, BUFSIZ - 1, " \t %c %s \n",
                               (job->curfile == obj ? '*' : ' '), obj->name);
                      revm_output(logbuf);
                    }

                }
              else
                {
                  snprintf(logbuf, BUFSIZ - 1, " \t   No files\n");
                  revm_output(logbuf);
                }
            }
        }
      revm_output("\n");
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

      /* $ workspace name */
    case 1:
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__,
		   revm_create_new_workspace(revm_get_cur_job_parameter(0)));

      /* Unknown command format */
    default:
      PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Wrong arg number", -1);
    }
}
예제 #22
0
/** 
 * List all the loaded objects 
 */
int		cmd_dolist()
{
  elfshobj_t	*actual;
  int		index;
  char		*time;
  char		*nl;
  char		c;
  char		c2;
  char		logbuf[BUFSIZ];
  char		optbuf[BUFSIZ];
  char		**keys;
  int		keynbr;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  index = 1;

  /* Private descriptors */
  if (hash_size(&world.curjob->loaded))
    {
      revm_output(" .::. Static Working files .::. \n");
      keys = hash_get_keys(&world.curjob->loaded, &keynbr);
      for (index = 0; index < keynbr; index++)
	{
	  actual = hash_get(&world.curjob->loaded, keys[index]);
	  time = ctime(&actual->loadtime);
	  nl = strchr(time, '\n');
	  if (nl)
	    *nl = 0x00;
	  c = (world.curjob->curfile == actual ? '*' : ' ');
	  c2 = ((actual->linkmap || actual->rhdr.base) ? 'M' : ' ');
	  if (elfsh_is_runtime_mode())
	    snprintf(optbuf, BUFSIZ, "(" XFMT ")", actual->rhdr.base);
	  else
	    snprintf(optbuf, BUFSIZ, "%s", "");
	  
	  snprintf(logbuf, BUFSIZ - 1, " %s %c%c %s ID: %10u %s %-31s ", 
		   time, c, c2, optbuf, actual->id, 
		   elfsh_get_objtype(actual->hdr) == ET_REL  ? "ET_REL " : 
		   elfsh_get_objtype(actual->hdr) == ET_DYN  ? "ET_DYN " : 
		   elfsh_get_objtype(actual->hdr) == ET_EXEC ? "ET_EXEC" : 
		   elfsh_get_objtype(actual->hdr) == ET_CORE ? "ET_CORE" : 
		   "UNKNOWN", actual->name);
	  revm_output(logbuf);
	  revm_dolist_dep(actual);
	  revm_output("\n");

	  /* printf("-> Hashes for object : PAR[%u] ROOT[%u] CHILD[%u] \n",
	     hash_size(&actual->parent_hash),
	     hash_size(&actual->root_hash),
	     hash_size(&actual->child_hash));
	  */

	}
    }

  /* Shared descriptors */
  if (hash_size(&world.shared_hash))
    {
      revm_output("\n .::. Shared Working files .::. \n");
      keys = hash_get_keys(&world.shared_hash, &keynbr);
      for (index = 0; index < keynbr; index++)
	{
	  actual = hash_get(&world.shared_hash, keys[index]);
	  time = ctime(&actual->loadtime);
	  nl = strchr(time, '\n');
	  if (nl)
	    *nl = 0x00;
	  c = (world.curjob->curfile == actual ? '*' : ' ');
	  c2 = (actual->linkmap ? 'L' : ' ');
	  if (elfsh_is_runtime_mode())
	    snprintf(optbuf, BUFSIZ, "(" XFMT ")", actual->rhdr.base);
	  else
	    snprintf(optbuf, BUFSIZ, "%s", "");
	  
	  snprintf(logbuf, BUFSIZ - 1, " [%02u] %s %c%c %s ID: %02u %-31s \n", 
		   index + 1, time, c, c2, optbuf, actual->id, actual->name);
	  revm_output(logbuf);
	}
    }

  if (!hash_size(&world.curjob->loaded) && !hash_size(&world.shared_hash))
    revm_output(" [*] No loaded file\n");
  revm_output("\n");
  revm_modlist();
  revm_output("\n");
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}