FreeCalypso > hg > freecalypso-reveng
diff leo-obj/tool/symtab.c @ 130:87b82398a08b
leo-obj project subtree started, tiobjd tool moved into it
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 06 Apr 2014 22:14:39 +0000 |
parents | ticoff/symtab.c@fb1e47bebe00 |
children | ed533d469838 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/leo-obj/tool/symtab.c Sun Apr 06 22:14:39 2014 +0000 @@ -0,0 +1,185 @@ +/* + * Code for working with the symbol table + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include "filestruct.h" +#include "intstruct.h" +#include "coffconst.h" +#include "globals.h" + +static struct classmap { + int code; + char *str; +} classtab[] = { + {C_NULL, "NULL"}, + {C_AUTO, "AUTO"}, + {C_EXT, "EXT"}, + {C_STAT, "STAT"}, + {C_REG, "REG"}, + {C_EXTREF, "EXTREF"}, + {C_LABEL, "LABEL"}, + {C_ULABEL, "ULABEL"}, + {C_MOS, "MOS"}, + {C_ARG, "ARG"}, + {C_STRTAG, "STRTAG"}, + {C_MOU, "MOU"}, + {C_UNTAG, "UNTAG"}, + {C_TPDEF, "TPDEF"}, + {C_USTATIC, "USTATIC"}, + {C_ENTAG, "ENTAG"}, + {C_MOE, "MOE"}, + {C_REGPARM, "REGPARM"}, + {C_FIELD, "FIELD"}, + {C_UEXT, "UEXT"}, + {C_STATLAB, "STATLAB"}, + {C_EXTLAB, "EXTLAB"}, + {C_SYSTEM, "SYSTEM"}, + {C_VARARG, "VARARG"}, + {C_BLOCK, "BLOCK"}, + {C_FCN, "FCN"}, + {C_EOS, "EOS"}, + {C_FILE, "FILE"}, + {C_LINE, "LINE"}, + {0, 0} +}; + +char * +storage_class_to_string(code, numbuf) + char *numbuf; +{ + struct classmap *tp; + + for (tp = classtab; tp->str; tp++) + if (tp->code == code) + return(tp->str); + sprintf(numbuf, "%d", code); + return(numbuf); +} + +dump_symtab() +{ + unsigned n; + struct internal_syment *sym; + char *sec, secstr[8]; + char *class, classbuf[8]; + + printf("%-5s %-30s %-4s %-7s %-12s %-8s\n", + "Num", "Name", "Type", "Class", "Section", "Value"); + for (n = 0; n < nsymtab; n++) { + sym = symtab[n]; + if (!sym) + continue; + if (sym->section) + sec = sym->section->name; + else { + sprintf(secstr, "%d", sym->scnum); + sec = secstr; + } + class = storage_class_to_string(sym->class, classbuf); + printf("%-5u %-30s %04X %-7s %-12s %08X%s\n", + n, sym->name, sym->type, class, + sec, sym->value, sym->aux ? " Aux" : ""); + } + return(0); +} + +static void +initial_fill_for_sort(sec) + struct internal_scnhdr *sec; +{ + unsigned n, m; + struct internal_syment *sym; + + m = 0; + for (n = 0; n < nsymtab; n++) { + sym = symtab[n]; + if (!sym) + continue; + if (sym->section != sec) + continue; + sec->sorted_symbols[m++] = sym; + } +} + +static int +compare_for_sort(p1, p2) + struct internal_syment **p1, **p2; +{ + /* sort by value first */ + if ((*p1)->value < (*p2)->value) + return(-1); + if ((*p1)->value > (*p2)->value) + return(1); + /* if same value, retain the original symtab order */ + if ((*p1)->number < (*p2)->number) + return(-1); + if ((*p1)->number > (*p2)->number) + return(1); + else + return(0); +} + +void +sort_symbols_of_sec(sec) + struct internal_scnhdr *sec; +{ + if (sec->sorted_symbols) + return; + if (!sec->nsymbols) { + fprintf(stderr, + "BUG: sort_symbols_of_sec() called for section \"%s\" w/o symbols\n", + sec->name); + exit(1); + } + sec->sorted_symbols = malloc(sizeof(void *) * sec->nsymbols); + if (!sec->sorted_symbols) { + perror("malloc"); + exit(1); + } + initial_fill_for_sort(sec); + qsort(sec->sorted_symbols, sec->nsymbols, sizeof(void *), + compare_for_sort); +} + +void +sort_symbols_of_all_sec() +{ + unsigned n; + struct internal_scnhdr *sec; + + for (n = 0; n < nsections; n++) { + sec = sections + n; + if (!sec->nsymbols) + continue; + sort_symbols_of_sec(sec); + } +} + +cmd_nm() +{ + unsigned n, m; + struct internal_scnhdr *sec; + struct internal_syment *sym; + char classbuf[8]; + + get_int_section_table(); + get_int_symbol_table(); + for (n = 0; n < nsections; n++) { + sec = sections + n; + if (!sec->nsymbols) + continue; + printf("%s:\n\n", sec->name); + sort_symbols_of_sec(sec); + for (m = 0; m < sec->nsymbols; m++) { + sym = sec->sorted_symbols[m]; + printf("%08X %-7s %s\n", sym->value, + storage_class_to_string(sym->class, classbuf), + sym->name); + } + putchar('\n'); + } + exit(0); +}