shithub: scc

Download patch

ref: 8336b733717f4fc2cf5ccf6647f1718760fc1bc8
parent: 6a972ee63bdb46b8fdc57af1740154c7ba576604
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Jan 7 13:19:24 EST 2019

[libmach] Split objread()

--- a/src/libmach/coff32.c
+++ b/src/libmach/coff32.c
@@ -176,13 +176,13 @@
 		ent = &coff->ents[i];
 
 		if ((t = typeof(coff, ent)) < 0)
-			return -1;
+			return 0;
 
 		if ((s = symname(coff, ent)) == NULL)
-			return -1;
+			return 0;
 
 		if ((sym = objlookup(obj, s)) == NULL)
-			return -1;
+			return 0;
 
 		sym->type = t;
 		sym->value = ent->n_value;
@@ -189,91 +189,135 @@
 		sym->size = (sym->type == 'C') ? ent->n_value : 0;
 	}
 
-	return 0;
+	return 1;
 }
 
 static int
-read(Obj *obj, FILE *fp)
+readscns(Obj *obj, FILE *fp)
 {
-	int order;
-	long i, siz;
 	FILHDR *hdr;
-	SCNHDR *scn;
-	SYMENT *ent;
-	char *str = NULL;
 	struct coff32 *coff;
-	unsigned char buf[100];
+	SCNHDR *scn;
+	long i;
+	unsigned char buf[SCNHSZ];
 
-	assert(FILHSZ < sizeof(buf));
-	assert(SCNHSZ < sizeof(buf));
-	assert(SYMESZ < sizeof(buf));
-
 	coff  = obj->data;
 	hdr = &coff->hdr;
 
-	order = ORDER(obj->type);
-	if (fgetpos(fp, &obj->pos))
-		goto error;
-	if (fread(buf, FILHSZ, 1, fp) != 1)
-		goto error;
-	unpack_hdr(order, buf, hdr);
-
 	if (hdr->f_nscns > 0) {
 		scn = calloc(hdr->f_nscns, sizeof(*scn));
 		if (!scn)
-			goto error;
+			return 0;
 		coff->scns = scn;
 	}
-	if (hdr->f_nsyms > 0) {
-		ent = calloc(hdr->f_nsyms, sizeof(*ent));
-		if (!ent)
-			goto error;
-		coff->ents = ent;
-	}
-
 	if (fseek(fp, hdr->f_opthdr, SEEK_CUR) < 0)
-		goto error;
+		return 0;
 	for (i = 0; i < hdr->f_nscns; i++) {
 		if (fread(buf, SCNHSZ, 1, fp) < 0)
-			goto error;
-		unpack_scn(order, buf, &scn[i]);
+			return 0;
+		unpack_scn(ORDER(obj->type), buf, &scn[i]);
 	}
 
+	return 1;
+}
+
+static int
+readents(Obj *obj, FILE *fp)
+{
+	FILHDR *hdr;
+	struct coff32 *coff;
+	SYMENT *ent;
+	long i;
+	unsigned char buf[SYMESZ];
+
+	coff  = obj->data;
+	hdr = &coff->hdr;
+
+	if (hdr->f_nsyms > 0) {
+		ent = calloc(hdr->f_nsyms, sizeof(*ent));
+		if (!ent)
+			return 0;
+		coff->ents = ent;
+	}
 	if (fsetpos(fp, &obj->pos))
-		return -1;
+		return 0;
 	if (fseek(fp, hdr->f_symptr, SEEK_CUR) < 0)
-		return -1;
+		return 0;
 	for (i = 0; i < hdr->f_nsyms; i++) {
 		if (fread(buf, SYMESZ, 1, fp) != 1)
-			goto error;
-		unpack_ent(order, buf, &ent[i]);
+			return 0;
+		unpack_ent(ORDER(obj->type), buf, &ent[i]);
 	}
 
+	return 1;
+}
+
+static int
+readstr(Obj *obj, FILE *fp)
+{
+	FILHDR *hdr;
+	struct coff32 *coff;
+	long siz;
+	char *str;
+	unsigned char buf[10];
+
 	if (fread(buf, 4, 1, fp) != 1)
-		goto error;
-	unpack(order, buf, "l", &siz);
+		return 0;
+	unpack(ORDER(obj->type), buf, "l", &siz);
 	siz -= 4;
+	if (siz < 0)
+		return 0;
 	if (siz > 0) {
 		if (siz > SIZE_MAX)
-			goto error;
+			return 0;
 		str = malloc(siz);
 		if (!str)
-			goto error;
-		if (fread(str, siz, 1, fp) != 1)
-			goto error;
+			return 0;
 		coff->strtbl = str;
 		coff->strsiz = siz;
+
+		if (fread(str, siz, 1, fp) != 1)
+			return 0;
 	}
-	obj->data = coff;
+	return 1;
+}
 
-	if (mkindex(obj) < 0)
-		goto error;
+static int
+readhdr(Obj *obj, FILE *fp)
+{
+	FILHDR *hdr;
+	struct coff32 *coff;
+	unsigned char buf[FILHSZ];
 
+	coff  = obj->data;
+	hdr = &coff->hdr;
+
+	if (fread(buf, FILHSZ, 1, fp) != 1)
+		return 0;
+	unpack_hdr(ORDER(obj->type), buf, hdr);
+
+	return 1;
+}
+
+static int
+read(Obj *obj, FILE *fp)
+{
+	if (fgetpos(fp, &obj->pos))
+		goto error;
+	if (!readhdr(obj, fp))
+		goto error;
+	if (!readscns(obj, fp))
+		goto error;
+	if (!readents(obj, fp))
+		goto error;
+	if (!readstr(obj, fp))
+		goto error;
+	if (!mkindex(obj))
+		goto error;
 	return 0;
 
 error:
 	objreset(obj);
-
 	return -1;
 }