shithub: scc

Download patch

ref: 433b3e94d16471eac86a328f3016617be0f382b7
parent: 5b7017f04867f0666222a6466ac016ab395fe128
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Jan 8 06:02:42 EST 2019

[size] Add a first version of size

This version is not fully functional and it doesn't support libraries.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -56,3 +56,7 @@
 extern int objload(Obj *obj, Obj *to);
 extern int objreloc(Obj *obj, char *sect, void *rel);
 extern int objwrite(Obj *obj, FILE *fp);
+extern void objsize(Obj *obj,
+                    unsigned long long *text,
+                    unsigned long long *data,
+                    unsigned long long *bss);
--- a/src/cmd/.gitignore
+++ b/src/cmd/.gitignore
@@ -1,2 +1,3 @@
 nm
 strip
+size
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -5,6 +5,7 @@
 
 TARGET = $(BINDIR)/nm \
          $(BINDIR)/strip \
+         $(BINDIR)/size \
 
 LIBS   = -lmach
 
@@ -18,8 +19,11 @@
 $(BINDIR)/strip: strip
 	cp strip $@
 
+$(BINDIR)/size: size
+	cp size $@
+
 clean:
-	rm -f nm strip
+	rm -f nm strip size
 
 dep: inc-dep
 
--- a/src/cmd/deps.mk
+++ b/src/cmd/deps.mk
@@ -1,5 +1,7 @@
 #deps
 nm.o: $(INCDIR)/scc/scc/arg.h
 nm.o: $(INCDIR)/scc/scc/mach.h
+size.o: $(INCDIR)/scc/scc/arg.h
+size.o: $(INCDIR)/scc/scc/mach.h
 strip.o: $(INCDIR)/scc/scc/arg.h
 strip.o: $(INCDIR)/scc/scc/mach.h
--- /dev/null
+++ b/src/cmd/size.c
@@ -1,0 +1,111 @@
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/arg.h>
+#include <scc/mach.h>
+
+static int status;
+static char *filename;
+static int tflag;
+static unsigned long long ttext, tdata, tbss, ttotal;
+char *argv0;
+
+static void
+error(char *fmt, ...)
+{
+	va_list va;
+
+	va_start(va, fmt);
+	fprintf(stderr, "size: %s: ", filename);
+	vfprintf(stderr, fmt, va);
+	putc('\n', stderr);
+	va_end(va);
+
+	status = EXIT_FAILURE;
+}
+
+static void
+size(char *fname)
+{
+	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;
+	}
+	if (objread(obj, fp) < 0) {
+		error("file corrupted");
+		goto err2;
+	}
+	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);
+
+	ttext += text;
+	tdata += data;
+	tbss += bss;
+	ttotal += total;
+
+err2:
+	objdel(obj);
+err1:
+	fclose(fp);
+	return;
+}
+
+static void
+usage(void)
+{
+	fputs("usage: size [-t] file ...\n", stderr);
+	exit(EXIT_FAILURE);
+}
+
+int
+main(int argc, char *argv[])
+{
+	unsigned long long total;
+
+	ARGBEGIN {
+	case 't':
+		tflag = 1;
+		break;
+	default:
+		usage();
+	} ARGEND
+
+	if (argc == 1)
+		usage;
+
+	puts("text\tdata\tbss\tdec\thex\tfilename");
+	for (argc--; argc > 0; argc--)
+		size(*argv++);
+
+	if (tflag) {
+		total = ttext + tdata + tbss;
+		printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n",
+		       ttext, tdata, tbss, total, total, "(TOTALS)");
+	}
+
+	if (fflush(stdout)) {
+		filename = "stdout";
+		error(strerror(errno));
+	}
+
+	return status;
+}
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -28,11 +28,15 @@
 
 struct format {
 	int (*probe)(unsigned char *buf, char **name);
-	void (*strip)(Obj *obj);
+	int (*strip)(Obj *obj);
 	int (*new)(Obj *obj);
 	int (*read)(Obj *obj, FILE *fp);
 	int (*write)(Obj *obj, FILE *fp);
 	void (*del)(Obj *obj);
+	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
@@ -180,7 +180,7 @@
 	free(obj);
 }
 
-void
+int
 objstrip(Obj *obj)
 {
 	int fmt;
@@ -192,4 +192,20 @@
 	op = objfmt[fmt];
 	(*op->strip)(obj);
 	delsyms(obj);
+}
+
+void
+objsize(Obj *obj,
+        unsigned long long *text,
+        unsigned long long *data,
+        unsigned long long *bss)
+{
+	int fmt;
+	struct format *op;
+
+	fmt = FORMAT(obj->type);
+	if (fmt >= NFORMATS)
+		return -1;
+	op = objfmt[fmt];
+	(*op->size)(obj, text, data, bss);
 }