scc

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

commit 14e979f0753a3a3ccd51fc81a6c3aa238e093f2f
parent ab1d0cf5a9ed003d4337a3bac11116e7fb1fde8b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 21 Aug 2019 21:58:58 +0100

[ld] Add pass5()

This function only writes the result back to a binary file.

Diffstat:
Minclude/scc/scc/mach.h | 4+++-
Msrc/cmd/ld/Makefile | 1+
Msrc/cmd/ld/deps.mk | 2++
Msrc/cmd/ld/ld.h | 2++
Msrc/cmd/ld/main.c | 4+++-
Msrc/cmd/ld/pass1.c | 37++++++++++++++++++++++++++-----------
Asrc/cmd/ld/pass5.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/Makefile | 2++
Msrc/libmach/coff32/Makefile | 1+
Asrc/libmach/coff32/coff32sync.c | 10++++++++++
Msrc/libmach/libmach.h | 2++
Asrc/libmach/objaddseg.c | 9+++++++++
Asrc/libmach/objsync.c | 20++++++++++++++++++++
13 files changed, 133 insertions(+), 13 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -76,7 +76,9 @@ extern long armember(FILE *fp, char *member); extern long setindex(int type, long nsyms, Objsymdef *def, FILE *fp); extern int getindex(int type, long *nsyms, Objsymdef **def, FILE *fp); + /* TODO */ -extern int objload(Obj *obj, Obj *to); +extern int objaddseg(Obj *obj, void *seg); +extern int objsync(Obj *obj); extern int objreloc(Obj *obj, char *sect, void *rel); extern int addr2line(Obj *obj, unsigned long long addr, char *fname, int *line); diff --git a/src/cmd/ld/Makefile b/src/cmd/ld/Makefile @@ -10,6 +10,7 @@ OBJS = main.o \ pass2.o \ pass3.o \ pass4.o \ + pass5.o \ all: $(TARGET) diff --git a/src/cmd/ld/deps.mk b/src/cmd/ld/deps.mk @@ -11,6 +11,8 @@ ./pass3.o: ./ld.h ./pass4.o: $(INCDIR)/scc/scc/mach.h ./pass4.o: ./ld.h +./pass5.o: $(INCDIR)/scc/scc/mach.h +./pass5.o: ./ld.h ./symbol.o: $(INCDIR)/scc/scc/mach.h ./symbol.o: $(INCDIR)/scc/scc/scc.h ./symbol.o: ./ld.h diff --git a/src/cmd/ld/ld.h b/src/cmd/ld/ld.h @@ -44,6 +44,7 @@ extern void pass1(int argc, char *argv[]); extern void pass2(int argc, char *argv[]); extern void pass3(int argc, char *argv[]); extern void pass4(int argc, char *argv[]); +extern void pass5(int argc, char *argv[]); /* main.c */ extern char *errstr(void); @@ -65,6 +66,7 @@ extern int rflag; extern int dflag; extern int gflag; extern char *Dflag; +extern char *output, *entry; extern Objlst *objhead; extern Section *sechead; extern Segment text, rodata, data, bss; diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c @@ -23,7 +23,7 @@ Segment rodata = {.type = 'R'}; Segment data = {.type = 'D'}; Segment bss = {.type = 'B'}; -static char *output = "a.out", *entry = "start"; +char *output = "a.out", *entry = "start"; static int status; char * @@ -60,6 +60,7 @@ cleanup(void) * pass2: Calculate the size of every segment. * pass3: Rebase all symbols in sections * pass4: Create the temporary files per section + * pass5: Create the temporary files per segment */ static void ld(int argc, char*argv[]) @@ -68,6 +69,7 @@ ld(int argc, char*argv[]) pass2(argc, argv); pass3(argc, argv); pass4(argc, argv); + pass5(argc, argv); debugsym(); debugsec(); } diff --git a/src/cmd/ld/pass1.c b/src/cmd/ld/pass1.c @@ -15,29 +15,45 @@ enum { INLIB, }; -static int bintype = -1; +int bintype = -1; static Symbol refhead = { .next = &refhead, .prev = &refhead, }; + +Symbol defhead = { + .next = &defhead, + .prev = &defhead, +}; static Objlst *objlast; Objlst *objhead; static Symbol * -undef(char *name) +linksym(Symbol *list, Symbol *sym) { - Symbol *sym = install(name); - - sym->next = &refhead; - sym->prev = refhead.prev; - refhead.prev->next = sym; - refhead.prev = sym; + sym->next = list; + sym->prev = list->prev; + list->prev->next = sym; + list->prev = sym; + return sym; +} +static Symbol * +unlinksym(Symbol *sym) +{ + sym->next->prev = sym->prev; + sym->prev->next = sym->next; return sym; } static Symbol * +undef(char *name) +{ + return linksym(&refhead, install(name)); +} + +static Symbol * define(Objsym *osym, Obj *obj) { Symbol *sym = lookup(osym->name); @@ -56,9 +72,8 @@ define(Objsym *osym, Obj *obj) sym->size = osym->size; sym->value = osym->value; - sym->next->prev = sym->prev; - sym->prev->next = sym->next; - sym->next = sym->prev = NULL; + unlinksym(sym); + linksym(&defhead, sym); return sym; } diff --git a/src/cmd/ld/pass5.c b/src/cmd/ld/pass5.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <scc/mach.h> + +#include "ld.h" + +extern int bintype; +extern Symbol defhead; + +/* + char *name; + int type; + int sect; + unsigned long long size; + unsigned long long value; +*/ + +void +pass5(int argc, char *argv[]) +{ + Obj *obj; + Symbol *sym; + Segment **segp; + Objsym *osym; + FILE *fp; + static Segment *segv[] = { + &text, + &data, + &bss, + /* TODO: debug, */ + NULL, + }; + + obj = objnew(bintype); + + for (segp = segv; *segp; segp++) + objaddseg(obj, *segp); + + for (sym = defhead.next; sym != &defhead; sym = sym->next) { + osym = objlookup(obj, sym->name, 1); + osym->size = sym->size; + osym->value = sym->value; + } + + /* TODO: write relocations */ + /* TODO: write line information */ + + fp = fopen(output, "wb"); + objsync(obj); + objwrite(obj, fp); +} diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -12,6 +12,8 @@ OBJS = objnew.o \ objsect.o \ objsyms.o \ objdel.o \ + objaddseg.o \ + objsync.o \ addr2line.o \ archive.o \ armember.o \ diff --git a/src/libmach/coff32/Makefile b/src/libmach/coff32/Makefile @@ -14,6 +14,7 @@ OBJS = coff32del.o \ coff32getidx.o \ coff32getsect.o \ coff32getsyms.o \ + coff32sync.o \ all: $(OBJS) diff --git a/src/libmach/coff32/coff32sync.c b/src/libmach/coff32/coff32sync.c @@ -0,0 +1,10 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "../libmach.h" + +int +coff32sync(Obj *obj) +{ +} diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -34,6 +34,7 @@ extern int unpack(int order, unsigned char *src, char *fmt, ...); extern int objfree(Obj *obj, int what); /* coff32 functions */ +/* TODO: Move this functions to a coff32 files */ extern long coff32index(int type, long nsyms, Objsymdef *head, FILE *fp); extern int coff32new(Obj *obj); extern void coff32del(Obj *obj); @@ -52,3 +53,4 @@ extern int coff32getsect(Obj *obj); extern char *coff32namidx(void); extern int coff32getsyms(Obj *obj); +extern int coff32sync(Obj *obj); diff --git a/src/libmach/objaddseg.c b/src/libmach/objaddseg.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#include <scc/mach.h> + +int +objaddseg(Obj *obj, void *seg) +{ + return 0; +} diff --git a/src/libmach/objsync.c b/src/libmach/objsync.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +static int (*funv[])(Obj *) = { + [COFF32] = coff32sync, +}; + +int +objsync(Obj *obj) +{ + int fmt; + + fmt = FORMAT(obj->type); + if (fmt >= NFORMATS) + return -1; + return (*funv[fmt])(obj); +}