scc

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

commit 03b5aecd77d410af75c8236b09f8d70071b0552d
parent e8e24d5c05305a29469c5e339f8674718e943b3d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  1 Nov 2019 11:40:14 +0100

[ld] Recover pass2

Pass2 was disabled with the big rewrite of libmach. This patch
enables the code code again but further changes are needed.

Diffstat:
Minclude/scc/scc/mach.h | 2++
Msrc/cmd/ld/Makefile | 3+--
Msrc/cmd/ld/ld.h | 3++-
Msrc/cmd/ld/main.c | 6++++--
Msrc/cmd/ld/pass1.c | 1+
Msrc/cmd/ld/pass2.c | 50++++++++++++++------------------------------------
Msrc/cmd/ld/section.c | 34+++++++++++++++++++++++++++++++---
Msrc/libmach/newobj.c | 1+
8 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -23,6 +23,7 @@ struct obj { int type; long pos; void *data; + Obj *next; }; struct segment { @@ -34,6 +35,7 @@ struct segment { int type; int align; int nsec; + Section **sections; }; struct section { diff --git a/src/cmd/ld/Makefile b/src/cmd/ld/Makefile @@ -9,8 +9,7 @@ OBJS =\ symbol.o\ section.o\ pass1.o\ - -# pass2.o \ + pass2.o \ # pass3.o \ # pass4.o \ # pass5.o \ diff --git a/src/cmd/ld/ld.h b/src/cmd/ld/ld.h @@ -21,7 +21,7 @@ extern void debugsym(void); extern Section *lookupsec(char *name); extern void copy(Obj *obj, Section *osec, Section *sec); extern void grow(Section *sec, int nbytes); - +extern void merge(Segment *seg); extern void debugsec(void); /* globals */ @@ -35,4 +35,5 @@ extern int dflag; extern int gflag; extern char *Dflag; extern char *output, *entry; +extern Obj *objhead; extern Segment debug, text, rodata, data, bss; diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c @@ -66,10 +66,12 @@ static void ld(int argc, char*argv[]) { pass1(argc, argv); -/* pass2(argc, argv); + pass2(argc, argv); +/* pass3(argc, argv); pass4(argc, argv); - pass5(argc, argv); */ + pass5(argc, argv); +*/ debugsym(); debugsec(); } diff --git a/src/cmd/ld/pass1.c b/src/cmd/ld/pass1.c @@ -17,6 +17,7 @@ enum { }; int bintype = -1; +Obj *objhead; static int is_needed(Obj *obj) diff --git a/src/cmd/ld/pass2.c b/src/cmd/ld/pass2.c @@ -9,49 +9,27 @@ static void mksecs(void) { - Objlst *lp; - Objsec *sp; - Section *sec; - - for (lp = objhead; lp; lp = lp->next) { - for (sp = lp->obj->secs; sp; sp = sp->next) { - sec = section(sp->name); - if (sec->type == '?') { - sec->type = sp->type; - sec->flags = sp->flags; + int i; + Obj *obj; + Section sec, *sp; + + for (obj = objhead; obj; obj = obj->next) { + for (i = 0; getsec(obj, &i, &sec); i++) { + sp = lookupsec(sec.name); + if (sp->type == '?') { + sp->type = sec.type; + sp->flags = sec.flags; } - if (sec->type != sp->type || sec->flags != sp->flags) { + if (sp->type != sec.type || sp->flags != sec.flags) { error("incompatible definitions of section '%s'", - sec->name); + sp->name); } - /* TODO: use add symbol aligment */ - sec->size += sp->size; - } - } -} - -static void -merge(Segment *seg) -{ - Section *sec, **p; - int n = 0; - - for (sec = sechead; sec; sec = sec->next) { - if (sec->type != seg->type) - continue; - p = realloc(seg->sections, (n+1) * sizeof(*p)); - if (!p) { - error("ou of memory"); - exit(EXIT_FAILURE); + sp->size = sp->size+sp->align-1 & sp->align-1; + sp->size += sec.size; } - p[n++] = sec; - seg->sections = p; - seg->size += sec->size; } - - seg->nsec = n; } static void diff --git a/src/cmd/ld/section.c b/src/cmd/ld/section.c @@ -74,7 +74,36 @@ lookupsec(char *name) sp->hash = sectab[h]; sectab[h] = sp; - return linksec(&secs, sec); + sp->next = &secs; + sp->prev = secs.prev; + secs.prev->next = sp; + secs.prev = sp; + + return sec; +} + +void +merge(Segment *seg) +{ + struct sectab *sp; + Section *sec, **p; + int n = 0; + + for (sp = secs.next; sp != &secs; sp = sp->next) { + sec = &sp->sec; + if (sec->type != seg->type) + continue; + p = realloc(seg->sections, (n+1) * sizeof(*p)); + if (!p) { + error("out of memory"); + exit(EXIT_FAILURE); + } + p[n++] = sec; + seg->sections = p; + seg->size += sec->size; + } + + seg->nsec = n; } void @@ -143,4 +172,4 @@ debugsec(void) } } } -#endif -\ No newline at end of file +#endif diff --git a/src/libmach/newobj.c b/src/libmach/newobj.c @@ -24,6 +24,7 @@ newobj(int type) obj->type = type; obj->ops = objops[fmt]; + obj->next = NULL; if ((*obj->ops->new)(obj) < 0) { free(obj); return NULL;