shithub: scc

Download patch

ref: 9b62b35493ec9d39704ca6c9a9e133a2f8e980fc
parent: 7d9ec5573f3348f6d9c26c5eb6945f880d1488f5
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Nov 25 04:39:22 EST 2017

[nm] Add print() function

This function prints all the information needed in nm. It is a first
proposal and bugs are expected.

--- a/nm/main.c
+++ b/nm/main.c
@@ -13,6 +13,7 @@
 #include "../inc/ar.h"
 
 char *argv0;
+char *strings;
 int radix = 16;
 int Pflag;
 int Aflag;
@@ -55,15 +56,71 @@
 	return 0;
 }
 
+static int
+cmp(const void *p1, const void *p2)
+{
+	const struct myrosym *s1 = p1, *s2 = p2;
+
+	if (vflag)
+		return s1->offset - s2->offset;
+	else
+		return strcmp(strings + s1->name, strings + s2->name);
+}
+
+static int
+typeof(struct myrosym *sym)
+{
+	return 'U';
+}
+
 static void
+print(char *member, struct myrosym *sym, FILE *fp)
+{
+	char *fmt, *name = strings + sym->name;
+	int type = typeof(sym);
+
+	if (uflag && type != 'U')
+		return;
+	if (gflag && type != 'A' && type != 'B' && type != 'D')
+		return;
+
+	if (Aflag)
+		fprintf(fp, "%s: ", member);
+	if (Pflag) {
+		fprintf(fp, "%s %c", name, type);
+		if (type != 'U') {
+			if (radix == 8)
+				fmt = "%llo %llo";
+			else if (radix == 10)
+				fmt = "%llu %llu";
+			else
+				fmt = "%llx %llx";
+			fprintf(fp, fmt, sym->offset, sym->len);
+		}
+	} else {
+		if (type == 'U')
+			fmt = "                ";
+		else if (radix == 8)
+			fmt = "%016.16llo";
+		else if (radix == 8)
+			fmt = "%016.16lld";
+		else
+			fmt = "%016.16llx";
+		fprintf(fp, fmt, sym->offset);
+		fprintf(fp, " %c %s", type, name);
+	}
+	putc('\n', fp);
+}
+
+static void
 nm(char *fname, char *member, FILE *fp)
 {
 	struct myrohdr hdr;
 	struct myrosym *syms = NULL;
-	char *strings = NULL;
 	size_t n, i;
 	long off;
 
+	strings = NULL;
 	if (rdmyrohdr(fp, &hdr) < 0) {
 		fprintf(stderr, "nm: %s: incorrect header\n", member);
 		return;
@@ -94,11 +151,17 @@
 	if (fseek(fp, off, SEEK_SET) < 0)
 		goto free_arrays;
 
-	for (i = 0; n--; ++i) {
+	for (i = 0; i < n; ++i) {
 		if (rdmyrosym(fp, &syms[i]) < 0)
 			goto free_arrays;
+		if (syms[i].name >= hdr.strsize)
+			goto offset_overflow;
 	}
+	qsort(syms, n, sizeof(*syms), cmp);
+	for (i = 0; i < n; ++i)
+		print(member, &syms[i], fp);
 
+
 free_arrays:
 	free(syms);
 	free(strings);
@@ -174,6 +237,9 @@
 	char *t;
 
 	ARGBEGIN {
+	case 'P':
+		Pflag = 1;
+		break;
 	case 'A':
 		Aflag = 1;
 		break;