void printSymTab() { int i, j; symtab *new_table; printf("----- Symbol Table ---------\n"); new_table = (symtab*) malloc(num_id*sizeof(symtab)); j=0; for (i=0; i<TABLE_SIZE; i++) { symtab* symptr; symptr = hash_table[i]; while (symptr != NULL) { /* Add to new table */ new_table[j++]=*symptr; symptr=symptr->front; } } /* Sort */ qsort(new_table, num_id, sizeof(symtab), cmp); /* Print the new table */ for(i=0; i<num_id; i++) { printf("====> index = %d \n", i); printSym(&new_table[i]); } }
void printSymtab ( void ) { Int i; VG_(printf)("\n------ BEGIN vg_symtab ------\n"); for (i = 0; i < vg_symtab_used; i++) printSym(i); VG_(printf)("------ BEGIN vg_symtab ------\n"); }
void printSymTab() { int i; printf("----- Symbol Table ---------\n"); for (i=0; i<TABLE_SIZE; i++) { symtab* symptr; symptr = hash_table[i]; while (symptr != NULL) { printf("====> index = %d \n", i); printSym(symptr); symptr=symptr->front; } } }
int main(int argc, char ** argv) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " (input file)" << std::endl; return EXIT_FAILURE; } uint64_t * counts = readFrequencies(argv[1]); assert(counts != NULL); for (unsigned i = 0; i < 257; i++) { if (counts[i] == 0) { continue; } printSym(std::cout, i); std::cout << ": " << counts[i] << std::endl; } delete[] counts; return EXIT_SUCCESS; }
/* Sort the symtab by starting address, and emit warnings if any symbols have overlapping address ranges. We use that old chestnut, shellsort. Mash the table around so as to establish the property that addresses are in order and the ranges to not overlap. This facilitates using binary search to map addresses to symbols when we come to query the table. */ static void canonicaliseSymtab ( SegInfo* si ) { /* Magic numbers due to Janet Incerpi and Robert Sedgewick. */ Int incs[16] = { 1, 3, 7, 21, 48, 112, 336, 861, 1968, 4592, 13776, 33936, 86961, 198768, 463792, 1391376 }; Int lo = 0; Int hi = si->symtab_used-1; Int i, j, h, bigN, hp, n_merged, n_truncated; RiSym v; Addr s1, s2, e1, e2; # define SWAP(ty,aa,bb) \ do { ty tt = (aa); (aa) = (bb); (bb) = tt; } while (0) bigN = hi - lo + 1; if (bigN < 2) return; hp = 0; while (hp < 16 && incs[hp] < bigN) hp++; hp--; vg_assert(0 <= hp && hp < 16); for (; hp >= 0; hp--) { h = incs[hp]; i = lo + h; while (1) { if (i > hi) break; v = si->symtab[i]; j = i; while (si->symtab[j-h].addr > v.addr) { si->symtab[j] = si->symtab[j-h]; j = j - h; if (j <= (lo + h - 1)) break; } si->symtab[j] = v; i++; } } cleanup_more: /* If two symbols have identical address ranges, favour the one with the longer name. */ do { n_merged = 0; j = si->symtab_used; si->symtab_used = 0; for (i = 0; i < j; i++) { if (i < j-1 && si->symtab[i].addr == si->symtab[i+1].addr && si->symtab[i].size == si->symtab[i+1].size) { n_merged++; /* merge the two into one */ if (VG_(strlen)(&si->strtab[si->symtab[i].nmoff]) > VG_(strlen)(&si->strtab[si->symtab[i+1].nmoff])) { si->symtab[si->symtab_used++] = si->symtab[i]; } else { si->symtab[si->symtab_used++] = si->symtab[i+1]; } i++; } else { si->symtab[si->symtab_used++] = si->symtab[i]; } } if (VG_(clo_trace_symtab)) VG_(printf)( "%d merged\n", n_merged); } while (n_merged > 0); /* Detect and "fix" overlapping address ranges. */ n_truncated = 0; for (i = 0; i < si->symtab_used-1; i++) { vg_assert(si->symtab[i].addr <= si->symtab[i+1].addr); /* Check for common (no overlap) case. */ if (si->symtab[i].addr + si->symtab[i].size <= si->symtab[i+1].addr) continue; /* There's an overlap. Truncate one or the other. */ if (VG_(clo_trace_symtab)) { VG_(printf)("overlapping address ranges in symbol table\n\t"); printSym(si,i); VG_(printf)("\t"); printSym(si,i+1); VG_(printf)("\n"); } /* Truncate one or the other. */ s1 = si->symtab[i].addr; s2 = si->symtab[i+1].addr; e1 = s1 + si->symtab[i].size - 1; e2 = s2 + si->symtab[i+1].size - 1; if (s1 < s2) { e1 = s2-1; } else { vg_assert(s1 == s2); if (e1 > e2) { s1 = e2+1; SWAP(Addr,s1,s2); SWAP(Addr,e1,e2); } else if (e1 < e2) { s2 = e1+1; } else { /* e1 == e2. Identical addr ranges. We'll eventually wind up back at cleanup_more, which will take care of it. */ } } si->symtab[i].addr = s1; si->symtab[i+1].addr = s2; si->symtab[i].size = e1 - s1 + 1; si->symtab[i+1].size = e2 - s2 + 1; vg_assert(s1 <= s2); vg_assert(si->symtab[i].size > 0); vg_assert(si->symtab[i+1].size > 0); /* It may be that the i+1 entry now needs to be moved further along to maintain the address order requirement. */ j = i+1; while (j < si->symtab_used-1 && si->symtab[j].addr > si->symtab[j+1].addr) { SWAP(RiSym,si->symtab[j],si->symtab[j+1]); j++; } n_truncated++; } if (n_truncated > 0) goto cleanup_more; /* Ensure relevant postconditions hold. */ for (i = 0; i < si->symtab_used-1; i++) { /* No zero-sized symbols. */ vg_assert(si->symtab[i].size > 0); /* In order. */ vg_assert(si->symtab[i].addr < si->symtab[i+1].addr); /* No overlaps. */ vg_assert(si->symtab[i].addr + si->symtab[i].size - 1 < si->symtab[i+1].addr); } # undef SWAP }