ref: c32c0377e6dfe16c281b3f72bd6264054f2aba35
parent: 8336b733717f4fc2cf5ccf6647f1718760fc1bc8
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jan 7 14:00:58 EST 2019
Create cmd directory These directory is intended for all the tools with only one source file.
--- a/scripts/rules.mk
+++ b/scripts/rules.mk
@@ -36,6 +36,9 @@
cd $$pwd; \
done
+.o:
+ $(CC) $(SCC_LDFLAGS) -o $@ $< $(LIBS)
+
.s.o:
$(AS) $< -o $@
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@
PROJECTDIR = ..
include $(PROJECTDIR)/scripts/rules.mk
-TOOLS = cc1 cc2 ld as nm objdump ar
+TOOLS = cc1 cc2 ld as objdump ar cmd
LIBS = libscc libc libcrt libmach
DIRS = $(TOOLS) $(LIBS)
--- /dev/null
+++ b/src/cmd/.gitignore
@@ -1,0 +1,1 @@
+nm
--- /dev/null
+++ b/src/cmd/Makefile
@@ -1,0 +1,20 @@
+.POSIX:
+
+PROJECTDIR = ../..
+include $(PROJECTDIR)/scripts/rules.mk
+
+TARGET = $(BINDIR)/nm
+LIBS = -lmach
+
+all: $(TARGET)
+
+nm: $(LIBDIR)/libmach.a
+$(BINDIR)/nm: nm
+ cp nm $@
+
+clean:
+ rm -f nm
+
+dep: inc-dep
+
+include deps.mk
--- /dev/null
+++ b/src/cmd/deps.mk
@@ -1,0 +1,3 @@
+#deps
+nm.o: $(INCDIR)/scc/scc/arg.h
+nm.o: $(INCDIR)/scc/scc/mach.h
--- /dev/null
+++ b/src/cmd/nm.c
@@ -1,0 +1,272 @@
+static char sccsid[] = "@(#) ./nm/main.c";
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/arg.h>
+#include <scc/mach.h>
+
+
+struct symtbl {
+ Symbol **buf;
+ size_t nsyms;
+};
+
+char *argv0;
+static int status, multi;
+static int radix = 16;
+static int Pflag;
+static int Aflag;
+static int vflag;
+static int gflag;
+static int uflag;
+static char *filename, *membname;
+
+static void
+error(char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ fprintf(stderr, "nm: %s: ", filename);
+ if (membname)
+ fprintf(stderr, "%s: ", membname);
+ vfprintf(stderr, fmt, va);
+ putc('\n', stderr);
+ va_end(va);
+
+ status = EXIT_FAILURE;
+}
+
+static int
+cmp(const void *p1, const void *p2)
+{
+ Symbol **s1 = (Symbol **) p1, **s2 = (Symbol **) p2;
+ Symbol *sym1 = *s1, *sym2 = *s2;
+
+ if (vflag) {
+ if (sym1->value > sym2->value)
+ return 1;
+ if (sym1->value < sym2->value)
+ return -1;
+ if (sym1->type == 'U' && sym2->type == 'U')
+ return 0;
+ if (sym1->type == 'U')
+ return -1;
+ if (sym2->type == 'U')
+ return 1;
+ return 0;
+ } else {
+ return strcmp(sym1->name, sym2->name);
+ }
+}
+
+static void
+printsyms(Symbol **syms, size_t nsym)
+{
+ size_t i;
+
+ qsort(syms, nsym, sizeof(syms), cmp);
+
+ if (multi)
+ printf("%s:\n", (membname) ? membname : filename);
+
+ for (i = 0; i < nsym; i++) {
+ Symbol *sym = syms[i];
+ int type = sym->type;
+ char *fmt;
+
+ if (Aflag) {
+ fmt = (membname) ? "%s[%s]: " : "%s: ";
+ printf(fmt, filename, membname);
+ }
+
+ if (Pflag) {
+ printf("%s %c", sym->name, sym->type);
+ if (type != 'U') {
+ if (radix == 8)
+ fmt = " %016.16llo %lo";
+ else if (radix == 10)
+ fmt = " %016.16llu %lu";
+ else
+ fmt = " %016.16llx %lx";
+ printf(fmt, sym->value, sym->size);
+ }
+ } else {
+ if (type == 'U')
+ fmt = " ";
+ else if (radix == 8)
+ fmt = "%016.16llo";
+ else if (radix == 10)
+ fmt = "%016.16lld";
+ else
+ fmt = "%016.16llx";
+ printf(fmt, sym->value);
+ printf(" %c %s", sym->type, sym->name);
+ }
+ putchar('\n');
+ }
+}
+
+static int
+newsym(Symbol *sym, void *data)
+{
+ struct symtbl *tbl = data;
+ Symbol **p;
+ size_t n, size;
+ int type = sym->type;
+
+ if (type == '?' || type == 'N')
+ return 1;
+
+ if (uflag && type != 'U')
+ return 1;
+
+ if (gflag && !isupper(type))
+ return 1;
+
+ n = tbl->nsyms+1;
+ if (n == 0 || n > SIZE_MAX / sizeof(*p))
+ return 0;
+ size = n *sizeof(*p);
+
+ if ((p = realloc(tbl->buf, size)) == NULL)
+ return 0;
+ tbl->buf = p;
+ p[tbl->nsyms++] = sym;
+
+ return 1;
+}
+
+static void
+newobject(FILE *fp, int type)
+{
+ int err = 1;
+ Obj *obj;
+ struct symtbl tbl = {NULL, 0};
+
+ if ((obj = objnew(type)) == NULL) {
+ error("out of memory");
+ return;
+ }
+
+ if (objread(obj, fp) < 0)
+ goto error;
+
+ if (!objtraverse(obj, newsym, &tbl))
+ goto error;
+
+ printsyms(tbl.buf, tbl.nsyms);
+ err = 0;
+
+error:
+ free(tbl.buf);
+ objdel(obj);
+ if (err)
+ error("object file corrupted");
+}
+
+static int
+newmember(FILE *fp, char *name, void *data)
+{
+ int t;
+
+ multi = 1;
+ membname = name;
+ if ((t = objtype(fp, NULL)) != -1)
+ newobject(fp, t);
+
+ return 1;
+}
+
+static void
+nm(char *fname)
+{
+ int t;
+ FILE *fp;
+
+ filename = fname;
+ membname = NULL;
+
+ if ((fp = fopen(fname, "rb")) == NULL) {
+ error(strerror(errno));
+ return;
+ }
+
+ if ((t = objtype(fp, NULL)) != -1)
+ newobject(fp, t);
+ else if (archive(fp))
+ artraverse(fp, newmember, NULL);
+ else
+ error("bad format");
+
+ if (ferror(fp))
+ error(strerror(errno));
+
+ fclose(fp);
+}
+
+static void
+usage(void)
+{
+ fputs("nm [-APv][ -g| -u][-t format] [file...]\n", stderr);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *t;
+
+ ARGBEGIN {
+ case 'P':
+ Pflag = 1;
+ break;
+ case 'A':
+ Aflag = 1;
+ break;
+ case 'g':
+ gflag = 1;
+ break;
+ case 'u':
+ uflag = 1;
+ break;
+ case 'v':
+ vflag = 1;
+ break;
+ case 't':
+ t = EARGF(usage());
+ if (!strcmp(t, "o"))
+ radix = 8;
+ else if (!strcmp(t, "d"))
+ radix = 10;
+ else if (!strcmp(t, "x"))
+ radix = 16;
+ else
+ usage();
+ break;
+ default:
+ usage();
+ } ARGEND
+
+ if (argc == 0) {
+ nm("a.out");
+ } else {
+ if (argc > 1)
+ multi = 1;
+ for ( ; *argv; ++argv)
+ nm(*argv);
+ }
+
+ if (fflush(stdout)) {
+ fprintf(stderr, "nm: error writing in output");
+ status = 1;
+ }
+
+ return status;
+}
--- a/src/libmach/coff32.c
+++ b/src/libmach/coff32.c
@@ -233,12 +233,14 @@
coff = obj->data;
hdr = &coff->hdr;
- if (hdr->f_nsyms > 0) {
- ent = calloc(hdr->f_nsyms, sizeof(*ent));
- if (!ent)
- return 0;
- coff->ents = ent;
- }
+ if (hdr->f_nsyms == 0)
+ return 1;
+
+ ent = calloc(hdr->f_nsyms, sizeof(*ent));
+ if (!ent)
+ return 0;
+ coff->ents = ent;
+
if (fsetpos(fp, &obj->pos))
return 0;
if (fseek(fp, hdr->f_symptr, SEEK_CUR) < 0)
@@ -261,6 +263,12 @@
char *str;
unsigned char buf[10];
+ coff = obj->data;
+ hdr = &coff->hdr;
+
+ if (hdr->f_nsyms == 0)
+ return 1;
+
if (fread(buf, 4, 1, fp) != 1)
return 0;
unpack(ORDER(obj->type), buf, "l", &siz);
@@ -332,10 +340,13 @@
{
struct coff32 *coff = obj->data;
- free(coff->scns);
- free(coff->ents);
- free(coff->strtbl);
+ if (coff) {
+ free(coff->scns);
+ free(coff->ents);
+ free(coff->strtbl);
+ }
free(obj->data);
+ obj->data = NULL;
}
static int
--- a/src/nm/Makefile
+++ /dev/null
@@ -1,19 +1,0 @@
-.POSIX:
-
-PROJECTDIR = ../..
-include $(PROJECTDIR)/scripts/rules.mk
-
-OBJS = nm.o \
-
-TARGET = $(BINDIR)/nm
-
-all: $(TARGET)
-
-$(TARGET): $(LIBDIR)/libmach.a
-
-$(TARGET): $(OBJS)
- $(CC) $(SCC_LDFLAGS) $(OBJS) -lmach -o $@
-
-dep: inc-dep
-
-include deps.mk
--- a/src/nm/deps.mk
+++ /dev/null
@@ -1,3 +1,0 @@
-#deps
-nm.o: $(INCDIR)/scc/scc/arg.h
-nm.o: $(INCDIR)/scc/scc/mach.h
--- a/src/nm/nm.c
+++ /dev/null
@@ -1,273 +1,0 @@
-static char sccsid[] = "@(#) ./nm/main.c";
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <scc/arg.h>
-#include <scc/mach.h>
-
-
-struct symtbl {
- Symbol **buf;
- size_t nsyms;
-};
-
-char *argv0;
-static int status, multi;
-static int radix = 16;
-static int Pflag;
-static int Aflag;
-static int vflag;
-static int gflag;
-static int uflag;
-static char *filename, *membname;
-
-static void
-error(char *fmt, ...)
-{
- va_list va;
-
- va_start(va, fmt);
- fprintf(stderr, "nm: %s: ", filename);
- if (membname)
- fprintf(stderr, "%s: ", membname);
- vfprintf(stderr, fmt, va);
- putc('\n', stderr);
- va_end(va);
-
- status = EXIT_FAILURE;
-}
-
-static int
-cmp(const void *p1, const void *p2)
-{
- Symbol **s1 = (Symbol **) p1, **s2 = (Symbol **) p2;
- Symbol *sym1 = *s1, *sym2 = *s2;
-
- if (vflag) {
- if (sym1->value > sym2->value)
- return 1;
- if (sym1->value < sym2->value)
- return -1;
- if (sym1->type == 'U' && sym2->type == 'U')
- return 0;
- if (sym1->type == 'U')
- return -1;
- if (sym2->type == 'U')
- return 1;
- return 0;
- } else {
- return strcmp(sym1->name, sym2->name);
- }
-}
-
-static void
-printsyms(Symbol **syms, size_t nsym)
-{
- size_t i;
-
- qsort(syms, nsym, sizeof(syms), cmp);
-
- if (multi)
- printf("%s:\n", (membname) ? membname : filename);
-
- for (i = 0; i < nsym; i++) {
- Symbol *sym = syms[i];
- int type = sym->type;
- char *fmt;
-
- if (Aflag) {
- fmt = (membname) ? "%s[%s]: " : "%s: ";
- printf(fmt, filename, membname);
- }
-
- if (Pflag) {
- printf("%s %c", sym->name, sym->type);
- if (type != 'U') {
- if (radix == 8)
- fmt = " %016.16llo %lo";
- else if (radix == 10)
- fmt = " %016.16llu %lu";
- else
- fmt = " %016.16llx %lx";
- printf(fmt, sym->value, sym->size);
- }
- } else {
- if (type == 'U')
- fmt = " ";
- else if (radix == 8)
- fmt = "%016.16llo";
- else if (radix == 10)
- fmt = "%016.16lld";
- else
- fmt = "%016.16llx";
- printf(fmt, sym->value);
- printf(" %c %s", sym->type, sym->name);
- }
- putchar('\n');
- }
-}
-
-static int
-newsym(Symbol *sym, void *data)
-{
- struct symtbl *tbl = data;
- Symbol **p;
- size_t n, size;
- int type = sym->type;
-
- if (type == '?' || type == 'N')
- return 1;
-
- if (uflag && type != 'U')
- return 1;
-
- if (gflag && !isupper(type))
- return 1;
-
- n = tbl->nsyms+1;
- if (n == 0 || n > SIZE_MAX / sizeof(*p))
- return 0;
- size = n *sizeof(*p);
-
- if ((p = realloc(tbl->buf, size)) == NULL)
- return 0;
- tbl->buf = p;
- p[tbl->nsyms++] = sym;
-
- return 1;
-}
-
-static void
-newobject(FILE *fp, int type)
-{
- int err = 1;
- Obj *obj;
- struct symtbl tbl = {NULL, 0};
-
- if ((obj = objnew(type)) == NULL) {
- error("out of memory");
- return;
- }
-
- if (objread(obj, fp) < 0)
- goto error;
-
- if (!objtraverse(obj, newsym, &tbl))
- goto error;
-
- printsyms(tbl.buf, tbl.nsyms);
- err = 0;
-
-error:
- free(tbl.buf);
- objdel(obj);
- if (err)
- error("object file corrupted");
-}
-
-static int
-newmember(FILE *fp, char *name, void *data)
-{
- int t;
-
- multi = 1;
- membname = name;
- if ((t = objtype(fp, NULL)) != -1)
- newobject(fp, t);
-
- return 1;
-}
-
-static void
-nm(char *fname)
-{
- int t;
- FILE *fp;
-
- filename = fname;
- membname = NULL;
-
- if ((fp = fopen(fname, "rb")) == NULL) {
- error(strerror(errno));
- return;
- }
-
- if ((t = objtype(fp, NULL)) != -1)
- newobject(fp, t);
- else if (archive(fp))
- artraverse(fp, newmember, NULL);
- else
- error("bad format");
-
- if (ferror(fp))
- error(strerror(errno));
-
- fclose(fp);
-}
-
-static void
-usage(void)
-{
- fputs("nm [-APv][ -g| -u][-t format] [file...]\n", stderr);
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- char *t;
-
- ARGBEGIN {
- case 'P':
- Pflag = 1;
- break;
- case 'A':
- Aflag = 1;
- break;
- case 'g':
- gflag = 1;
- break;
- case 'u':
- uflag = 1;
- break;
- case 'v':
- vflag = 1;
- break;
- case 't':
- t = EARGF(usage());
- if (!strcmp(t, "o"))
- radix = 8;
- else if (!strcmp(t, "d"))
- radix = 10;
- else if (!strcmp(t, "x"))
- radix = 16;
- else
- usage();
- break;
- default:
- usage();
- } ARGEND
-
- if (argc == 0) {
- nm("a.out");
- } else {
- if (argc > 1)
- multi = 1;
- for ( ; *argv; ++argv)
- nm(*argv);
- }
-
- fflush(stdout);
- if (ferror(stdout)) {
- fprintf(stderr, "nm: error writing in output");
- status = 1;
- }
-
- return status;
-}