scc

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

commit caa96d4e8c805e2ae1634f4f49d6291d5507287e
parent 682597159c584f8e509371ecbe32cf15d897da75
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 27 Aug 2019 15:58:16 +0100

[nm] Improve error handling

There is a centralized check of errors now.

Diffstat:
Minclude/scc/scc/mach.h | 3++-
Msrc/cmd/nm.c | 71+++++++++++++++++++++++++++++++++++------------------------------------
Msrc/libmach/Makefile | 3++-
Msrc/libmach/armember.c | 9+++++++--
Msrc/libmach/coff32/coff32del.c | 2--
Msrc/libmach/coff32/coff32getsym.c | 9++++++---
Msrc/libmach/coff32/coff32read.c | 5++++-
Asrc/libmach/newobj.c | 33+++++++++++++++++++++++++++++++++
Dsrc/libmach/objnew.c | 33---------------------------------
9 files changed, 89 insertions(+), 79 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -68,6 +68,7 @@ extern int archive(FILE *fp); extern long armember(FILE *fp, char *member); extern int objtype(FILE *fp, char **name); -extern Obj *objnew(int type); +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); diff --git a/src/cmd/nm.c b/src/cmd/nm.c @@ -121,36 +121,32 @@ newsym(Symbol *sym, struct symtbl *tbl) size_t n, size; int type = sym->type; - if (type == '?' || type == 'N') - return 1; - - if (uflag && type != 'U') - return 1; - - if (gflag && !isupper(type)) - return 1; + if (type == '?' + || type == 'N' + || uflag && type != 'U' + || gflag && !isupper(type)) { + return 0; + } n = tbl->nsyms+1; - if (n == 0 || n > SIZE_MAX / sizeof(*p)) - return 0; size = n *sizeof(*p); - p = realloc(tbl->buf, size); s = malloc(sizeof(*s)); if (!p || !s) { - error("out of memory"); - exit(EXIT_FAILURE); + free(p); + free(s); + error(strerror(errno)); + return -1; } *s = *sym; tbl->buf = p; p[tbl->nsyms++] = s; - - return 1; + return 0; } static void -newobject(FILE *fp, int type) +nmobj(FILE *fp, int type) { int err = 1; long i; @@ -158,54 +154,60 @@ newobject(FILE *fp, int type) Symbol sym; struct symtbl tbl = {NULL, 0}; - if ((obj = objnew(type)) == NULL) { - error("out of memory"); - exit(EXIT_FAILURE); + if ((obj = newobj(type)) == NULL) { + error(strerror(errno)); + goto err1; } - if (readobj(obj, fp) < 0) - goto error; + if (readobj(obj, fp) < 0) { + error(strerror(errno)); + goto err2; + } - for (i = 0; getsym(obj, &i, &sym); i++) - newsym(&sym, &tbl); + for (i = 0; getsym(obj, &i, &sym) != -1; i++) { + if (newsym(&sym, &tbl) < 0) + goto err3; + } printsyms(tbl.buf, tbl.nsyms); err = 0; -error: - (*obj->ops->del)(obj); +err3: free(tbl.buf); +err2: + delobj(obj); +err1: if (err) error("object file corrupted"); } static void -newlib(FILE *fp) +nmlib(FILE *fp) { int t; long off, cur; char memb[SARNAM+1]; - while (!feof(fp)) { + for (;;) { cur = ftell(fp); off = armember(fp, memb); switch (off) { case -1: error("library corrupted"); + if (ferror(fp)) + error(strerror(errno)); case 0: return; default: membname = memb; if ((t = objtype(fp, NULL)) != -1) - newobject(fp, t); + nmobj(fp, t); membname = NULL; fseek(fp, cur, SEEK_SET); fseek(fp, off, SEEK_CUR); break; } } - - error("library corrupted:%s", strerror(errno)); } static void @@ -223,15 +225,12 @@ nm(char *fname) } if ((t = objtype(fp, NULL)) != -1) - newobject(fp, t); + nmobj(fp, t); else if (archive(fp)) - newlib(fp); + nmlib(fp); else error("bad format"); - if (ferror(fp)) - error(strerror(errno)); - fclose(fp); } @@ -287,7 +286,7 @@ main(int argc, char *argv[]) nm(*argv); } - if (fflush(stdout)) { + if (fflush(stdout) == EOF) { fprintf(stderr, "nm: error writing in output:%s\n", strerror(errno)); diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -5,7 +5,8 @@ include $(PROJECTDIR)/scripts/rules.mk TARGET = $(LIBDIR)/libmach.a OBJS = mach.o \ - objnew.o \ + newobj.o \ + delobj.o \ objpos.o \ archive.o \ armember.o \ diff --git a/src/libmach/armember.c b/src/libmach/armember.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -31,14 +32,18 @@ armember(FILE *fp, char *member) if (fread(&hdr, sizeof(hdr), 1, fp) != 1) return (feof(fp)) ? 0 : -1; - if (strncmp(hdr.ar_fmag, ARFMAG, sizeof(hdr.ar_fmag))) + if (strncmp(hdr.ar_fmag, ARFMAG, sizeof(hdr.ar_fmag))) { + errno = ERANGE; return -1; + } siz = strtol(hdr.ar_size, NULL, 0); if (siz & 1) siz++; - if (siz == 0) + if (siz == 0) { + errno = ERANGE; return -1; + } getfname(&hdr, member); diff --git a/src/libmach/coff32/coff32del.c b/src/libmach/coff32/coff32del.c @@ -18,6 +18,4 @@ coff32del(Obj *obj) } free(obj->data); obj->data = NULL; - - free(obj); } diff --git a/src/libmach/coff32/coff32getsym.c b/src/libmach/coff32/coff32getsym.c @@ -1,4 +1,5 @@ #include <ctype.h> +#include <errno.h> #include <stdio.h> #include <scc/mach.h> @@ -59,8 +60,10 @@ coff32getsym(Obj *obj, long *idx, Symbol *sym) SYMENT *ent; Coff32 *coff = obj->data; - if (*idx >= coff->hdr.f_nsyms) - return 0; + if (*idx >= coff->hdr.f_nsyms) { + errno = ERANGE; + return -1; + } ent = &coff->ents[n]; sym->name = symname(coff, ent); @@ -70,5 +73,5 @@ coff32getsym(Obj *obj, long *idx, Symbol *sym) sym->index = n; *idx += ent->n_numaux; - return 1; + return 0; } diff --git a/src/libmach/coff32/coff32read.c b/src/libmach/coff32/coff32read.c @@ -1,5 +1,6 @@ #include <assert.h> #include <ctype.h> +#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -359,8 +360,10 @@ coff32read(Obj *obj, FILE *fp) for (i = 0; i < hdr->f_nsyms; i++) { SYMENT *ent = &coff->ents[i]; - if (ent->n_zeroes != 0 && ent->n_offset > coff->strsiz) + if (ent->n_zeroes != 0 && ent->n_offset > coff->strsiz) { + errno = ERANGE; return -1; + } } return 0; diff --git a/src/libmach/newobj.c b/src/libmach/newobj.c @@ -0,0 +1,33 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <scc/mach.h> + +#include "libmach.h" + +Obj * +newobj(int type) +{ + Obj *obj; + int fmt; + + fmt = FORMAT(type); + if (fmt >= NFORMATS) { + errno = ERANGE; + return NULL; + } + + if ((obj = malloc(sizeof(*obj))) == NULL) + return NULL; + + obj->type = type; + obj->ops = objops[fmt]; + if ((*obj->ops->new)(obj) < 0) { + free(obj); + return NULL; + } + + return obj; +} diff --git a/src/libmach/objnew.c b/src/libmach/objnew.c @@ -1,33 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <scc/mach.h> - -#include "libmach.h" - -Obj * -objnew(int type) -{ - Obj *obj; - int fmt; - Objops *ops; - - fmt = FORMAT(type); - if (fmt >= NFORMATS) - return NULL; - - if ((obj = malloc(sizeof(*obj))) == NULL) - return NULL; - - obj->type = type; - ops = objops[fmt]; - obj->ops = ops; - - if ((*ops->new)(obj) < 0) { - free(obj); - return NULL; - } - - return obj; -}