commit 29cdba27742a2f8d7280ffaf7b9dc8ddd60e15ac
parent 29366934e10a3b77952788494396b6097873f8e9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 27 Aug 2019 21:07:16 +0100
[libmach] Add strip()
This function removes all the debug information of object files.
Diffstat:
9 files changed, 48 insertions(+), 53 deletions(-)
diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h
@@ -51,7 +51,7 @@ struct objops {
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 int objtype(FILE *fp, char **name);
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
diff --git a/src/cmd/Makefile b/src/cmd/Makefile
@@ -5,8 +5,8 @@ include $(PROJECTDIR)/scripts/rules.mk
TARGET = $(BINDIR)/nm \
$(BINDIR)/ar \
+ $(BINDIR)/strip \
-# $(BINDIR)/strip \
# $(BINDIR)/size \
# $(BINDIR)/ranlib \
# $(BINDIR)/objdump \
diff --git a/src/cmd/nm.c b/src/cmd/nm.c
@@ -70,6 +70,10 @@ printsyms(Symbol **syms, size_t nsym)
{
size_t i;
+ if (nsym == 0) {
+ error("no symbols");
+ return;
+ }
qsort(syms, nsym, sizeof(syms), cmp);
if (!Aflag) {
@@ -164,7 +168,7 @@ nmobj(FILE *fp, int type)
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;
}
diff --git 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 @@ error(char *fmt, ...)
}
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");
- goto err3;
- }
- ops = obj->ops;
-
- if ((*ops->read)(obj, fp) < 0) {
- error("file corrupted");
+ if ((obj = newobj(type)) == NULL)
+ goto err2;
+ if (readobj(obj, fp) < 0)
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 @@ main(int argc, char *argv[])
} ARGEND
if (argc == 0) {
- strip("a.out");
+ doit("a.out");
} else {
for (; *argv; ++argv)
- strip(*argv);
+ doit(*argv);
}
return status;
diff --git a/src/libmach/Makefile b/src/libmach/Makefile
@@ -12,7 +12,9 @@ OBJS = mach.o \
armember.o \
objtype.o \
readobj.o \
+ writeobj.o \
getsym.o \
+ strip.o \
pack.o \
unpack.o \
diff --git a/src/libmach/coff32/coff32.h b/src/libmach/coff32/coff32.h
@@ -39,4 +39,4 @@ extern int coff32xsetidx(int order,
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
diff --git a/src/libmach/coff32/coff32getsym.c b/src/libmach/coff32/coff32getsym.c
@@ -53,17 +53,16 @@ symname(Coff32 *coff, SYMENT *ent)
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 @@ coff32getsym(Obj *obj, long *idx, Symbol *sym)
sym->index = n;
*idx += ent->n_numaux;
- return 0;
+ return sym;
}
diff --git a/src/libmach/coff32/coff32strip.c b/src/libmach/coff32/coff32strip.c
@@ -10,11 +10,10 @@ int
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;
diff --git 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);