scc

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

commit 0c7d2a91ce6786c090baf1cf99ce0f5a236fac88
parent 052263553c1014478d3d950edb92d265552a88a4
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  8 Jan 2019 12:12:17 +0000

[size] Add support for libraries and coff32

Diffstat:
Msrc/cmd/size.c | 18++++++++++--------
Msrc/cmd/strip.c | 12+++++++-----
Msrc/libmach/coff32.c | 52+++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/libmach/libmach.h | 10+++++-----
Msrc/libmach/object.c | 3+--
5 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/src/cmd/size.c b/src/cmd/size.c @@ -39,11 +39,11 @@ newobject(FILE *fp, int type) 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 @@ size(char *fname) 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 @@ main(int argc, char *argv[]) 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; diff --git a/src/cmd/strip.c b/src/cmd/strip.c @@ -85,7 +85,7 @@ err: static void usage(void) { - fputs("usage: strip file ...\n", stderr); + fputs("usage: strip [file...]\n", stderr); exit(EXIT_FAILURE); } @@ -97,10 +97,12 @@ main(int argc, char *argv[]) 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; } diff --git 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 @@ new(Obj *obj) 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 @@ struct format objcoff32 = { .read = read, .write = write, .strip = strip, + .size = size, }; diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -28,15 +28,15 @@ enum order { 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, ...); diff --git a/src/libmach/object.c b/src/libmach/object.c @@ -210,6 +210,5 @@ objsize(Obj *obj, if (fmt >= NFORMATS) return -1; op = objfmt[fmt]; - (*op->size)(obj, text, data, bss); - return 0; + return (*op->size)(obj, text, data, bss); }