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);
}