scc

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

commit fe7dfc544705bbdea43716d08628036a7f1a6cbe
parent 37cb8ee7d412facd351f0ac236d0600b593b86bd
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  7 Jan 2019 21:58:17 +0000

[strip] first version

This is not a functional version

Diffstat:
Minclude/scc/scc/mach.h | 1+
Msrc/cmd/.gitignore | 1+
Msrc/cmd/Makefile | 12+++++++++---
Msrc/cmd/deps.mk | 2++
Asrc/cmd/strip.c | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32.c | 16++++++++++++++++
Msrc/libmach/libmach.h | 1+
Msrc/libmach/object.c | 40++++++++++++++++++++++++++++++----------
8 files changed, 166 insertions(+), 13 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -50,6 +50,7 @@ extern void objreset(Obj *obj); extern int objread(Obj *obj, FILE *fp); extern Symbol *objlookup(Obj *obj, char *name); extern int objtraverse(Obj *obj, int (*fn)(Symbol *sym, void *data), void *data); +extern void objstrip(Obj *obj); /* TODO */ extern int objload(Obj *obj, Obj *to); diff --git a/src/cmd/.gitignore b/src/cmd/.gitignore @@ -1 +1,2 @@ nm +strip diff --git a/src/cmd/Makefile b/src/cmd/Makefile @@ -3,17 +3,23 @@ PROJECTDIR = ../.. include $(PROJECTDIR)/scripts/rules.mk -TARGET = $(BINDIR)/nm +TARGET = $(BINDIR)/nm \ + $(BINDIR)/strip \ + LIBS = -lmach all: $(TARGET) -nm: $(LIBDIR)/libmach.a +nm strip: $(LIBDIR)/libmach.a + $(BINDIR)/nm: nm cp nm $@ +$(BINDIR)/strip: strip + cp strip $@ + clean: - rm -f nm + rm -f nm strip dep: inc-dep diff --git a/src/cmd/deps.mk b/src/cmd/deps.mk @@ -1,3 +1,5 @@ #deps nm.o: $(INCDIR)/scc/scc/arg.h nm.o: $(INCDIR)/scc/scc/mach.h +strip.o: $(INCDIR)/scc/scc/arg.h +strip.o: $(INCDIR)/scc/scc/mach.h diff --git a/src/cmd/strip.c b/src/cmd/strip.c @@ -0,0 +1,106 @@ +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <scc/arg.h> +#include <scc/mach.h> + +static int status; +static char *filename; +char *argv0; + +static void +error(char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + fprintf(stderr, "strip: %s: ", filename); + vfprintf(stderr, fmt, va); + putc('\n', stderr); + va_end(va); + + status = EXIT_FAILURE; +} + +static void +strip(char *fname) +{ + int type; + FILE *fp, *tmp; + Obj *obj; + + filename = fname; + if ((tmp = fopen("strip.tmp", "wb")) == NULL) { + error("%s", strerror(errno)); + goto err; + } + if ((fp = fopen(fname, "rb")) == NULL) { + error("%s", strerror(errno)); + goto err1; + } + if ((type = objtype(fp, NULL)) < 0) { + error("file format not recognized"); + goto err2; + } + if ((obj = objnew(type)) == NULL) { + error("out of memory"); + goto err3; + } + if (objread(obj, fp) < 0) { + error("file corrupted"); + goto err3; + } + objstrip(obj); + + if (objwrite(obj, tmp) < 0) { + error("error writing output"); + goto err3; + } + + fclose(fp); + fp = NULL; + + if (remove(fname) || rename("strip.tmp", fname)) { + error(strerror(errno)); + goto err3; + } + objdel(obj); + return; + +err3: + objdel(obj); +err2: + if (fp) + fclose(fp); +err1: + fclose(tmp); + remove("strip.tmp"); +err: + return; +} + +static void +usage(void) +{ + fputs("usage: strip file ...\n", stderr); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + ARGBEGIN { + default: + usage(); + } ARGEND + + if (argc == 1) + usage; + + for (argc--; argc > 0; argc--) + strip(*argv++); + return status; +} diff --git a/src/libmach/coff32.c b/src/libmach/coff32.c @@ -360,10 +360,26 @@ new(Obj *obj) return 0; } +static void +strip(Obj *obj) +{ + struct coff32 *coff = obj->data; + FILHDR *hdr; + + if (coff) { + hdr = &coff->hdr; + free(coff->ents); + coff->ents = NULL; + hdr->f_nsyms = 0; + hdr->f_symptr = 0; + } +} + struct format objcoff32 = { .probe = probe, .new = new, .del = del, .read = read, .write = write, + .strip = strip, }; diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -28,6 +28,7 @@ enum order { struct format { int (*probe)(unsigned char *buf, char **name); + void (*strip)(Obj *obj); int (*new)(Obj *obj); int (*read)(Obj *obj, FILE *fp); int (*write)(Obj *obj, FILE *fp); diff --git a/src/libmach/object.c b/src/libmach/object.c @@ -144,18 +144,10 @@ objtraverse(Obj *obj, int (*fn)(Symbol *, void *), void *data) return 1; } -void -objreset(Obj *obj) +static void +delsyms(Obj *obj) { - int fmt; Symbol *sym, *next; - struct format *op; - - fmt = FORMAT(obj->type); - if (fmt < NFORMATS) { - op = objfmt[fmt]; - (*op->del)(obj); - } for (sym = obj->head; sym; sym = next) { next = sym->next; @@ -168,8 +160,36 @@ objreset(Obj *obj) } void +objreset(Obj *obj) +{ + int fmt; + struct format *op; + + fmt = FORMAT(obj->type); + if (fmt < NFORMATS) { + op = objfmt[fmt]; + (*op->del)(obj); + } + delsyms(obj); +} + +void objdel(Obj *obj) { objreset(obj); free(obj); } + +void +objstrip(Obj *obj) +{ + int fmt; + struct format *op; + + fmt = FORMAT(obj->type); + if (fmt >= NFORMATS) + return -1; + op = objfmt[fmt]; + (*op->strip)(obj); + delsyms(obj); +}