/// 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(); }
/// 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(); }
// 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); }
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); }
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++; }
/** * 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); }
/** * @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])); }
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 *)); }
/** * 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])); }
/** * 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; }
/* 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); }
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"); }
/* 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(); }
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(); }
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(); }
/* 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; }
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)); }
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"); }
static size_t perceived_hash(perceived_t* per) { return hash_size(per->token); }
/* * 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); }
/** * 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); } }
/** * 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); }