scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit e69bb726e983797ef0d094e1622465cb35ec3814
parent c1b5ec796dc1e791a4ee2dd68bbbfdf6c9f3c54b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  6 Mar 2018 14:41:08 +0100

[nm] Remove myro object file

We are going to migrate to COFF, and nm is going to be the first
tool migrated.

Diffstat:
Mnm/Makefile | 8++++----
Anm/coff.c | 21+++++++++++++++++++++
Anm/formats.c | 15+++++++++++++++
Mnm/main.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Dnm/myro.c | 141-------------------------------------------------------------------------------
Mnm/nm.h | 17+++++------------
6 files changed, 104 insertions(+), 186 deletions(-)

diff --git a/nm/Makefile b/nm/Makefile @@ -5,13 +5,13 @@ LIBDIR = $(PROJECTDIR)/lib/scc include $(PROJECTDIR)/rules.mk include $(LIBDIR)/libdep.mk -OBJ = main.o myro.o +OBJ = main.o coff.o formats.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 +main.o: $(INCDIR)/scc.h $(INCDIR)/ar.h $(INCDIR)/arg.h nm.h +coff.o: nm.h +formats.o: nm.h nm: $(OBJ) $(LIBDIR)/libscc.a $(CC) $(SCC_LDFLAGS) $(OBJ) -lscc -o $@ diff --git a/nm/coff.c b/nm/coff.c @@ -0,0 +1,21 @@ + +static char sccsid[] = "@(#) ./nm/coff.c"; + +#include <stdio.h> + +#include "nm.h" + +static void +nm(char *fname, FILE *fp) +{ +} + +static int +probe(FILE *fp) +{ +} + +struct objfile coff = { + .probe = probe, + .nm = nm, +}; diff --git a/nm/formats.c b/nm/formats.c @@ -0,0 +1,15 @@ + +static char sccsid[] = "@(#) ./nm/probe.c"; + +#include <stdio.h> + +#include "nm.h" + +struct objfile coff; + +/* TODO: Autogenerate this file */ + +struct objfile *formats[] = { + &coff, + NULL, +}; diff --git a/nm/main.c b/nm/main.c @@ -14,29 +14,26 @@ static char sccsid[] = "@(#) ./nm/main.c"; #include "nm.h" char *argv0; -int radix = 16; -int Pflag; -int Aflag; -int vflag; -int gflag; -int uflag; -int arflag; +static int radix = 16; +static int Pflag; +static int Aflag; +static int vflag; +static int gflag; +static int uflag; +static int arflag; -static int -archive(char *fname, FILE *fp) +int +object(char *fname, FILE *fp) { - char magic[SARMAG]; - fpos_t pos; - - fgetpos(fp, &pos); - fread(magic, SARMAG, 1, fp); - fsetpos(fp, &pos); - - if (ferror(fp)) { - perror("nm"); - exit(1); - } - return strncmp(magic, ARMAG, SARMAG) == 0; + extern struct objfile formats[]; + struct objfile *p; + + for (p = formats; p->probe && (*p->probe)(fp); ++p) + ; + if (!p->probe) + return 0; + (*p->nm)(fname, fp); + return 1; } static char * @@ -87,9 +84,7 @@ ar(char *fname, FILE *fp) pos += siz; getfname(&hdr, member); - if (object(fp)) { - nm(fname, hdr.ar_name, fp); - } else { + if (!object(member, fp)) { fprintf(stderr, "nm: skipping member %s in archive %s\n", member, fname); @@ -103,6 +98,26 @@ corrupted: exit(1); } +static int +archive(char *fname, FILE *fp) +{ + char magic[SARMAG]; + fpos_t pos; + + fgetpos(fp, &pos); + fread(magic, SARMAG, 1, fp); + fsetpos(fp, &pos); + + if (ferror(fp)) { + perror("nm"); + exit(1); + } + if (strncmp(magic, ARMAG, SARMAG) != 0) + return 0; + ar(fname, fp); + return 1; +} + void print(char *file, char *member, struct symbol *sym) { @@ -142,6 +157,25 @@ print(char *file, char *member, struct symbol *sym) putchar('\n'); } +static int +cmp(const void *p1, const void *p2) +{ + const struct symbol *s1 = p1, *s2 = p2; + + if (vflag) + return s1->off - s2->off; + else + return strcmp(s1->name, s2->name); +} + +void +printsyms(char *file, char *member, struct symbol *syms, size_t nsyms) +{ + qsort(syms, nsyms, sizeof(*syms), cmp); + + while (nsyms--) + print(file, member, syms++); +} void doit(char *fname) @@ -154,11 +188,7 @@ doit(char *fname) exit(1); } - if (object(fp)) - nm(fname, fname, fp); - else if (archive(fname, fp)) - ar(fname, fp); - else + if (!object(fname, fp) && !archive(fname, fp)) fprintf(stderr, "nm: %s: File format not recognized\n", fname); if (ferror(fp) || fclose(fp) == EOF) { diff --git a/nm/myro.c b/nm/myro.c @@ -1,141 +0,0 @@ -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; - struct symbol symbol; - 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 = &syms[i]; - symbol.name = strings + sym->name; - symbol.type = typeof(sym); - symbol.off = sym->offset; - symbol.size = sym->len; - print(fname, member, &symbol); - } - -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(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; -} - diff --git a/nm/nm.h b/nm/nm.h @@ -6,17 +6,10 @@ struct symbol { unsigned long size; }; +struct objfile { + int (*probe)(FILE *fp); + void (*nm)(char *fname, FILE *fp); +}; + /* main.c */ extern void print(char *file, char *member, struct symbol *sym); - -/* object format file */ -extern void nm(char *fname, char *member, FILE *fp); -extern int object(FILE *fp); - -extern int radix; -extern int Pflag; -extern int Aflag; -extern int vflag; -extern int gflag; -extern int uflag; -extern int arflag;