shithub: scc

Download patch

ref: c50958a29245fe95b6f22473bfcc17f0cf5e3025
parent: b7bebb290854fb4aeff7f7112fda09d04818534f
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jan 8 07:12:17 EST 2019

[size] Add support for libraries and coff32

--- a/src/cmd/size.c
+++ b/src/cmd/size.c
@@ -39,11 +39,11 @@
 		error("out of memory");
 		goto error;
 	}
-	if (objread(obj, fp) < 0) {
+	if (objread(obj, fp) < 0 || objsize(obj, &text, &data, &bss) < 0) {
 		error("file corrupted");
 		goto error;
 	}
-	objsize(obj, &text, &data, &bss);
+
 	total = text + data + bss;
 	printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n",
 	       text, data, bss, total, total, filename);
@@ -98,7 +98,7 @@
 static void
 usage(void)
 {
-	fputs("usage: size [-t] file ...\n", stderr);
+	fputs("usage: size [-t] [file...]\n", stderr);
 	exit(EXIT_FAILURE);
 }
 
@@ -115,12 +115,14 @@
 		usage();
 	} ARGEND
 
-	if (argc == 1)
-		usage;
-
 	puts("text\tdata\tbss\tdec\thex\tfilename");
-	for (argc--; argc > 0; argc--)
-		size(*argv++);
+
+	if (argc == 0) {
+		size("a.out");
+	} else {
+		for (; *argv; ++argv)
+			size(*argv);
+	}
 
 	if (tflag) {
 		total = ttext + tdata + tbss;
--- a/src/cmd/strip.c
+++ b/src/cmd/strip.c
@@ -85,7 +85,7 @@
 static void
 usage(void)
 {
-	fputs("usage: strip file ...\n", stderr);
+	fputs("usage: strip [file...]\n", stderr);
 	exit(EXIT_FAILURE);
 }
 
@@ -97,10 +97,12 @@
 		usage();
 	} ARGEND
 
-	if (argc == 1)
-		usage;
+	if (argc == 0) {
+		strip("a.out");
+	} else {
+		for (; *argv; ++argv)
+			strip(*argv);
+	}
 
-	for (argc--; argc > 0; argc--)
-		strip(*argv++);
 	return status;
 }
--- a/src/libmach/coff32.c
+++ b/src/libmach/coff32.c
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <ctype.h>
+#include <limits.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -361,19 +362,55 @@
 	return 0;
 }
 
-static int
+static void
 strip(Obj *obj)
 {
 	struct coff32 *coff = obj->data;
 	FILHDR *hdr;
 
-	if (coff) {
-		hdr = &coff->hdr;
-		free(coff->ents);
-		coff->ents = NULL;
-		hdr->f_nsyms = 0;
-		hdr->f_symptr = 0;
+	hdr = &coff->hdr;
+	free(coff->ents);
+	coff->ents = NULL;
+	hdr->f_nsyms = 0;
+	hdr->f_symptr = 0;
+}
+
+static int
+size(Obj *obj,
+     unsigned long long *text,
+     unsigned long long *data,
+     unsigned long long *bss)
+{
+	int i;
+	long flags;
+	FILHDR *hdr;
+	struct coff32 *coff;
+	SCNHDR *scn, *lim;
+	unsigned long long *p;
+
+	*text = 0;
+	*data = 0;
+	*bss = 0;
+
+	coff  = obj->data;
+	hdr = &coff->hdr;
+
+	lim = &coff->scns[hdr->f_nscns];
+	for (scn = coff->scns; scn < lim; scn++) {
+		flags = scn->s_flags;
+		if (flags & STYP_TEXT)
+			p = text;
+		else if (flags & STYP_DATA)
+			p = data;
+		else if (flags & STYP_BSS)
+			p = bss;
+		else
+			continue;
+		if (*p > ULONG_MAX - scn->s_size)
+			return -1;
+		*p += scn->s_size;
 	}
+	return 0;
 }
 
 struct format objcoff32 = {
@@ -383,4 +420,5 @@
 	.read = read,
 	.write = write,
 	.strip = strip,
+	.size = size,
 };
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -28,15 +28,15 @@
 
 struct format {
 	int (*probe)(unsigned char *buf, char **name);
-	int (*strip)(Obj *obj);
+	void (*strip)(Obj *obj);
 	int (*new)(Obj *obj);
 	int (*read)(Obj *obj, FILE *fp);
 	int (*write)(Obj *obj, FILE *fp);
 	void (*del)(Obj *obj);
-	void (*size)(Obj *obj,
-                 unsigned long long *,
-                 unsigned long long *,
-                 unsigned long long *);
+	int (*size)(Obj *obj,
+                unsigned long long *,
+                unsigned long long *,
+                unsigned long long *);
 };
 
 extern int pack(int order, unsigned char *dst, char *fmt, ...);
--- a/src/libmach/object.c
+++ b/src/libmach/object.c
@@ -210,6 +210,5 @@
 	if (fmt >= NFORMATS)
 		return -1;
 	op = objfmt[fmt];
-	(*op->size)(obj, text, data, bss);
-	return 0;
+	return (*op->size)(obj, text, data, bss);
 }