scc

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

commit 3d5c5f4032f30a579d4ffa17cc77d7799676514d
parent bea6fce5f7aa228c91283ad94cc8b5544313cb07
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 28 Aug 2019 10:51:23 +0100

[libmach] Add getsec()

Diffstat:
Minclude/scc/scc/mach.h | 52++++++++++++----------------------------------------
Msrc/cmd/Makefile | 2+-
Msrc/cmd/size.c | 67+++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/libmach/Makefile | 1+
Msrc/libmach/coff32/Makefile | 1+
Msrc/libmach/coff32/coff32.c | 3++-
Msrc/libmach/coff32/coff32.h | 4++--
Msrc/libmach/getsym.c | 2++
Msrc/libmach/libmach.h | 29+++++++++++++++++++++++++++++
Msrc/libmach/readobj.c | 2++
10 files changed, 91 insertions(+), 72 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -1,9 +1,5 @@ -#define NR_SYMHASH 32 - -typedef struct objsec Objsec; typedef struct symbol Symbol; -typedef struct objseg Objseg; -typedef struct objops Objops; +typedef struct section Section; typedef struct obj Obj; enum sectype { @@ -17,59 +13,36 @@ enum sectype { SSHARED = 1 << 7, }; -struct objsec { +struct section { char *name; - int id; + unsigned long long base; + unsigned long long size; + unsigned flags; int type; + int index; int align; - unsigned flags; - long seek; - unsigned long long size, base; - Objsec *next; }; struct symbol { char *name; unsigned long long size; unsigned long long value; - void *aux; int index; char class; char type; }; -struct objseg { - unsigned long long size; - unsigned long long value; -}; - -struct objops { - int (*probe)(unsigned char *buf, char **name); - int (*new)(Obj *obj); - void (*del)(Obj *obj); - int (*read)(Obj *obj, FILE *fp); - int (*write)(Obj *obj, FILE *fp); - int (*strip)(Obj *obj); - int (*addr2line)(Obj *, unsigned long long , char *, int *); - Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym); - int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp); - int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp); -}; - -struct obj { - char *index; - Objops *ops; - int type; - long pos; - void *data; -}; - extern int archive(FILE *fp); extern long armember(FILE *fp, char *member); extern int objtype(FILE *fp, char **name); extern Obj *newobj(int type); extern void delobj(Obj *obj); + extern int readobj(Obj *obj, FILE *fp); +extern int writeobj(Obj *obj, FILE *fp); + +extern int strip(Obj *obj); + extern Symbol *getsym(Obj *obj, long *index, Symbol *sym); -extern int strip(Obj *obj);- \ No newline at end of file +extern Section *getsec(Obj *obj, long *index, Section *sec); diff --git a/src/cmd/Makefile b/src/cmd/Makefile @@ -6,8 +6,8 @@ include $(PROJECTDIR)/scripts/rules.mk TARGET = $(BINDIR)/nm \ $(BINDIR)/ar \ $(BINDIR)/strip \ + $(BINDIR)/size \ -# $(BINDIR)/size \ # $(BINDIR)/ranlib \ # $(BINDIR)/objdump \ # $(BINDIR)/objcopy \ diff --git a/src/cmd/size.c b/src/cmd/size.c @@ -38,27 +38,27 @@ error(char *fmt, ...) } static void -newobject(FILE *fp, int type) +sizeobj(FILE *fp, int type) { - int i; + long i; Obj *obj; unsigned long long total, *p; - Objsec *sp; struct sizes siz; + Section sec; - if ((obj = objnew(type)) == NULL) { - error("out of memory"); + if ((obj = newobj(type)) == NULL) { + error(strerror(errno)); return; } - if ((*obj->ops->read)(obj, fp) < 0) { - error("file corrupted"); + if (readobj(obj, fp) < 0) { + error(strerror(errno)); goto err; } siz.text = siz.data = siz.bss = 0; - for (sp = obj->secs; sp; sp = sp->next) { - switch (sp->type) { + for (i = 0; getsec(obj, &i, &sec); i++) { + switch (sec.type) { case 'R': case 'T': p = &siz.text; @@ -73,12 +73,12 @@ newobject(FILE *fp, int type) continue; } - if (*p > ULLONG_MAX - sp->size) { + if (*p > ULLONG_MAX - sec.size) { error("integer overflow"); goto err; } - *p += sp->size; + *p += sec.size; } total = siz.text + siz.data + siz.bss; @@ -94,24 +94,36 @@ newobject(FILE *fp, int type) ttotal += total; err: - (*obj->ops->del)(obj); + delobj(obj); } static void -newlib(FILE *fp) +sizelib(FILE *fp) { int t; - long r; + long off, cur; char memb[SARNAM+1]; - while ((r = armember(fp, memb)) > 0) { - membname = memb; - if ((t = objtype(fp, NULL)) != -1) - newobject(fp, t); - membname = NULL; + for (;;) { + cur = ftell(fp); + off = armember(fp, memb); + switch (off) { + case -1: + error("library corrupted"); + if (ferror(fp)) + error(strerror(errno)); + case 0: + return; + default: + membname = memb; + if ((t = objtype(fp, NULL)) != -1) + sizeobj(fp, t); + membname = NULL; + fseek(fp, cur, SEEK_SET); + fseek(fp, off, SEEK_CUR); + break; + } } - if (r < 0) - error("library corrupted"); } static void @@ -127,15 +139,12 @@ size(char *fname) } if ((t = objtype(fp, NULL)) != -1) - newobject(fp, t); + sizeobj(fp, t); else if (archive(fp)) - newlib(fp); + sizelib(fp); else error("bad format"); - if (ferror(fp)) - error(strerror(errno)); - fclose(fp); } @@ -175,8 +184,10 @@ main(int argc, char *argv[]) } if (fflush(stdout)) { - filename = "stdout"; - error(strerror(errno)); + fprintf(stderr, + "size: error writing in output:%s\n", + strerror(errno)); + status = 1; } return status; diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -14,6 +14,7 @@ OBJS = mach.o \ readobj.o \ writeobj.o \ getsym.o \ + getsec.o \ strip.o \ pack.o \ unpack.o \ diff --git a/src/libmach/coff32/Makefile b/src/libmach/coff32/Makefile @@ -17,6 +17,7 @@ OBJS = coff32.o \ coff32getidx.o \ coff32addr2line.o \ coff32getsym.o \ + coff32getsec.o \ all: $(OBJS) diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c @@ -5,7 +5,7 @@ #include "../libmach.h" #include "coff32.h" -Objops coff32 = { +struct objops coff32 = { .probe = coff32probe, .new = coff32new, .read = coff32read, @@ -16,4 +16,5 @@ Objops coff32 = { .del = coff32del, .write = coff32write, .getsym = coff32getsym, + .getsec = coff32getsec, }; diff --git a/src/libmach/coff32/coff32.h b/src/libmach/coff32/coff32.h @@ -39,4 +39,5 @@ extern int coff32xsetidx(int order, extern int coff32xgetidx(int order, long *nsyms, char ***namep, long **offsp, FILE *fp); -extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);- \ No newline at end of file +extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym); +extern Section *coff32getsec(Obj *obj, long *idx, Section *sec); diff --git a/src/libmach/getsym.c b/src/libmach/getsym.c @@ -2,6 +2,8 @@ #include <scc/mach.h> +#include "libmach.h" + Symbol * getsym(Obj *obj, long *index, Symbol *sym) { diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -4,6 +4,8 @@ #define ARCH(t) (((t) >> 5) & 0x1f) #define ORDER(t) (((t) >> 10) & 0x1f) +typedef struct objops Objops; + enum objformat { COFF32, NFORMATS, @@ -23,6 +25,33 @@ enum order { BIG_ENDIAN, }; +struct objops { + int (*probe)(unsigned char *buf, char **name); + + int (*new)(Obj *obj); + void (*del)(Obj *obj); + + int (*read)(Obj *obj, FILE *fp); + int (*write)(Obj *obj, FILE *fp); + + int (*strip)(Obj *obj); + int (*addr2line)(Obj *, unsigned long long , char *, int *); + + Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym); + Section *(*getsec)(Obj *obj, long *index, Section *sec); + + int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp); + int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp); +}; + +struct obj { + char *index; + struct objops *ops; + int type; + long pos; + void *data; +}; + /* common functions */ extern int pack(int order, unsigned char *dst, char *fmt, ...); extern int unpack(int order, unsigned char *src, char *fmt, ...); diff --git a/src/libmach/readobj.c b/src/libmach/readobj.c @@ -2,6 +2,8 @@ #include <scc/mach.h> +#include "libmach.h" + int readobj(Obj *obj, FILE *fp) {