shithub: scc

Download patch

ref: d31f41ad68c39eb244316ae777bcddfb98beca17
parent: a032cacd156cbd3605b5c8f4c4c1149d56711eaa
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 28 06:51:23 EDT 2019

[libmach] Add getsec()

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -1,9 +1,5 @@
-#define NR_SYMHASH 32
-
-typedef struct objsec Objsec;
 typedef struct symbol Symbol;
-typedef struct objseg Objseg;
-typedef struct objops Objops;
+typedef struct section Section;
 typedef struct obj Obj;
 
 enum sectype {
@@ -17,15 +13,14 @@
 	SSHARED = 1 << 7,
 };
 
-struct objsec {
+struct section {
 	char *name;
-	int id;
+	unsigned long long base;
+	unsigned long long size;
+	unsigned flags;
 	int type;
+	int index;
 	int align;
-	unsigned flags;
-	long seek;
-	unsigned long long size, base;
-	Objsec *next;
 };
 
 struct symbol {
@@ -32,38 +27,11 @@
 	char *name;
 	unsigned long long size;
 	unsigned long long value;
-	void *aux;
 	int index;
 	char class;
 	char type;
 };
 
-struct objseg {
-	unsigned long long size;
-	unsigned long long value;
-};
-
-struct objops {
-	int (*probe)(unsigned char *buf, char **name);
-	int (*new)(Obj *obj);
-	void (*del)(Obj *obj);
-	int (*read)(Obj *obj, FILE *fp);
-	int (*write)(Obj *obj, FILE *fp);
-	int (*strip)(Obj *obj);
-	int (*addr2line)(Obj *, unsigned long long , char *, int *);
-	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);
-};
-
-struct obj {
-	char *index;
-	Objops *ops;
-	int type;
-	long pos;
-	void *data;
-};
-
 extern int archive(FILE *fp);
 extern long armember(FILE *fp, char *member);
 
@@ -70,6 +38,11 @@
 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 writeobj(Obj *obj, FILE *fp);
+
+extern int strip(Obj *obj);
+
 extern Symbol *getsym(Obj *obj, long *index, Symbol *sym);
-extern int strip(Obj *obj);
\ No newline at end of file
+extern Section *getsec(Obj *obj, long *index, Section *sec);
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -6,8 +6,8 @@
 TARGET = $(BINDIR)/nm \
          $(BINDIR)/ar \
          $(BINDIR)/strip \
+         $(BINDIR)/size \
 
-#         $(BINDIR)/size \
 #         $(BINDIR)/ranlib \
 #         $(BINDIR)/objdump \
 #         $(BINDIR)/objcopy \
--- a/src/cmd/size.c
+++ b/src/cmd/size.c
@@ -38,27 +38,27 @@
 }
 
 static void
-newobject(FILE *fp, int type)
+sizeobj(FILE *fp, int type)
 {
-	int i;
+	long i;
 	Obj *obj;
 	unsigned long long total, *p;
-	Objsec *sp;
 	struct sizes siz;
+	Section sec;
 
-	if ((obj = objnew(type)) == NULL) {
-		error("out of memory");
+	if ((obj = newobj(type)) == NULL) {
+		error(strerror(errno));
 		return;
 	}
 
-	if ((*obj->ops->read)(obj, fp) < 0) {
-		error("file corrupted");
+	if (readobj(obj, fp) < 0) {
+		error(strerror(errno));
 		goto err;
 	}
 
 	siz.text = siz.data = siz.bss = 0;
-	for (sp = obj->secs; sp; sp = sp->next) {
-		switch (sp->type) {
+	for (i = 0; getsec(obj, &i, &sec); i++) {
+		switch (sec.type) {
 		case 'R':
 		case 'T':
 			p = &siz.text;
@@ -73,12 +73,12 @@
 			continue;
 		}
 
-		if (*p > ULLONG_MAX - sp->size) {
+		if (*p > ULLONG_MAX - sec.size) {
 			error("integer overflow");
 			goto err;
 		}
 			
-		*p += sp->size;
+		*p += sec.size;
 	}
 
 	total = siz.text + siz.data + siz.bss;
@@ -94,24 +94,36 @@
 	ttotal += total;
 
 err:
-	(*obj->ops->del)(obj);
+	delobj(obj);
 }
 
 static void
-newlib(FILE *fp)
+sizelib(FILE *fp)
 {
 	int t;
-	long r;
+	long off, cur;
 	char memb[SARNAM+1];
 
-	while ((r = armember(fp, memb)) > 0) {
-		membname = memb;
-		if ((t = objtype(fp, NULL)) != -1)
-			newobject(fp, t);
-		membname = NULL;
+	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)
+				sizeobj(fp, t);
+			membname = NULL;
+			fseek(fp, cur, SEEK_SET);
+			fseek(fp, off, SEEK_CUR);
+			break;
+		}
 	}
-	if (r < 0)
-		error("library corrupted");
 }
 
 static void
@@ -127,15 +139,12 @@
 	}
 
 	if ((t = objtype(fp, NULL)) != -1)
-		newobject(fp, t);
+		sizeobj(fp, t);
 	else if (archive(fp))
-		newlib(fp);
+		sizelib(fp);
 	else
 		error("bad format");
 
-	if (ferror(fp))
-		error(strerror(errno));
-
 	fclose(fp);
 }
 
@@ -175,8 +184,10 @@
 	}
 
 	if (fflush(stdout)) {
-		filename = "stdout";
-		error(strerror(errno));
+		fprintf(stderr,
+		        "size: error writing in output:%s\n",
+		        strerror(errno));
+		status = 1;
 	}
 
 	return status;
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -14,6 +14,7 @@
        readobj.o \
        writeobj.o \
        getsym.o \
+       getsec.o \
        strip.o \
        pack.o \
        unpack.o \
--- a/src/libmach/coff32/Makefile
+++ b/src/libmach/coff32/Makefile
@@ -17,6 +17,7 @@
        coff32getidx.o \
        coff32addr2line.o \
        coff32getsym.o \
+       coff32getsec.o \
 
 all: $(OBJS)
 
--- a/src/libmach/coff32/coff32.c
+++ b/src/libmach/coff32/coff32.c
@@ -5,7 +5,7 @@
 #include "../libmach.h"
 #include "coff32.h"
 
-Objops coff32 = {
+struct objops coff32 = {
 	.probe = coff32probe,
 	.new = coff32new,
 	.read = coff32read,
@@ -16,4 +16,5 @@
 	.del = coff32del,
 	.write = coff32write,
 	.getsym = coff32getsym,
+	.getsec = coff32getsec,
 };
--- a/src/libmach/coff32/coff32.h
+++ b/src/libmach/coff32/coff32.h
@@ -39,4 +39,5 @@
 extern int coff32xgetidx(int order,
                          long *nsyms, char ***namep, long **offsp, FILE *fp);
 
-extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);
\ No newline at end of file
+extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);
+extern Section *coff32getsec(Obj *obj, long *idx, Section *sec);
--- a/src/libmach/getsym.c
+++ b/src/libmach/getsym.c
@@ -2,6 +2,8 @@
 
 #include <scc/mach.h>
 
+#include "libmach.h"
+
 Symbol *
 getsym(Obj *obj, long *index, Symbol *sym)
 {
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -4,6 +4,8 @@
 #define ARCH(t) (((t) >> 5) & 0x1f)
 #define ORDER(t) (((t) >> 10) & 0x1f)
 
+typedef struct objops Objops;
+
 enum objformat {
 	COFF32,
 	NFORMATS,
@@ -21,6 +23,33 @@
 enum order {
 	LITTLE_ENDIAN,
 	BIG_ENDIAN,
+};
+
+struct objops {
+	int (*probe)(unsigned char *buf, char **name);
+
+	int (*new)(Obj *obj);
+	void (*del)(Obj *obj);
+
+	int (*read)(Obj *obj, FILE *fp);
+	int (*write)(Obj *obj, FILE *fp);
+
+	int (*strip)(Obj *obj);
+	int (*addr2line)(Obj *, unsigned long long , char *, int *);
+
+	Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym);
+	Section *(*getsec)(Obj *obj, long *index, Section *sec);
+
+	int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp);
+	int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp);
+};
+
+struct obj {
+	char *index;
+	struct objops *ops;
+	int type;
+	long pos;
+	void *data;
 };
 
 /* common functions */
--- a/src/libmach/readobj.c
+++ b/src/libmach/readobj.c
@@ -2,6 +2,8 @@
 
 #include <scc/mach.h>
 
+#include "libmach.h"
+
 int
 readobj(Obj *obj, FILE *fp)
 {