scc

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

commit 2a53cf364037e35fffa1a6950083ac55eb91c5e3
parent b99f13d9205071c49ee3bd5c6f10777f26913634
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 30 May 2018 19:48:46 +0100

[as] Add push() and pop()

These functions push and pop an object file from the list of
object files that has to be loaded.

Diffstat:
Mld/coff32.c | 6+++---
Mld/ld.h | 8++++++--
Mld/obj.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/ld/coff32.c b/ld/coff32.c @@ -371,6 +371,8 @@ static void unload(Obj *obj) { /* TODO */ + pop(obj); + delobj(obj); } static void @@ -379,7 +381,6 @@ pass1(Obj *obj) load(obj); if (obj->member && !obj->define) unload(obj); - } static void @@ -422,8 +423,7 @@ probe(char *fname, char *member, FILE *fp) return NULL; } - obj = newobj(fname, member); - obj->fp = fp; + obj = newobj(fname, member, fp); obj->unpack = unpack; obj->align = align; obj->fmt = &coff32; diff --git a/ld/ld.h b/ld/ld.h @@ -8,6 +8,7 @@ struct obj { char *member; FILE *fp; Fmt *fmt; + long offset; void *filhdr; void *scnhdr; @@ -22,7 +23,7 @@ struct obj { int align; int define; - struct obj *next; + struct obj *next, *prev; }; struct symbol { @@ -43,7 +44,10 @@ struct objfmt { }; /* obj.c */ -extern Obj *newobj(char *fname, char *member); +extern Obj *newobj(char *fname, char *member, FILE *fp); +extern void delobj(Obj *obj); +extern void pop(Obj *obj); +extern void push(Obj *obj); extern Symbol *lookup(char *name); /* main.c */ diff --git a/ld/obj.c b/ld/obj.c @@ -1,5 +1,6 @@ static char sccsid[] = "@(#) ./ld/obj.c"; +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,12 +11,53 @@ static char sccsid[] = "@(#) ./ld/obj.c"; #define NR_SYM_HASH 64 Obj *objlst; -static Obj *tail; +static Obj *objtail; +Symbol *sectlst; static Symbol *symtbl[NR_SYM_HASH]; +/* + * This function is always called with the last object created, + * so we can be sure that we only have to pop off the last + * object created + */ +void +pop(Obj *obj) +{ + objtail = objtail->prev; + if (!objtail) + objlst = NULL; +} + +void +push(Obj *obj) +{ + obj->prev = objlst; + obj->next = NULL; + + if (!objlst) { + objtail = objlst = obj; + } else { + objtail->next = obj; + objtail = obj; + } +} + +void +delobj(Obj *obj) +{ + free(obj->strtbl); + free(obj->sections); + free(obj->symbols); + free(obj->scnhdr); + free(obj->filhdr); + free(obj->fname); + free(obj->member); + free(obj); +} + Obj * -newobj(char *fname, char *member) +newobj(char *fname, char *member, FILE *fp) { Obj *obj; char *s, *t; @@ -37,12 +79,12 @@ newobj(char *fname, char *member) outmem(); obj->member = memcpy(s, member, len); } - obj->next = NULL; - if (!objlst) - tail = objlst = obj; - else - tail->next = obj; + obj->fp = fp; + if ((obj->offset = ftell(fp)) == EOF) { + fprintf(stderr, "ld: %s: %s\n", fname, strerror(errno)); + exit(1); + } return obj; }