FreeCalypso > hg > freecalypso-reveng
changeset 119:fb1e47bebe00
tiobjd: sorted profile output
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Apr 2014 05:11:32 +0000 |
parents | 193926ccd1ec |
children | 4d8dfdbd2ea1 |
files | ticoff/Makefile ticoff/profile.c ticoff/symtab.c |
diffstat | 3 files changed, 159 insertions(+), 57 deletions(-) [+] |
line wrap: on
line diff
--- a/ticoff/Makefile Thu Apr 03 07:47:03 2014 +0000 +++ b/ticoff/Makefile Fri Apr 04 05:11:32 2014 +0000 @@ -2,7 +2,7 @@ CFLAGS= -O2 PROG= tiobjd OBJS= armdis.o atcommon.o basics.o disasm.o globals.o lowlevel.o main.o \ - reloc.o symtab.o tables.o thumbdis.o + profile.o reloc.o symtab.o tables.o thumbdis.o HDRS= coffconst.h filestruct.h globals.h intstruct.h all: ${PROG}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ticoff/profile.c Fri Apr 04 05:11:32 2014 +0000 @@ -0,0 +1,158 @@ +/* + * 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); +}
--- a/ticoff/symtab.c Thu Apr 03 07:47:03 2014 +0000 +++ b/ticoff/symtab.c Fri Apr 04 05:11:32 2014 +0000 @@ -86,62 +86,6 @@ return(0); } -extern_profile_report(heading) - char *heading; -{ - unsigned n; - int first_extern = -1, last_extern; - struct internal_syment *sym; - int defs_started = 0; - - for (n = 0; n < nsymtab; n++) { - sym = symtab[n]; - if (!sym) - continue; - if (sym->class != C_EXT) - continue; - if (sym->scnum < 0) { - fprintf(stderr, - "symbol entry #%u: unexpected negative scnum for C_EXT\n", n); - exit(1); - } - if (sym->scnum == 0) { /* undef external ref */ - if (first_extern < 0) - first_extern = n; - last_extern = n; - continue; - } - if (!defs_started) { - printf("%s defines:\n\n", heading); - defs_started = 1; - } - printf("%s (%s)\n", sym->name, sym->section->name); - } - if (defs_started) - putchar('\n'); - if (first_extern < 0) - return(0); - printf("%s references:\n\n", heading); - for (n = first_extern; n <= last_extern; n++) { - sym = symtab[n]; - if (!sym) - continue; - if (sym->class != C_EXT || sym->scnum) - continue; - printf("%s\n", sym->name); - } - putchar('\n'); - return(0); -} - -cmd_profile() -{ - get_int_section_table(); - get_int_symbol_table(); - extern_profile_report(objfilename); - exit(0); -} - static void initial_fill_for_sort(sec) struct internal_scnhdr *sec;