scc

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

commit eef02524604f1a9303a807cafaeed78d82232762
parent 6c84132c304c95e7315ee1b46e66d844f758aaad
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  7 Jan 2019 19:00:58 +0000

Create cmd directory

These directory is intended for all the tools with
only one source file.

Diffstat:
Mscripts/rules.mk | 3+++
Msrc/Makefile | 2+-
Asrc/cmd/.gitignore | 1+
Asrc/cmd/Makefile | 20++++++++++++++++++++
Rsrc/nm/deps.mk -> src/cmd/deps.mk | 0
Asrc/cmd/nm.c | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32.c | 29++++++++++++++++++++---------
Dsrc/nm/Makefile | 19-------------------
Dsrc/nm/nm.c | 273-------------------------------------------------------------------------------
9 files changed, 317 insertions(+), 302 deletions(-)

diff --git a/scripts/rules.mk b/scripts/rules.mk @@ -36,6 +36,9 @@ FORALL = +@set -e ;\ cd $$pwd; \ done +.o: + $(CC) $(SCC_LDFLAGS) -o $@ $< $(LIBS) + .s.o: $(AS) $< -o $@ diff --git 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) diff --git a/src/cmd/.gitignore b/src/cmd/.gitignore @@ -0,0 +1 @@ +nm diff --git a/src/cmd/Makefile b/src/cmd/Makefile @@ -0,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 diff --git a/src/nm/deps.mk b/src/cmd/deps.mk diff --git a/src/cmd/nm.c b/src/cmd/nm.c @@ -0,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; +} diff --git a/src/libmach/coff32.c b/src/libmach/coff32.c @@ -233,12 +233,14 @@ readents(Obj *obj, FILE *fp) 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 @@ readstr(Obj *obj, FILE *fp) 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 @@ del(Obj *obj) { 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 diff --git a/src/nm/Makefile b/src/nm/Makefile @@ -1,19 +0,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 diff --git a/src/nm/nm.c b/src/nm/nm.c @@ -1,273 +0,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; -}