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;