shithub: scc

Download patch

ref: 57b7d9443f8a5ea6e19a7080f5ed310b86c3db74
parent: 279bf67dfc38f55a3c9f4529799686608bd28bb4
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 27 17:07:16 EDT 2019

[libmach] Add strip()

This function removes all the debug information of object files.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -51,7 +51,7 @@
 	int (*write)(Obj *obj, FILE *fp);
 	int (*strip)(Obj *obj);
 	int (*addr2line)(Obj *, unsigned long long , char *, int *);
-	int (*getsym)(Obj *obj, long *index, Symbol *sym);
+	Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym);
 	int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp);
 	int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp);
 };
@@ -71,4 +71,5 @@
 extern Obj *newobj(int type);
 extern void delobj(Obj *obj);
 extern int readobj(Obj *obj, FILE *fp);
-extern int getsym(Obj *obj, long *index, Symbol *sym);
+extern Symbol *getsym(Obj *obj, long *index, Symbol *sym);
+extern int strip(Obj *obj);
\ No newline at end of file
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -5,8 +5,8 @@
 
 TARGET = $(BINDIR)/nm \
          $(BINDIR)/ar \
+         $(BINDIR)/strip \
 
-#         $(BINDIR)/strip \
 #         $(BINDIR)/size \
 #         $(BINDIR)/ranlib \
 #         $(BINDIR)/objdump \
--- a/src/cmd/nm.c
+++ b/src/cmd/nm.c
@@ -70,6 +70,10 @@
 {
 	size_t i;
 
+	if (nsym == 0) {
+		error("no symbols");
+		return;
+	}
 	qsort(syms, nsym, sizeof(syms), cmp);
 
 	if (!Aflag) {
@@ -164,7 +168,7 @@
 		goto err2;
 	}
 
-	for (i = 0; getsym(obj, &i, &sym) != -1; i++) {
+	for (i = 0; getsym(obj, &i, &sym); i++) {
 		if (newsym(&sym, &tbl) < 0)
 			goto err3;
 	}
--- a/src/cmd/strip.c
+++ b/src/cmd/strip.c
@@ -8,6 +8,7 @@
 #include <scc/mach.h>
 
 static int status;
+static char tmpname[FILENAME_MAX];
 static char *filename;
 char *argv0;
 
@@ -26,65 +27,53 @@
 }
 
 static void
-strip(char *fname)
+doit(char *fname)
 {
 	int type;
+	size_t r;
 	FILE *fp;
 	Obj *obj;
-	Objops *ops;
 
-	errno = 0;
 	filename = fname;
-
 	if ((fp = fopen(fname, "rb")) == NULL)
 		goto err1;
-
-	if ((type = objtype(fp, NULL)) < 0) {
-		error("file format not recognized");
+	if ((type = objtype(fp, NULL)) < 0)
 		goto err2;
-	}
-	if ((obj = objnew(type)) == NULL) {
-		error("out of memory");
+	if ((obj = newobj(type)) == NULL)
+		goto err2;
+	if (readobj(obj, fp) < 0)
 		goto err3;
-	}
-	ops = obj->ops;
-
-	if ((*ops->read)(obj, fp) < 0) {
-		error("file corrupted");
-		goto err3;
-	}
 	fclose(fp);
-	fp = NULL;
 
-	if ((*ops->strip)(obj) < 0) {
-		error("error stripping");
-		goto err3;
+	if (strip(obj) < 0)
+		goto err2;
+
+	r = snprintf(tmpname, sizeof(tmpname), "%s.tmp", fname);
+	if (r >= sizeof(tmpname)) {
+		errno = ERANGE;
+		goto err2;
 	}
 
-	/* TODO: Use a temporary file */
-	if ((fp = fopen(fname, "wb")) == NULL)
-		goto err1;
+	if ((fp = fopen(tmpname, "wb")) == NULL)
+		goto err2;
 
-	if (ops->write(obj, fp) < 0) {
-		error("error writing output");
+	if (writeobj(obj, fp) < 0)
 		goto err3;
-	}
-
 	fclose(fp);
-	(*ops->del)(obj);
+	delobj(obj);
 
+	if (rename(tmpname, fname) == EOF)
+		goto err1;
+
 	return;
 
 err3:
-	(*ops->del)(obj);
+	fclose(fp);
 err2:
-	if (fp)
-		fclose(fp);
+	delobj(obj);
 err1:
-	if (errno)
-		error(strerror(errno));
-
-	return;
+	error(strerror(errno));
+	remove(tmpname);
 }
 
 static void
@@ -103,10 +92,10 @@
 	} ARGEND
 
 	if (argc == 0) {
-		strip("a.out");
+		doit("a.out");
 	} else {
 		for (; *argv; ++argv)
-			strip(*argv);
+			doit(*argv);
 	}
 
 	return status;
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -12,7 +12,9 @@
        armember.o \
        objtype.o \
        readobj.o \
+       writeobj.o \
        getsym.o \
+       strip.o \
        pack.o \
        unpack.o \
 
--- a/src/libmach/coff32/coff32.h
+++ b/src/libmach/coff32/coff32.h
@@ -39,4 +39,4 @@
 extern int coff32xgetidx(int order,
                          long *nsyms, char ***namep, long **offsp, FILE *fp);
 
-extern int coff32getsym(Obj *obj, long *idx, Symbol *sym);
\ No newline at end of file
+extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);
\ No newline at end of file
--- a/src/libmach/coff32/coff32getsym.c
+++ b/src/libmach/coff32/coff32getsym.c
@@ -53,17 +53,16 @@
 	return &coff->strtbl[ent->n_offset];
 }
 
-int
+Symbol *
 coff32getsym(Obj *obj, long *idx, Symbol *sym)
 {
 	long n = *idx;
 	SYMENT *ent;
 	Coff32 *coff = obj->data;
+	FILHDR *hdr = &coff->hdr;
 
-	if (*idx >= coff->hdr.f_nsyms) {
-		errno = ERANGE;
-		return -1;
-	}
+	if ((hdr->f_flags & F_SYMS) != 0 || n >= coff->hdr.f_nsyms)
+		return NULL;
 
 	ent = &coff->ents[n];
 	sym->name = symname(coff, ent);
@@ -73,5 +72,5 @@
 	sym->index = n;
 	*idx += ent->n_numaux;
 
-	return 0;
+	return sym;
 }
--- a/src/libmach/coff32/coff32strip.c
+++ b/src/libmach/coff32/coff32strip.c
@@ -10,11 +10,10 @@
 coff32strip(Obj *obj)
 {
 	int i;
-	FILHDR *hdr;
 	SCNHDR *scn;
 	struct coff32 *coff = obj->data;
+	FILHDR *hdr = &coff->hdr;
 
-	hdr = &coff->hdr;
 	for (i = 0; i < hdr->f_nscns; i++) {
 		scn = &coff->scns[i];
 		scn->s_nrelloc = 0;
--- a/src/libmach/getsym.c
+++ b/src/libmach/getsym.c
@@ -2,7 +2,7 @@
 
 #include <scc/mach.h>
 
-int
+Symbol *
 getsym(Obj *obj, long *index, Symbol *sym)
 {
 	return (*obj->ops->getsym)(obj, index, sym);