ref: aaabcfa788b098048d80c6e7e89cb78c408071d6
parent: 298d40ee45af86e00de6cd59f9cd27a0762e295a
author: Roberto E. Vargas Caballero <[email protected]>
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 \