scc

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

commit 71bb98c5705ca7e5e8fee2b3f0fb9725065e9db2
parent 68cbeec5a7dc36dfa0809236e1cfcf15b2f6489a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sun, 10 Feb 2019 07:03:45 +0000

[libmach] Introduce forsym() and forsect()

Objtraverse() was traversing only symbols. As we didn't
have a way to run ovr sections we had an ad-hoc function
,objsize, to calculate the size of a binary but it can
be done using a traverse function for sections.

Diffstat:
Minclude/scc/scc/mach.h | 14+++++++-------
Msrc/cmd/nm.c | 2+-
Msrc/cmd/ranlib.c | 2+-
Msrc/cmd/size.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++--------
Msrc/libmach/Makefile | 4++--
Asrc/libmach/forsect.c | 18++++++++++++++++++
Asrc/libmach/forsym.c | 17+++++++++++++++++
Dsrc/libmach/objsize.c | 40----------------------------------------
Dsrc/libmach/objtraverse.c | 17-----------------
9 files changed, 96 insertions(+), 76 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -55,9 +55,13 @@ extern int artraverse(FILE *fp, int (*fn)(FILE *, char *, void *), void *data); -extern int objtraverse(Obj *obj, - int (*fn)(Objsym *sym, void *data), - void *data); +extern int forsym(Obj *obj, + int (*fn)(Objsym *sym, void *data), + void *data); + +extern int forsect(Obj *obj, + int (*fn)(Objsect *sect, void *data), + void *data); extern int archive(FILE *fp); extern long armember(FILE *fp, char *member); @@ -68,10 +72,6 @@ extern int objreset(Obj *obj); extern int objread(Obj *obj, FILE *fp); extern Objsym *objlookup(Obj *obj, char *name); extern int objstrip(Obj *obj); -extern int objsize(Obj *obj, - unsigned long long *text, - unsigned long long *data, - unsigned long long *bss); extern long arindex(int type, long nsyms, Objsymdef *def, FILE *fp); extern int objwrite(Obj *obj, FILE *fp); diff --git a/src/cmd/nm.c b/src/cmd/nm.c @@ -158,7 +158,7 @@ newobject(FILE *fp, int type) if (objread(obj, fp) < 0) goto error; - if (!objtraverse(obj, newsym, &tbl)) + if (!forsym(obj, newsym, &tbl)) goto error; printsyms(tbl.buf, tbl.nsyms); diff --git a/src/cmd/ranlib.c b/src/cmd/ranlib.c @@ -150,7 +150,7 @@ newmember(FILE *fp, char *nam, void *data) goto error; } - if (!objtraverse(obj, newsymbol, NULL)) { + if (!forsym(obj, newsymbol, NULL)) { error("traversing object file"); goto error; } diff --git a/src/cmd/size.c b/src/cmd/size.c @@ -1,4 +1,5 @@ #include <errno.h> +#include <limits.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -7,6 +8,12 @@ #include <scc/arg.h> #include <scc/mach.h> +struct sizes { + unsigned long long text; + unsigned long long data; + unsigned long long bss; +}; + static int status; static char *filename, *membname; static int tflag; @@ -29,28 +36,63 @@ error(char *fmt, ...) status = EXIT_FAILURE; } +int +newsect(Objsect *secp, void *data) +{ + unsigned long long *p; + struct sizes *sp = data; + + switch (secp->type) { + case 'T': + p = &sp->text; + break; + case 'D': + p = &sp->data; + break; + case 'B': + p = &sp->bss; + break; + default: + return 1; + } + + if (*p > ULLONG_MAX - secp->size) + return -1; + *p += secp->size; + + return 1; +} + void newobject(FILE *fp, int type) { Obj *obj; - unsigned long long text, data, bss, total; + struct sizes siz; + unsigned long long total; if ((obj = objnew(type)) == NULL) { error("out of memory"); goto error; } - if (objread(obj, fp) < 0 || objsize(obj, &text, &data, &bss) < 0) { + + if (objread(obj, fp) < 0) { error("file corrupted"); goto error; } - total = text + data + bss; - printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n", - text, data, bss, total, total, filename); + siz.text = siz.data = siz.bss = 0; + forsect(obj, newsect, &siz); - ttext += text; - tdata += data; - tbss += bss; + total = siz.text + siz.data + siz.bss; + printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n", + siz.text, + siz.data, + siz.bss, + total, total, filename); + + ttext += siz.text; + tdata += siz.data; + tbss += siz.bss; ttotal += total; error: diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -16,9 +16,9 @@ OBJS = addr2line.o \ objpos.o \ objread.o \ objreset.o \ - objsize.o \ objstrip.o \ - objtraverse.o \ + forsym.o \ + forsect.o \ objtype.o \ objwrite.o \ objfree.o \ diff --git a/src/libmach/forsect.c b/src/libmach/forsect.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +int +forsect(Obj *obj, int (*fn)(Objsect *, void *), void *data) +{ + int i; + + for (i = 0; i < obj->nsecs; i++) { + if ((*fn)(&obj->sections[i], data)) + return 0; + } + + return 1; +} diff --git a/src/libmach/forsym.c b/src/libmach/forsym.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +int +forsym(Obj *obj, int (*fn)(Objsym *, void *), void *data) +{ + Objsym *sym; + + for (sym = obj->head; sym; sym = sym->next) { + if (!(*fn)(sym, data)) + return 0; + } + return 1; +} diff --git a/src/libmach/objsize.c b/src/libmach/objsize.c @@ -1,40 +0,0 @@ -#include <limits.h> -#include <stdio.h> - -#include <scc/mach.h> - -#include "libmach.h" - -int -objsize(Obj *obj, - unsigned long long *text, - unsigned long long *data, - unsigned long long *bss) -{ - Objsect *sp, *secs = obj->sections; - unsigned long long *p; - - *text = 0; - *data = 0; - *bss = 0; - for (sp =secs; sp < &secs[obj->nsecs]; sp++) { - switch (sp->type) { - case 'T': - p = text; - break; - case 'D': - p = data; - break; - case 'B': - p = bss; - break; - default: - continue; - } - - if (*p > ULLONG_MAX - sp->size) - return -1; - *p += sp->size; - } - return 0; -} diff --git a/src/libmach/objtraverse.c b/src/libmach/objtraverse.c @@ -1,17 +0,0 @@ -#include <stdio.h> - -#include <scc/mach.h> - -#include "libmach.h" - -int -objtraverse(Obj *obj, int (*fn)(Objsym *, void *), void *data) -{ - Objsym *sym; - - for (sym = obj->head; sym; sym = sym->next) { - if (!(*fn)(sym, data)) - return 0; - } - return 1; -}