scc

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

commit e3a04240fa62109f512c921db978df781a43ab61
parent 1c9e1f19f0b16a458ec20d349b2bcbe13e1b3efb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 11 Feb 2019 16:56:28 +0000

[libmach] Convert forsect() to objsect()

Diffstat:
Minclude/scc/scc/mach.h | 8++------
Msrc/cmd/ld.c | 12++++++------
Msrc/cmd/size.c | 70++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/libmach/.gitignore | 1+
Msrc/libmach/Makefile | 4+++-
Msrc/libmach/coff32/Makefile | 1+
Asrc/libmach/coff32/coff32getsect.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32/coff32read.c | 71-----------------------------------------------------------------------
Msrc/libmach/coff32/deps.mk | 3+++
Msrc/libmach/deps.mk | 9+++++++--
Dsrc/libmach/forsect.c | 19-------------------
Msrc/libmach/getindex.c | 2+-
Msrc/libmach/libmach.h | 4+++-
Msrc/libmach/objfree.c | 13-------------
Msrc/libmach/objnew.c | 1-
Msrc/libmach/objreset.c | 2+-
Asrc/libmach/objsect.c | 21+++++++++++++++++++++
17 files changed, 158 insertions(+), 156 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -45,7 +45,6 @@ struct object { Objsym *head; fpos_t pos; int nsecs; - Objsect *sections; void *data; }; @@ -58,10 +57,6 @@ 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); extern int objtype(FILE *fp, char **name); @@ -72,8 +67,9 @@ extern int objread(Obj *obj, FILE *fp); extern Objsym *objlookup(Obj *obj, char *name, int install); extern int objstrip(Obj *obj); extern int objwrite(Obj *obj, FILE *fp); +extern int objsect(Obj *obj, Objsect **sect); extern long setindex(int type, long nsyms, Objsymdef *def, FILE *fp); -extern long getindex(int type, long *nsyms, Objsymdef **def, FILE *fp); +extern int getindex(int type, long *nsyms, Objsymdef **def, FILE *fp); extern char *namindex(int type); /* TODO */ diff --git a/src/cmd/ld.c b/src/cmd/ld.c @@ -53,12 +53,12 @@ static Symbol refhead = { .prev = &refhead, }; -int sflag; /* discard all the symbols */ -int xflag; /* discard local symbols */ -int Xflag; /* discard locals starting with 'L' */ -int rflag; /* preserve relocation bits */ -int dflag; /* define common even with rflag */ -int gflag; /* preserve debug symbols */ +static int sflag; /* discard all the symbols */ +static int xflag; /* discard local symbols */ +static int Xflag; /* discard locals starting with 'L' */ +static int rflag; /* preserve relocation bits */ +static int dflag; /* define common even with rflag */ +static int gflag; /* preserve debug symbols */ static int status; diff --git a/src/cmd/size.c b/src/cmd/size.c @@ -36,52 +36,53 @@ 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) { + int n, i;; Obj *obj; + unsigned long long total, *p; + Objsect *secp; struct sizes siz; - unsigned long long total; if ((obj = objnew(type)) == NULL) { error("out of memory"); - goto error; + return; } if (objread(obj, fp) < 0) { error("file corrupted"); - goto error; + goto err1; } siz.text = siz.data = siz.bss = 0; - forsect(obj, newsect, &siz); + if ((n = objsect(obj, &secp)) < 0) { + error("out of memory"); + goto err1; + } + + for (i = 0; i < n; i++) { + switch (secp[i].type) { + case 'T': + p = &siz.text; + break; + case 'D': + p = &siz.data; + break; + case 'B': + p = &siz.bss; + break; + default: + continue; + } + + if (*p > ULLONG_MAX - secp->size) { + error("integer overflow"); + goto err2; + } + + *p += secp->size; + } total = siz.text + siz.data + siz.bss; printf("%llu\t%llu\t%llu\t%llu\t%llx\t%s\n", @@ -95,9 +96,10 @@ newobject(FILE *fp, int type) tbss += siz.bss; ttotal += total; -error: - if (obj) - objdel(obj); +err2: + free(secp); +err1: + objdel(obj); } static int diff --git a/src/libmach/.gitignore b/src/libmach/.gitignore @@ -9,3 +9,4 @@ write.c getidx.c setidx.c namidx.c +getsect.c diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -14,11 +14,11 @@ OBJS = addr2line.o \ objread.o \ objreset.o \ objstrip.o \ + objsect.o \ getindex.o \ setindex.o \ namindex.o \ forsym.o \ - forsect.o \ formember.o \ objtype.o \ objwrite.o \ @@ -34,12 +34,14 @@ OBJS = addr2line.o \ getidx.o \ setidx.o \ namidx.o \ + getsect.o \ DIRS = coff32 TBLS = setidx.c \ getidx.c \ + getsect.c \ namidx.c \ new.c \ read.c \ diff --git a/src/libmach/coff32/Makefile b/src/libmach/coff32/Makefile @@ -13,6 +13,7 @@ OBJS = coff32del.o \ coff32setidx.o \ coff32getidx.o \ coff32namidx.o \ + coff32getsect.o \ all: $(OBJS) diff --git a/src/libmach/coff32/coff32getsect.c b/src/libmach/coff32/coff32getsect.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "coff32.h" + +int +coff32getsect(Obj *obj, Objsect **sectp) +{ + int nsecs; + unsigned sflags, type; + unsigned long flags; + FILHDR *hdr; + struct coff32 *coff; + SCNHDR *scn; + Objsect *secs, *sp; + + coff = obj->data; + hdr = &coff->hdr; + scn = coff->scns; + + nsecs = 0; + secs = malloc(sizeof(Objsect) * hdr->f_nscns); + if (!secs) + return -1; + + for (sp = secs; sp < &secs[hdr->f_nscns]; sp++) { + flags = scn->s_flags; + + if (flags & STYP_TEXT) { + type = 'T'; + sflags = SALLOC | SRELOC | SLOAD | SEXEC | SREAD; + if (flags & STYP_NOLOAD) + sflags |= SSHARED; + } else if (flags & STYP_DATA) { + type = 'D'; + sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD; + if (flags & STYP_NOLOAD) + sflags |= SSHARED; + } else if (flags & STYP_BSS) { + type = 'B'; + sflags = SALLOC | SREAD | SWRITE; + } else if (flags & STYP_INFO) { + type = 'N'; + sflags = 0; + } else if (flags & STYP_LIB) { + type = 'T'; + sflags = SRELOC; + } else if (flags & STYP_DSECT) { + type = 'D'; + sflags = SRELOC; + } else if (flags & STYP_PAD) { + type = 'D'; + sflags = SLOAD; + } else { + type = 'D'; /* We assume that STYP_REG is data */ + sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD; + } + + if (flags & STYP_NOLOAD) + sflags &= ~SLOAD; + + sp->name = scn->s_name; + sp->offset = scn->s_scnptr; + sp->size = scn->s_size; + sp->type = type; + nsecs++; + } + + return 1; +} diff --git a/src/libmach/coff32/coff32read.c b/src/libmach/coff32/coff32read.c @@ -136,75 +136,6 @@ readhdr(Obj *obj, FILE *fp) } static int -loadsections(Obj *obj, FILE *fp) -{ - size_t len; - unsigned sflags, type; - unsigned long flags; - FILHDR *hdr; - struct coff32 *coff; - SCNHDR *scn; - Objsect *secs, *sp; - - coff = obj->data; - hdr = &coff->hdr; - scn = coff->scns; - - secs = malloc(sizeof(Objsect) * hdr->f_nscns); - if (!secs) - return 0; - obj->sections = secs; - - for (sp = secs; sp < &secs[hdr->f_nscns]; sp++) { - flags = scn->s_flags; - - if (flags & STYP_TEXT) { - type = 'T'; - sflags = SALLOC | SRELOC | SLOAD | SEXEC | SREAD; - if (flags & STYP_NOLOAD) - sflags |= SSHARED; - } else if (flags & STYP_DATA) { - type = 'D'; - sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD; - if (flags & STYP_NOLOAD) - sflags |= SSHARED; - } else if (flags & STYP_BSS) { - type = 'B'; - sflags = SALLOC | SREAD | SWRITE; - } else if (flags & STYP_INFO) { - type = 'N'; - sflags = 0; - } else if (flags & STYP_LIB) { - type = 'T'; - sflags = SRELOC; - } else if (flags & STYP_DSECT) { - type = 'D'; - sflags = SRELOC; - } else if (flags & STYP_PAD) { - type = 'D'; - sflags = SLOAD; - } else { - type = 'D'; /* We assume that STYP_REG is data */ - sflags = SALLOC | SRELOC | SLOAD | SWRITE | SREAD; - } - - if (flags & STYP_NOLOAD) - sflags &= ~SLOAD; - - len = strlen(scn->s_name) + 1; - if ((sp->name = malloc(len)) == NULL) - return 0; - - memcpy(sp->name, scn->s_name, len); - sp->offset = scn->s_scnptr; - sp->size = scn->s_size; - sp->type = type; - obj->nsecs++; - } - return 1; -} - -static int readstr(Obj *obj, FILE *fp) { FILHDR *hdr; @@ -511,8 +442,6 @@ coff32read(Obj *obj, FILE *fp) goto error; if (!loadsyms(obj)) goto error; - if (!loadsections(obj, fp)) - goto error; return 0; error: diff --git a/src/libmach/coff32/deps.mk b/src/libmach/coff32/deps.mk @@ -9,6 +9,9 @@ ./coff32getindex.o: $(INCDIR)/scc/scc/mach.h ./coff32getindex.o: ./../libmach.h ./coff32getindex.o: ./coff32.h +./coff32getsect.o: $(INCDIR)/scc/scc/mach.h +./coff32getsect.o: ./../libmach.h +./coff32getsect.o: ./coff32.h ./coff32namidx.o: $(INCDIR)/scc/scc/mach.h ./coff32new.o: $(INCDIR)/scc/scc/mach.h ./coff32new.o: ./../libmach.h diff --git a/src/libmach/deps.mk b/src/libmach/deps.mk @@ -15,6 +15,9 @@ ./coff32/coff32getindex.o: $(INCDIR)/scc/scc/mach.h ./coff32/coff32getindex.o: ./coff32/../libmach.h ./coff32/coff32getindex.o: ./coff32/coff32.h +./coff32/coff32getsect.o: $(INCDIR)/scc/scc/mach.h +./coff32/coff32getsect.o: ./coff32/../libmach.h +./coff32/coff32getsect.o: ./coff32/coff32.h ./coff32/coff32namidx.o: $(INCDIR)/scc/scc/mach.h ./coff32/coff32new.o: $(INCDIR)/scc/scc/mach.h ./coff32/coff32new.o: ./coff32/../libmach.h @@ -40,14 +43,14 @@ ./del.o: ./libmach.h ./formember.o: $(INCDIR)/scc/scc/ar.h ./formember.o: $(INCDIR)/scc/scc/mach.h -./forsect.o: $(INCDIR)/scc/scc/mach.h -./forsect.o: ./libmach.h ./forsym.o: $(INCDIR)/scc/scc/mach.h ./forsym.o: ./libmach.h ./getidx.o: $(INCDIR)/scc/scc/mach.h ./getidx.o: ./libmach.h ./getindex.o: $(INCDIR)/scc/scc/mach.h ./getindex.o: ./libmach.h +./getsect.o: $(INCDIR)/scc/scc/mach.h +./getsect.o: ./libmach.h ./namidx.o: $(INCDIR)/scc/scc/mach.h ./namidx.o: ./libmach.h ./namindex.o: $(INCDIR)/scc/scc/mach.h @@ -68,6 +71,8 @@ ./objread.o: ./libmach.h ./objreset.o: $(INCDIR)/scc/scc/mach.h ./objreset.o: ./libmach.h +./objsect.o: $(INCDIR)/scc/scc/mach.h +./objsect.o: ./libmach.h ./objstrip.o: $(INCDIR)/scc/scc/mach.h ./objstrip.o: ./libmach.h ./objtype.o: $(INCDIR)/scc/scc/mach.h diff --git a/src/libmach/forsect.c b/src/libmach/forsect.c @@ -1,19 +0,0 @@ -#include <stdio.h> - -#include <scc/mach.h> - -#include "libmach.h" - -int -forsect(Obj *obj, int (*fn)(Objsect *, void *), void *data) -{ - int i, r; - - for (i = 0; i < obj->nsecs; i++) { - r = (*fn)(&obj->sections[i], data); - if (r <= 0) - return r; - } - - return 1; -} diff --git a/src/libmach/getindex.c b/src/libmach/getindex.c @@ -6,7 +6,7 @@ extern getidxfun_t getidxv[]; -long +int getindex(int type, long *nsyms, Objsymdef **head, FILE *fp) { int fmt; diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -25,7 +25,6 @@ enum order { enum freeflags { FREESYM, - FREESECT, }; typedef int (*newfun_t)(Obj *obj); @@ -36,6 +35,7 @@ typedef int (*probefun_t)(unsigned char *buf, char **name); typedef int (*writefun_t)(Obj *obj, FILE *fp); typedef long (*setidxfun_t)(int, long, Objsymdef *, FILE *); typedef int (*getidxfun_t)(int t, long *n, Objsymdef **def, FILE *fp); +typedef int (*getsectfun_t)(Obj *obj, Objsect **secp); typedef char *(*namidxfun_t)(void); /* common functions */ @@ -59,4 +59,6 @@ extern long coff32setidx(int order, long nsyms, Objsymdef *head, FILE *fp); extern int coff32getindex(int type, long *nsyms, Objsymdef **def, FILE *fp); extern int coff32getidx(int order, long *nsyms, Objsymdef **def, FILE *fp); +extern int coff32getsect(Obj *obj, Objsect **secp); + extern char *coff32namidx(void); diff --git a/src/libmach/objfree.c b/src/libmach/objfree.c @@ -21,22 +21,9 @@ delsyms(Obj *obj) memset(obj->htab, 0, sizeof(obj->htab)); } -static void -delsecs(Obj *obj) -{ - int i; - - for (i = 0; i < obj->nsecs; i++) - free(obj->sections[i].name); - free(obj->sections); - obj->sections = NULL; -} - void objfree(Obj *obj, int what) { if (what & FREESYM) delsyms(obj); - if (what & FREESECT) - delsecs(obj); } diff --git a/src/libmach/objnew.c b/src/libmach/objnew.c @@ -24,7 +24,6 @@ objnew(int type) obj->type = type; obj->head = NULL; - obj->sections = NULL; memset(obj->htab, 0, sizeof(obj->htab)); fn = newv[fmt]; diff --git a/src/libmach/objreset.c b/src/libmach/objreset.c @@ -17,6 +17,6 @@ objreset(Obj *obj) return -1; fn = delv[fmt]; (*fn)(obj); - objfree(obj, FREESYM | FREESECT); + objfree(obj, FREESYM); return 0; } diff --git a/src/libmach/objsect.c b/src/libmach/objsect.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +extern getsectfun_t getsectv[]; + +int +objsect(Obj *obj, Objsect **secp) +{ + int fmt; + getsectfun_t fn; + + fmt = FORMAT(obj->type); + if (fmt >= NFORMATS) + return -1; + + fn = getsectv[fmt]; + return (*fn)(obj, secp); +}