shithub: scc

Download patch

ref: aaabcfa788b098048d80c6e7e89cb78c408071d6
parent: 298d40ee45af86e00de6cd59f9cd27a0762e295a
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Mar 5 10:21:28 EST 2018

[nm] Split main.c in common and object part

This is the first step to be able to have ar working with
different file formats.

--- a/nm/Makefile
+++ b/nm/Makefile
@@ -5,14 +5,16 @@
 include $(PROJECTDIR)/rules.mk
 include $(LIBDIR)/libdep.mk
 
-OBJ       = main.o
+OBJ       = main.o myro.o
 
 all: nm
 
+main.o: $(INCDIR)/scc.h $(INCDIR)/ar.h $(INCDIR)/arg.h
+main.o: nm.h
+myro.o: $(INCDIR)/scc.h $(INCDIR)/myro.h nm.h
+
 nm: $(OBJ) $(LIBDIR)/libscc.a
 	$(CC) $(SCC_LDFLAGS) $(OBJ) -lscc -o $@
-
-main.o: $(PROJECTDIR)/inc/scc.h $(PROJECTDIR)/inc/ar.h $(PROJECTDIR)/inc/myro.h
 
 $(LIBDIR)/libscc.a: $(LIB-OBJ)
 	+cd $(LIBDIR) && $(MAKE)
--- a/nm/main.c
+++ b/nm/main.c
@@ -10,35 +10,19 @@
 
 #include "../inc/arg.h"
 #include "../inc/scc.h"
-#include "../inc/myro.h"
 #include "../inc/ar.h"
+#include "nm.h"
 
 char *argv0;
-char *strings;
-static int radix = 16;
-static int Pflag;
-static int Aflag;
-static int vflag;
-static int gflag;
-static int uflag;
-static int arflag;
+int radix = 16;
+int Pflag;
+int Aflag;
+int vflag;
+int gflag;
+int uflag;
+int arflag;
 
 static int
-object(char *fname, FILE *fp)
-{
-	char magic[MYROMAGIC_SIZ];
-	fpos_t pos;
-
-	fgetpos(fp, &pos);
-	fread(magic, sizeof(magic), 1, fp);
-	fsetpos(fp, &pos);
-
-	if (!ferror(fp) && !strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ))
-		return 1;
-	return 0;
-}
-
-static int
 archive(char *fname, FILE *fp)
 {
 	char magic[SARMAG];
@@ -53,51 +37,43 @@
 	return 0;
 }
 
-static int
-cmp(const void *p1, const void *p2)
+static void
+ar(char *fname, FILE *fp)
 {
-	const struct myrosym *s1 = p1, *s2 = p2;
+	struct ar_hdr hdr;
+	long pos, siz;
 
-	if (vflag)
-		return s1->offset - s2->offset;
-	else
-		return strcmp(strings + s1->name, strings + s2->name);
-}
+	arflag = 1;
+	fseek(fp, sizeof(struct ar_hdr), SEEK_CUR);
 
-static int
-typeof(struct myrosym *sym)
-{
-	int t, flags = sym->flags;
+	while (fread(&hdr, sizeof(hdr), 1, fp) == 1) {
+		pos = ftell(fp);
+		sscanf(hdr.ar_size, "%10ld", &siz);
+		if (pos == -1 || pos > LONG_MAX - siz) {
+			fprintf(stderr,
+			        "nm: %s: overflow in size of archive\n",
+			        fname);
+			return;
+		}
+		pos += siz;
+		if (siz & 1)
+			++pos;
 
-	switch (sym->section) {
-	case MYRO_TEXT:
-		t = 't';
-		break;
-	case MYRO_DATA:
-		t = 'd';
-		break;
-	case MYRO_BSS:
-		t = (flags & MYROSYM_COMMON) ? 'c' : 'b';
-		break;
-	case MYRO_ABS:
-		t = 'a';
-		break;
-	default:
-		t = (flags & MYROSYM_UNDEF) ? 'u' : '?';
-		break;
+		if (object(fname, fp)) {
+			nm(fname, hdr.ar_name, fp);
+		} else {
+			fprintf(stderr,
+			        "nm: skipping member %s in archive %s\n",
+			        hdr.ar_name, fname);
+		}
+		fseek(fp, pos, SEEK_SET);
 	}
-	if (flags & MYROSYM_ABS)
-		t = 'a';
-	if (flags & MYROSYM_EXTERN)
-		t = tolower(t);
-	return t;
 }
 
-static void
-print(char *file, char *member, struct myrosym *sym)
+void
+print(char *file, char *member, char *name, int type, unsigned long long off, long siz)
 {
-	char *fmt, *name = strings + sym->name;
-	int type = typeof(sym);
+	char *fmt;
 
 	if (uflag && type != 'U')
 		return;
@@ -115,7 +91,7 @@
 				fmt = "%llu %llu";
 			else
 				fmt = "%llx %llx";
-			printf(fmt, sym->offset, sym->len);
+			printf(fmt, off, siz);
 		}
 	} else {
 		if (type == 'U')
@@ -126,109 +102,12 @@
 			fmt = "%016.16lld";
 		else
 			fmt = "%016.16llx";
-		printf(fmt, sym->offset);
+		printf(fmt, off);
 		printf(" %c %s", type, name);
 	}
 	putchar('\n');
 }
 
-static void
-nm(char *fname, char *member, FILE *fp)
-{
-	struct myrohdr hdr;
-	struct myrosym *syms = NULL;
-	size_t n, i;
-	long off;
-
-	strings = NULL;
-	if (rdmyrohdr(fp, &hdr) < 0) {
-		fprintf(stderr, "nm: %s: incorrect header\n", member);
-		return;
-	}
-
-	n = hdr.symsize / MYROSYM_SIZ;
-	if (n == 0) {
-		fprintf(stderr, "nm: %s: no name list\n", member);
-		return;
-	}
-	if (n > SIZE_MAX / sizeof(struct myrosym) ||
-	    hdr.symsize / MYROSYM_SIZ > SIZE_MAX ||
-	    hdr.strsize > SIZE_MAX) {
-		goto offset_overflow;
-	}
-
-	syms = xmalloc(n * sizeof(struct myrosym));
-	strings = xmalloc(hdr.strsize);
-	fread(strings, hdr.strsize, 1, fp);
-	if (feof(fp))
-		goto free_arrays;
-	if ((off = ftell(fp)) < 0)
-		return;
-	if (off > LONG_MAX - hdr.secsize)
-		goto offset_overflow;
-	off += hdr.secsize;
-
-	if (fseek(fp, off, SEEK_SET) < 0)
-		goto free_arrays;
-
-	for (i = 0; i < n; ++i) {
-		if (rdmyrosym(fp, &syms[i]) < 0)
-			goto symbol_error;
-		if (syms[i].name >= hdr.strsize)
-			goto offset_overflow;
-	}
-	qsort(syms, n, sizeof(*syms), cmp);
-	for (i = 0; i < n; ++i)
-		print(fname, member, &syms[i]);
-
-
-free_arrays:
-	free(syms);
-	free(strings);
-	return;
-
-symbol_error:
-	fprintf(stderr, "nm: %s: error reading symbols\n", fname);
-	goto free_arrays;
-
-offset_overflow:
-	fprintf(stderr, "nm: %s: overflow in headers of archive\n",
-		fname);
-	goto free_arrays;
-}
-
-static void
-ar(char *fname, FILE *fp)
-{
-	struct ar_hdr hdr;
-	long pos, siz;
-
-	arflag = 1;
-	fseek(fp, sizeof(struct ar_hdr), SEEK_CUR);
-
-	while (fread(&hdr, sizeof(hdr), 1, fp) == 1) {
-		pos = ftell(fp);
-		sscanf(hdr.ar_size, "%10ld", &siz);
-		if (pos == -1 || pos > LONG_MAX - siz) {
-			fprintf(stderr,
-			        "nm: %s: overflow in size of archive\n",
-			        fname);
-			return;
-		}
-		pos += siz;
-		if (siz & 1)
-			++pos;
-
-		if (object(fname, fp)) {
-			nm(fname, hdr.ar_name, fp);
-		} else {
-			fprintf(stderr,
-			        "nm: skipping member %s in archive %s\n",
-			        hdr.ar_name, fname);
-		}
-		fseek(fp, pos, SEEK_SET);
-	}
-}
 
 void
 doit(char *fname)
--- /dev/null
+++ b/nm/myro.c
@@ -1,0 +1,141 @@
+static char sccsid[] = "@(#) ./nm/myro.c";
+
+#include <ctype.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../inc/scc.h"
+#include "../inc/myro.h"
+#include "nm.h"
+
+static char *strings;
+
+static int
+typeof(struct myrosym *sym)
+{
+	int t, flags = sym->flags;
+
+	switch (sym->section) {
+	case MYRO_TEXT:
+		t = 't';
+		break;
+	case MYRO_DATA:
+		t = 'd';
+		break;
+	case MYRO_BSS:
+		t = (flags & MYROSYM_COMMON) ? 'c' : 'b';
+		break;
+	case MYRO_ABS:
+		t = 'a';
+		break;
+	default:
+		t = (flags & MYROSYM_UNDEF) ? 'u' : '?';
+		break;
+	}
+	if (flags & MYROSYM_ABS)
+		t = 'a';
+	if (flags & MYROSYM_EXTERN)
+		t = tolower(t);
+	return t;
+}
+
+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);
+}
+
+void
+nm(char *fname, char *member, FILE *fp)
+{
+	struct myrohdr hdr;
+	struct myrosym *syms = NULL, *sym;
+	size_t n, i;
+	long off;
+
+	strings = NULL;
+	if (rdmyrohdr(fp, &hdr) < 0) {
+		fprintf(stderr, "nm: %s: incorrect header\n", member);
+		return;
+	}
+
+	n = hdr.symsize / MYROSYM_SIZ;
+	if (n == 0) {
+		fprintf(stderr, "nm: %s: no name list\n", member);
+		return;
+	}
+	if (n > SIZE_MAX / sizeof(struct myrosym) ||
+	    hdr.symsize / MYROSYM_SIZ > SIZE_MAX ||
+	    hdr.strsize > SIZE_MAX) {
+		goto offset_overflow;
+	}
+
+	syms = xmalloc(n * sizeof(struct myrosym));
+	strings = xmalloc(hdr.strsize);
+	fread(strings, hdr.strsize, 1, fp);
+	if (feof(fp))
+		goto free_arrays;
+	if ((off = ftell(fp)) < 0)
+		return;
+	if (off > LONG_MAX - hdr.secsize)
+		goto offset_overflow;
+	off += hdr.secsize;
+
+	if (fseek(fp, off, SEEK_SET) < 0)
+		goto free_arrays;
+
+	for (i = 0; i < n; ++i) {
+		if (rdmyrosym(fp, &syms[i]) < 0)
+			goto symbol_error;
+		if (syms[i].name >= hdr.strsize)
+			goto offset_overflow;
+	}
+	qsort(syms, n, sizeof(*syms), cmp);
+	for (i = 0; i < n; ++i) {
+		sym = &sym[i];
+		print(fname,
+		      member,
+		      strings + sym->name,
+		      typeof(sym),
+		      sym->offset,
+		      sym->len);
+	}
+
+free_arrays:
+	free(syms);
+	free(strings);
+	return;
+
+symbol_error:
+	fprintf(stderr, "nm: %s: error reading symbols\n", fname);
+	goto free_arrays;
+
+offset_overflow:
+	fprintf(stderr, "nm: %s: overflow in headers of archive\n",
+		fname);
+	goto free_arrays;
+}
+
+int
+object(char *fname, FILE *fp)
+{
+	char magic[MYROMAGIC_SIZ];
+	fpos_t pos;
+
+	fgetpos(fp, &pos);
+	fread(magic, sizeof(magic), 1, fp);
+	fsetpos(fp, &pos);
+
+	if (!ferror(fp) && !strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ))
+		return 1;
+	return 0;
+}
+
--- /dev/null
+++ b/nm/nm.h
@@ -1,0 +1,15 @@
+
+/* main.c */
+extern void print(char *file, char *member, char *name, int type, unsigned long long off, long siz);
+
+/* object format file */
+extern void nm(char *fname, char *member, FILE *fp);
+extern int object(char *fname, FILE *fp);
+
+extern int radix;
+extern int Pflag;
+extern int Aflag;
+extern int vflag;
+extern int gflag;
+extern int uflag;
+extern int arflag;
--- a/rules.mk
+++ b/rules.mk
@@ -1,5 +1,7 @@
 include $(PROJECTDIR)/config.mk
 
+INCDIR  = $(PROJECTDIR)/inc/
+
 SCC_CFLAGS = $(MOREFLAGS) \
              $(SYSCFLAGS) \
              -g \