FreeCalypso > hg > freecalypso-reveng
view leo-obj/tool/profile.c @ 193:37f78f986a0a
grokdsn: tree dump implemented
author | Michael Spacefalcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Wed, 07 Jan 2015 08:09:30 +0000 |
parents | 87b82398a08b |
children |
line wrap: on
line source
/* * It is handy to have a "profile" of what functions and variables * a given module defines (presents to the rest of the fw) and what * it references. This profile is constructed from the symbol table. * * Experience indicates that the order of these symbols in the * artifact symtab is often "random", and an alphabetic sort is * expected to improve readability. This module contains the * messy code. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "intstruct.h" #include "coffconst.h" #include "globals.h" static int is_symbol_text_def(sym) struct internal_syment *sym; { if (!sym->section) return(0); if (!strncmp(sym->section->name, ".text", 5)) return(1); else return(0); } static int is_symbol_nontext_def(sym) struct internal_syment *sym; { if (!sym->section) return(0); if (!strncmp(sym->section->name, ".text", 5)) return(0); else return(1); } static int is_symbol_extref(sym) struct internal_syment *sym; { if (sym->section) return(0); else return(1); } static int compare_for_sort(p1, p2) struct internal_syment **p1, **p2; { return strcmp((*p1)->name, (*p2)->name); } static void list_class(firstidx, lastidx, total, checkfunc, printsec) unsigned firstidx, lastidx, total; int (*checkfunc)(); { struct internal_syment **array, *sym; unsigned n, m; array = malloc(sizeof(void *) * total); if (!array) { perror("malloc"); exit(1); } m = 0; for (n = firstidx; n <= lastidx; n++) { sym = symtab[n]; if (!sym) continue; if (sym->class != C_EXT) continue; if (!checkfunc(sym)) continue; array[m++] = sym; } if (m != total) { fprintf(stderr, "BUG: symbol class miscount in profile gen\n"); exit(1); } qsort(array, total, sizeof(void *), compare_for_sort); for (n = 0; n < total; n++) { sym = array[n]; if (printsec) printf("%s (%s)\n", sym->name, sym->section->name); else printf("%s\n", sym->name); } free(array); putchar('\n'); } extern_profile_report(heading) char *heading; { unsigned n; int first_extern = -1, last_extern; struct internal_syment *sym; unsigned defs_text = 0, defs_nontext = 0, extrefs = 0; for (n = 0; n < nsymtab; n++) { sym = symtab[n]; if (!sym) continue; if (sym->class != C_EXT) continue; if (first_extern < 0) first_extern = n; last_extern = n; if (sym->scnum < 0) { fprintf(stderr, "symbol entry #%u: unexpected negative scnum for C_EXT\n", n); exit(1); } if (sym->scnum == 0) extrefs++; else if (!strncmp(sym->section->name, ".text", 5)) defs_text++; else defs_nontext++; } if (first_extern < 0) { printf("%s has no external symbols!\n", heading); return(1); } if (defs_text || defs_nontext) { printf("%s defines:\n\n", heading); if (defs_text) list_class(first_extern, last_extern, defs_text, is_symbol_text_def, 1); if (defs_nontext) list_class(first_extern, last_extern, defs_nontext, is_symbol_nontext_def, 1); } if (extrefs) { printf("%s references:\n\n", heading); list_class(first_extern, last_extern, extrefs, is_symbol_extref, 0); } return(0); } cmd_profile() { get_int_section_table(); get_int_symbol_table(); extern_profile_report(objfilename); exit(0); }