scc

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

commit a15a20fdd53e15e9250237d2c7c9d112d5e3cd01
parent 9a40ee5c8c5466c8324204c8a185e8b2dd2dac0b
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 19 Aug 2019 17:02:14 +0100

[ld] Add pass4

This pass is combining every section in a
temporary file. This is only a skeleton
because it doesn't care about alignment
or rellocations.

Diffstat:
Msrc/cmd/ld/deps.mk | 2++
Msrc/cmd/ld/ld.h | 4++--
Msrc/cmd/ld/main.c | 14++++++++++----
Msrc/cmd/ld/pass2.c | 9+--------
Asrc/cmd/ld/pass4.c | 39+++++++++++++++++++++++++++++++++++++++
5 files changed, 54 insertions(+), 14 deletions(-)

diff --git a/src/cmd/ld/deps.mk b/src/cmd/ld/deps.mk @@ -9,6 +9,8 @@ ./pass2.o: ./ld.h ./pass3.o: $(INCDIR)/scc/scc/mach.h ./pass3.o: ./ld.h +./pass4.o: $(INCDIR)/scc/scc/mach.h +./pass4.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 @@ -8,8 +8,8 @@ typedef struct segment Segment; struct section { char *name; - unsigned long base; - unsigned long long size; + unsigned long long base; + unsigned long size; unsigned flags; int type; FILE *fp; diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c @@ -8,10 +8,6 @@ #include "ld.h" -char *output = "a.out", *entry = "start"; - -char *filename, *membname; - int sflag; /* discard all the symbols */ int xflag; /* discard local symbols */ int Xflag; /* discard locals starting with 'L' */ @@ -20,6 +16,14 @@ int dflag; /* define common even with rflag */ int gflag; /* preserve debug symbols */ char *Dflag; /* size of data */ +char *filename, *membname; + +Segment text = {.type = 'T'}; +Segment rodata = {.type = 'R'}; +Segment data = {.type = 'D'}; +Segment bss = {.type = 'B'}; + +static char *output = "a.out", *entry = "start"; static int status; char * @@ -55,6 +59,7 @@ cleanup(void) * pass1: Get the list of object files that are going to be linked. * pass2: Calculate the size of every segment. * pass3: Rebase all symbols in sections + * pass4: Create the temporary files per section */ static void ld(int argc, char*argv[]) @@ -62,6 +67,7 @@ ld(int argc, char*argv[]) pass1(argc, argv); pass2(argc, argv); pass3(argc, argv); + pass4(argc, argv); debugsym(); debugsec(); } diff --git a/src/cmd/ld/pass2.c b/src/cmd/ld/pass2.c @@ -6,12 +6,6 @@ #include "ld.h" -Segment text = {.type = 'T'}; -Segment rodata = {.type = 'R'}; -Segment data = {.type = 'D'}; -Segment bss = {.type = 'B'}; -Segment debug = {.type = 'N'}; - static void mksecs(void) { @@ -22,7 +16,6 @@ mksecs(void) 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; @@ -33,6 +26,7 @@ mksecs(void) sec->name); } + /* TODO: use add symbol aligment */ sec->size += sp->size; } } @@ -67,7 +61,6 @@ mksegs(void) merge(&rodata); merge(&data); merge(&bss); - merge(&debug); } void diff --git a/src/cmd/ld/pass4.c b/src/cmd/ld/pass4.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> + +#include <scc/mach.h> + +#include "ld.h" + +void +pass4(int argc, char *argv[]) +{ + Objlst *lp; + Objsect *sp; + Section *sec; + unsigned long i; + FILE *fp; + + for (lp = objhead; lp; lp = lp->next) { + fp = lp->obj->fp; + for (sp = lp->obj->secs; sp; sp = sp->next) { + fseek(fp, sp->seek, SEEK_SET); + + sec = section(sp->name); + if (!sec->fp) { + sec->fp = tmpfile(); + if (!sec->fp) { + error("out of memory"); + exit(EXIT_FAILURE); + } + } + + /* TODO: add symbol alignment */ + + for (i = 0; i < sp->size; i++) + putc(getc(fp), sec->fp); + + /* TODO: Apply relocations */ + } + } +}