shithub: scc

Download patch

ref: 5b7017f04867f0666222a6466ac016ab395fe128
parent: c56added1b7434a96dbe34a6dc5e7637a9c9adc2
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jan 7 16:58:17 EST 2019

[strip] first version

This is not a functional version

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -50,6 +50,7 @@
 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);
--- a/src/cmd/.gitignore
+++ b/src/cmd/.gitignore
@@ -1,1 +1,2 @@
 nm
+strip
--- 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
 
--- 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
--- /dev/null
+++ b/src/cmd/strip.c
@@ -1,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;
+}
--- a/src/libmach/coff32.c
+++ b/src/libmach/coff32.c
@@ -360,6 +360,21 @@
 	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,
@@ -366,4 +381,5 @@
 	.del = del,
 	.read = read,
 	.write = write,
+	.strip = strip,
 };
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -28,6 +28,7 @@
 
 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);
--- a/src/libmach/object.c
+++ b/src/libmach/object.c
@@ -144,19 +144,11 @@
 	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;
 		free(sym->name);
@@ -168,8 +160,36 @@
 }
 
 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);
 }