scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit f5ed5507fb01df5285cfbc5cdf86bd7b7ed1e6be
parent fe7dfc544705bbdea43716d08628036a7f1a6cbe
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  8 Jan 2019 11:02:42 +0000

[size] Add a first version of size

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

Diffstat:
Minclude/scc/scc/mach.h | 4++++
Msrc/cmd/.gitignore | 1+
Msrc/cmd/Makefile | 6+++++-
Msrc/cmd/deps.mk | 2++
Asrc/cmd/size.c | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/libmach.h | 6+++++-
Msrc/libmach/object.c | 18+++++++++++++++++-
7 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -56,3 +56,7 @@ extern void objstrip(Obj *obj); 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); diff --git a/src/cmd/.gitignore b/src/cmd/.gitignore @@ -1,2 +1,3 @@ nm strip +size diff --git a/src/cmd/Makefile b/src/cmd/Makefile @@ -5,6 +5,7 @@ include $(PROJECTDIR)/scripts/rules.mk TARGET = $(BINDIR)/nm \ $(BINDIR)/strip \ + $(BINDIR)/size \ LIBS = -lmach @@ -18,8 +19,11 @@ $(BINDIR)/nm: nm $(BINDIR)/strip: strip cp strip $@ +$(BINDIR)/size: size + cp size $@ + clean: - rm -f nm strip + rm -f nm strip size dep: inc-dep diff --git 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 diff --git a/src/cmd/size.c b/src/cmd/size.c @@ -0,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; +} diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -28,11 +28,15 @@ enum order { 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, ...); diff --git a/src/libmach/object.c b/src/libmach/object.c @@ -180,7 +180,7 @@ objdel(Obj *obj) free(obj); } -void +int objstrip(Obj *obj) { int fmt; @@ -193,3 +193,19 @@ objstrip(Obj *obj) (*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); +}