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);
+}