shithub: scc

Download patch

ref: b7bebb290854fb4aeff7f7112fda09d04818534f
parent: d0a9d4f58eb08bf3d1ffff3ce0da5b9d9f4b497a
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jan 8 06:43:07 EST 2019

[size] Add support for libraries

--- a/src/cmd/size.c
+++ b/src/cmd/size.c
@@ -8,7 +8,7 @@
 #include <scc/mach.h>
 
 static int status;
-static char *filename;
+static char *filename, *membname;
 static int tflag;
 static unsigned long long ttext, tdata, tbss, ttotal;
 char *argv0;
@@ -20,6 +20,8 @@
 
 	va_start(va, fmt);
 	fprintf(stderr, "size: %s: ", filename);
+	if (membname)
+		fprintf(stderr, "%s: ", membname);
 	vfprintf(stderr, fmt, va);
 	putc('\n', stderr);
 	va_end(va);
@@ -27,35 +29,24 @@
 	status = EXIT_FAILURE;
 }
 
-static void
-size(char *fname)
+void
+newobject(FILE *fp, int type)
 {
-	int type;
 	Obj *obj;
-	FILE *fp;
 	unsigned long long text, data, bss, total;
 
-	filename = fname;
-	if ((fp = fopen(fname, "rb")) == NULL) {
-		error(strerror(errno));
-		return;
-	}
-	if ((type = objtype(fp, NULL)) < 0) {
-		error(strerror(errno));
-		goto err1;
-	}
 	if ((obj = objnew(type)) == NULL) {
 		error("out of memory");
-		goto err1;
+		goto error;
 	}
 	if (objread(obj, fp) < 0) {
 		error("file corrupted");
-		goto err2;
+		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, fname);
+	       text, data, bss, total, total, filename);
 
 	ttext += text;
 	tdata += data;
@@ -62,11 +53,46 @@
 	tbss += bss;
 	ttotal += total;
 
-err2:
-	objdel(obj);
-err1:
+error:
+	if (obj)
+		objdel(obj);
+}
+
+static int
+newmember(FILE *fp, char *name, void *data)
+{
+	int t;
+
+	membname = name;
+	if ((t = objtype(fp, NULL)) != -1)
+		newobject(fp, t);
+
+	return 1;
+}
+
+static void
+size(char *fname)
+{
+	int t;
+	FILE *fp;
+
+	filename = fname;
+	if ((fp = fopen(fname, "rb")) == NULL) {
+		error(strerror(errno));
+		return;
+	}
+
+	if ((t = objtype(fp, NULL)) != -1)
+		newobject(fp, t);
+	else if (archive(fp))
+		artraverse(fp, newmember, NULL);
+	else
+		error("bad format");
+
+	if (ferror(fp))
+		error(strerror(errno));
+
 	fclose(fp);
-	return;
 }
 
 static void