ref: 1623dbdd55d0ee760c4a1c17c5881f7ca0153186
parent: 845a4d450d705c86e557494e4661abddf4f157be
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 27 11:58:16 EDT 2019
[nm] Improve error handling There is a centralized check of errors now.
--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -68,6 +68,7 @@
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);
--- a/src/cmd/nm.c
+++ b/src/cmd/nm.c
@@ -121,36 +121,32 @@
size_t n, size;
int type = sym->type;
- if (type == '?' || type == 'N')
- return 1;
+ if (type == '?'
+ || type == 'N'
+ || uflag && type != 'U'
+ || gflag && !isupper(type)) {
+ return 0;
+ }
- if (uflag && type != 'U')
- return 1;
-
- if (gflag && !isupper(type))
- return 1;
-
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,46 +154,54 @@
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);
@@ -204,8 +208,6 @@
break;
}
}
-
- error("library corrupted:%s", strerror(errno));
}
static void
@@ -223,15 +225,12 @@
}
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 @@
nm(*argv);
}
- if (fflush(stdout)) {
+ if (fflush(stdout) == EOF) {
fprintf(stderr,
"nm: error writing in output:%s\n",
strerror(errno));
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -5,7 +5,8 @@
TARGET = $(LIBDIR)/libmach.a
OBJS = mach.o \
- objnew.o \
+ newobj.o \
+ delobj.o \
objpos.o \
archive.o \
armember.o \
--- 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 @@
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);
--- a/src/libmach/coff32/coff32del.c
+++ b/src/libmach/coff32/coff32del.c
@@ -18,6 +18,4 @@
}
free(obj->data);
obj->data = NULL;
-
- free(obj);
}
--- 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 @@
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 @@
sym->index = n;
*idx += ent->n_numaux;
- return 1;
+ return 0;
}
--- 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 @@
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;
--- /dev/null
+++ b/src/libmach/newobj.c
@@ -1,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;
+}
--- a/src/libmach/objnew.c
+++ /dev/null
@@ -1,33 +1,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;
-}