scc

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

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:
Minclude/scc/scc/mach.h | 6++++--
Msrc/cmd/Makefile | 2+-
Msrc/cmd/nm.c | 6+++++-
Msrc/cmd/strip.c | 65+++++++++++++++++++++++++++--------------------------------------
Msrc/libmach/Makefile | 2++
Msrc/libmach/coff32/coff32.h | 4++--
Msrc/libmach/coff32/coff32getsym.c | 11+++++------
Msrc/libmach/coff32/coff32strip.c | 3+--
Msrc/libmach/getsym.c | 2+-
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);