shithub: scc

Download patch

ref: 0da5637da083a7e827d63fac3701de2e768aea54
parent: 0bdc41f75c7f007037d8e5ee20e0ecad88bc5558
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Feb 11 11:56:28 EST 2019

[libmach] Convert forsect() to objsect()

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -45,7 +45,6 @@
 	Objsym *head;
 	fpos_t pos;
 	int nsecs;
-	Objsect *sections;
 	void *data;
 };
 
@@ -58,10 +57,6 @@
                   int (*fn)(Objsym *sym, void *data),
                   void *data);
 
-extern int forsect(Obj *obj,
-                   int (*fn)(Objsect *sect, void *data),
-                   void *data);
-
 extern int archive(FILE *fp);
 extern long armember(FILE *fp, char *member);
 extern int objtype(FILE *fp, char **name);
@@ -72,8 +67,9 @@
 extern Objsym *objlookup(Obj *obj, char *name, int install);
 extern int objstrip(Obj *obj);
 extern int objwrite(Obj *obj, FILE *fp);
+extern int objsect(Obj *obj, Objsect **sect);
 extern long setindex(int type, long nsyms, Objsymdef *def, FILE *fp);
-extern long getindex(int type, long *nsyms, Objsymdef **def, FILE *fp);
+extern int getindex(int type, long *nsyms, Objsymdef **def, FILE *fp);
 extern char *namindex(int type);
 
 /* TODO */
--- a/src/cmd/ld.c
+++ b/src/cmd/ld.c
@@ -53,12 +53,12 @@
 	.prev = &refhead,
 };
 
-int sflag;		/* discard all the symbols */
-int xflag;		/* discard local symbols */
-int Xflag;		/* discard locals starting with 'L' */
-int rflag;		/* preserve relocation bits */
-int dflag;		/* define common even with rflag */
-int gflag;              /* preserve debug symbols */
+static int sflag;		/* discard all the symbols */
+static int xflag;		/* discard local symbols */
+static int Xflag;		/* discard locals starting with 'L' */
+static int rflag;		/* preserve relocation bits */
+static int dflag;		/* define common even with rflag */
+static int gflag;              /* preserve debug symbols */
 
 static int status;
 
--- a/src/cmd/size.c
+++ b/src/cmd/size.c
@@ -36,53 +36,54 @@
 	status = EXIT_FAILURE;
 }
 
-int
-newsect(Objsect *secp, void *data)
-{
-	unsigned long long *p;
-	struct sizes *sp = data;
-
-	switch (secp->type) {
-	case 'T':
-		p = &sp->text;
-		break;
-	case 'D':
-		p = &sp->data;
-		break;
-	case 'B':
-		p = &sp->bss;
-		break;
-	default:
-		return 1;
-	}
-
-	if (*p > ULLONG_MAX - secp->size)
-		return -1;
-	*p += secp->size;
-
-	return 1;
-}
-
 void
 newobject(FILE *fp, int type)
 {
+	int n, i;;
 	Obj *obj;
+	unsigned long long total, *p;
+	Objsect *secp;
 	struct sizes siz;
-	unsigned long long total;
 
 	if ((obj = objnew(type)) == NULL) {
 		error("out of memory");
-		goto error;
+		return;
 	}
 
 	if (objread(obj, fp) < 0) {
 		error("file corrupted");
-		goto error;
+		goto err1;
 	}
 
 	siz.text = siz.data = siz.bss = 0;
-	forsect(obj, newsect, &siz);
+	if ((n = objsect(obj, &secp)) < 0) {
+		error("out of memory");
+		goto err1;
+	}
 
+	for (i = 0; i < n; i++) {
+		switch (secp[i].type) {
+		case 'T':
+			p = &siz.text;
+			break;
+		case 'D':
+			p = &siz.data;
+			break;
+		case 'B':
+			p = &siz.bss;
+			break;
+		default:
+			continue;
+		}
+
+		if (*p > ULLONG_MAX - secp->size) {
+			error("integer overflow");
+			goto err2;
+		}
+			
+		*p += secp->size;
+	}
+
 	total = siz.text + siz.data + siz.bss;
 	printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n",
 	       siz.text,
@@ -95,9 +96,10 @@
 	tbss += siz.bss;
 	ttotal += total;
 
-error:
-	if (obj)
-		objdel(obj);
+err2:
+	free(secp);
+err1:
+	objdel(obj);
 }
 
 static int
--- a/src/libmach/.gitignore
+++ b/src/libmach/.gitignore
@@ -9,3 +9,4 @@
 getidx.c
 setidx.c
 namidx.c
+getsect.c
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -14,11 +14,11 @@
        objread.o \
        objreset.o \
        objstrip.o \
+       objsect.o \
        getindex.o \
        setindex.o \
        namindex.o \
        forsym.o \
-       forsect.o \
        formember.o \
        objtype.o \
        objwrite.o \
@@ -34,6 +34,7 @@
        getidx.o \
        setidx.o \
        namidx.o \
+       getsect.o \
 
 
 DIRS = coff32
@@ -40,6 +41,7 @@
 
 TBLS = setidx.c \
        getidx.c \
+       getsect.c \
        namidx.c \
        new.c \
        read.c \
--- a/src/libmach/coff32/Makefile
+++ b/src/libmach/coff32/Makefile
@@ -13,6 +13,7 @@
        coff32setidx.o \
        coff32getidx.o \
        coff32namidx.o \
+       coff32getsect.o \
 
 all: $(OBJS)
 
--- /dev/null
+++ b/src/libmach/coff32/coff32getsect.c
@@ -1,0 +1,73 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <scc/mach.h>
+
+#include "../libmach.h"
+#include "coff32.h"
+
+int
+coff32getsect(Obj *obj, Objsect **sectp)
+{
+	int nsecs;
+	unsigned sflags, type;
+	unsigned long flags;
+	FILHDR *hdr;
+	struct coff32 *coff;
+	SCNHDR *scn;
+	Objsect *secs, *sp;
+
+	coff  = obj->data;
+	hdr = &coff->hdr;
+	scn = coff->scns;
+
+	nsecs = 0;
+	secs = malloc(sizeof(Objsect) * hdr->f_nscns);
+	if (!secs)
+		return -1;
+
+	for (sp = secs; sp < &secs[hdr->f_nscns]; sp++) {
+		flags = scn->s_flags;
+
+		if (flags & STYP_TEXT) {
+			type = 'T';
+			sflags = SALLOC | SRELOC | SLOAD | SEXEC | SREAD;
+			if (flags & STYP_NOLOAD)
+				sflags |= SSHARED;
+		} else if (flags & STYP_DATA) {
+			type = 'D';
+			sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD;
+			if (flags & STYP_NOLOAD)
+				sflags |= SSHARED;
+		} else if (flags & STYP_BSS) {
+			type = 'B';
+			sflags = SALLOC | SREAD | SWRITE;
+		} else if (flags & STYP_INFO) {
+			type = 'N';
+			sflags = 0;
+		} else if (flags & STYP_LIB) {
+			type = 'T';
+			sflags = SRELOC;
+		} else if (flags & STYP_DSECT) {
+			type = 'D';
+			sflags = SRELOC;
+		} else if (flags & STYP_PAD) {
+			type = 'D';
+			sflags = SLOAD;
+		} else {
+			type = 'D';  /* We assume that STYP_REG is data */
+			sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD;
+		}
+
+		if (flags & STYP_NOLOAD)
+			sflags &= ~SLOAD;
+
+		sp->name = scn->s_name;
+		sp->offset = scn->s_scnptr;
+		sp->size = scn->s_size;
+		sp->type = type;
+		nsecs++;
+	}
+
+	return 1;
+}
--- a/src/libmach/coff32/coff32read.c
+++ b/src/libmach/coff32/coff32read.c
@@ -136,75 +136,6 @@
 }
 
 static int
-loadsections(Obj *obj, FILE *fp)
-{
-	size_t len;
-	unsigned sflags, type;
-	unsigned long flags;
-	FILHDR *hdr;
-	struct coff32 *coff;
-	SCNHDR *scn;
-	Objsect *secs, *sp;
-
-	coff  = obj->data;
-	hdr = &coff->hdr;
-	scn = coff->scns;
-
-	secs = malloc(sizeof(Objsect) * hdr->f_nscns);
-	if (!secs)
-		return 0;
-	obj->sections = secs;
-
-	for (sp = secs; sp < &secs[hdr->f_nscns]; sp++) {
-		flags = scn->s_flags;
-
-		if (flags & STYP_TEXT) {
-			type = 'T';
-			sflags = SALLOC | SRELOC | SLOAD | SEXEC | SREAD;
-			if (flags & STYP_NOLOAD)
-				sflags |= SSHARED;
-		} else if (flags & STYP_DATA) {
-			type = 'D';
-			sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD;
-			if (flags & STYP_NOLOAD)
-				sflags |= SSHARED;
-		} else if (flags & STYP_BSS) {
-			type = 'B';
-			sflags = SALLOC | SREAD | SWRITE;
-		} else if (flags & STYP_INFO) {
-			type = 'N';
-			sflags = 0;
-		} else if (flags & STYP_LIB) {
-			type = 'T';
-			sflags = SRELOC;
-		} else if (flags & STYP_DSECT) {
-			type = 'D';
-			sflags = SRELOC;
-		} else if (flags & STYP_PAD) {
-			type = 'D';
-			sflags = SLOAD;
-		} else {
-			type = 'D';  /* We assume that STYP_REG is data */
-			sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD;
-		}
-
-		if (flags & STYP_NOLOAD)
-			sflags &= ~SLOAD;
-
-		len = strlen(scn->s_name) + 1;
-		if ((sp->name = malloc(len)) == NULL)
-			return 0;
-
-		memcpy(sp->name, scn->s_name, len);
-		sp->offset = scn->s_scnptr;
-		sp->size = scn->s_size;
-		sp->type = type;
-		obj->nsecs++;
-	}
-	return 1;
-}
-
-static int
 readstr(Obj *obj, FILE *fp)
 {
 	FILHDR *hdr;
@@ -510,8 +441,6 @@
 	if (!readlines(obj, fp))
 		goto error;
 	if (!loadsyms(obj))
-		goto error;
-	if (!loadsections(obj, fp))
 		goto error;
 	return 0;
 
--- a/src/libmach/coff32/deps.mk
+++ b/src/libmach/coff32/deps.mk
@@ -9,6 +9,9 @@
 ./coff32getindex.o: $(INCDIR)/scc/scc/mach.h
 ./coff32getindex.o: ./../libmach.h
 ./coff32getindex.o: ./coff32.h
+./coff32getsect.o: $(INCDIR)/scc/scc/mach.h
+./coff32getsect.o: ./../libmach.h
+./coff32getsect.o: ./coff32.h
 ./coff32namidx.o: $(INCDIR)/scc/scc/mach.h
 ./coff32new.o: $(INCDIR)/scc/scc/mach.h
 ./coff32new.o: ./../libmach.h
--- a/src/libmach/deps.mk
+++ b/src/libmach/deps.mk
@@ -15,6 +15,9 @@
 ./coff32/coff32getindex.o: $(INCDIR)/scc/scc/mach.h
 ./coff32/coff32getindex.o: ./coff32/../libmach.h
 ./coff32/coff32getindex.o: ./coff32/coff32.h
+./coff32/coff32getsect.o: $(INCDIR)/scc/scc/mach.h
+./coff32/coff32getsect.o: ./coff32/../libmach.h
+./coff32/coff32getsect.o: ./coff32/coff32.h
 ./coff32/coff32namidx.o: $(INCDIR)/scc/scc/mach.h
 ./coff32/coff32new.o: $(INCDIR)/scc/scc/mach.h
 ./coff32/coff32new.o: ./coff32/../libmach.h
@@ -40,8 +43,6 @@
 ./del.o: ./libmach.h
 ./formember.o: $(INCDIR)/scc/scc/ar.h
 ./formember.o: $(INCDIR)/scc/scc/mach.h
-./forsect.o: $(INCDIR)/scc/scc/mach.h
-./forsect.o: ./libmach.h
 ./forsym.o: $(INCDIR)/scc/scc/mach.h
 ./forsym.o: ./libmach.h
 ./getidx.o: $(INCDIR)/scc/scc/mach.h
@@ -48,6 +49,8 @@
 ./getidx.o: ./libmach.h
 ./getindex.o: $(INCDIR)/scc/scc/mach.h
 ./getindex.o: ./libmach.h
+./getsect.o: $(INCDIR)/scc/scc/mach.h
+./getsect.o: ./libmach.h
 ./namidx.o: $(INCDIR)/scc/scc/mach.h
 ./namidx.o: ./libmach.h
 ./namindex.o: $(INCDIR)/scc/scc/mach.h
@@ -68,6 +71,8 @@
 ./objread.o: ./libmach.h
 ./objreset.o: $(INCDIR)/scc/scc/mach.h
 ./objreset.o: ./libmach.h
+./objsect.o: $(INCDIR)/scc/scc/mach.h
+./objsect.o: ./libmach.h
 ./objstrip.o: $(INCDIR)/scc/scc/mach.h
 ./objstrip.o: ./libmach.h
 ./objtype.o: $(INCDIR)/scc/scc/mach.h
--- a/src/libmach/forsect.c
+++ /dev/null
@@ -1,19 +1,0 @@
-#include <stdio.h>
-
-#include <scc/mach.h>
-
-#include "libmach.h"
-
-int
-forsect(Obj *obj, int (*fn)(Objsect *, void *), void *data)
-{
-	int i, r;
-
-	for (i = 0; i < obj->nsecs; i++) {
-		r = (*fn)(&obj->sections[i], data);
-		if (r <= 0)
-			return r;
-	}
-
-	return 1;
-}
--- a/src/libmach/getindex.c
+++ b/src/libmach/getindex.c
@@ -6,7 +6,7 @@
 
 extern getidxfun_t getidxv[];
 
-long
+int
 getindex(int type, long *nsyms, Objsymdef **head, FILE *fp)
 {
 	int fmt;
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -25,7 +25,6 @@
 
 enum freeflags {
 	FREESYM,
-	FREESECT,
 };
 
 typedef int (*newfun_t)(Obj *obj);
@@ -36,6 +35,7 @@
 typedef int (*writefun_t)(Obj *obj, FILE *fp);
 typedef long (*setidxfun_t)(int, long, Objsymdef *, FILE *);
 typedef int (*getidxfun_t)(int t, long *n, Objsymdef **def, FILE *fp);
+typedef int (*getsectfun_t)(Obj *obj, Objsect **secp);
 typedef char *(*namidxfun_t)(void);
 
 /* common functions */
@@ -58,5 +58,7 @@
 
 extern int coff32getindex(int type, long *nsyms, Objsymdef **def, FILE *fp);
 extern int coff32getidx(int order, long *nsyms, Objsymdef **def, FILE *fp);
+
+extern int coff32getsect(Obj *obj, Objsect **secp);
 
 extern char *coff32namidx(void);
--- a/src/libmach/objfree.c
+++ b/src/libmach/objfree.c
@@ -21,22 +21,9 @@
 	memset(obj->htab, 0, sizeof(obj->htab));
 }
 
-static void
-delsecs(Obj *obj)
-{
-	int i;
-
-	for (i = 0; i < obj->nsecs; i++)
-		free(obj->sections[i].name);
-	free(obj->sections);
-	obj->sections = NULL;
-}
-
 void
 objfree(Obj *obj, int what)
 {
 	if (what & FREESYM)
 		delsyms(obj);
-	if (what & FREESECT)
-		delsecs(obj);
 }
--- a/src/libmach/objnew.c
+++ b/src/libmach/objnew.c
@@ -24,7 +24,6 @@
 
 	obj->type = type;
 	obj->head = NULL;
-	obj->sections = NULL;
 	memset(obj->htab, 0, sizeof(obj->htab));
 
 	fn = newv[fmt];
--- a/src/libmach/objreset.c
+++ b/src/libmach/objreset.c
@@ -17,6 +17,6 @@
 		return -1;
 	fn = delv[fmt];
 	(*fn)(obj);
-	objfree(obj, FREESYM | FREESECT);
+	objfree(obj, FREESYM);
 	return 0;
 }
--- /dev/null
+++ b/src/libmach/objsect.c
@@ -1,0 +1,21 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+extern getsectfun_t getsectv[];
+
+int
+objsect(Obj *obj, Objsect **secp)
+{
+	int fmt;
+	getsectfun_t fn;
+
+	fmt = FORMAT(obj->type);
+	if (fmt >= NFORMATS)
+		return -1;
+
+	fn = getsectv[fmt];
+	return  (*fn)(obj, secp);
+}