ref: a91a01b018c181d150937db6f74cb1f7d0e3ebde
parent: 718fad000a4821aeab5d6050e8a93298a1a67e77
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 21 17:58:58 EDT 2019
[ld] Add pass5() This function only writes the result back to a binary file.
--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -76,7 +76,9 @@
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);
--- a/src/cmd/ld/Makefile
+++ b/src/cmd/ld/Makefile
@@ -10,6 +10,7 @@
pass2.o \
pass3.o \
pass4.o \
+ pass5.o \
all: $(TARGET)
--- 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
--- a/src/cmd/ld/ld.h
+++ b/src/cmd/ld/ld.h
@@ -44,6 +44,7 @@
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 dflag;
extern int gflag;
extern char *Dflag;
+extern char *output, *entry;
extern Objlst *objhead;
extern Section *sechead;
extern Segment text, rodata, data, bss;
--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -23,7 +23,7 @@
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 @@
* 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 @@
pass2(argc, argv);
pass3(argc, argv);
pass4(argc, argv);
+ pass5(argc, argv);
debugsym();
debugsec();
}
--- a/src/cmd/ld/pass1.c
+++ b/src/cmd/ld/pass1.c
@@ -15,29 +15,45 @@
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 = list;
+ sym->prev = list->prev;
+ list->prev->next = sym;
+ list->prev = sym;
+ return sym;
+}
- sym->next = &refhead;
- sym->prev = refhead.prev;
- refhead.prev->next = sym;
- refhead.prev = 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 @@
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;
}
--- /dev/null
+++ b/src/cmd/ld/pass5.c
@@ -1,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);
+}
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -12,6 +12,8 @@
objsect.o \
objsyms.o \
objdel.o \
+ objaddseg.o \
+ objsync.o \
addr2line.o \
archive.o \
armember.o \
--- a/src/libmach/coff32/Makefile
+++ b/src/libmach/coff32/Makefile
@@ -14,6 +14,7 @@
coff32getidx.o \
coff32getsect.o \
coff32getsyms.o \
+ coff32sync.o \
all: $(OBJS)
--- /dev/null
+++ b/src/libmach/coff32/coff32sync.c
@@ -1,0 +1,10 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "../libmach.h"
+
+int
+coff32sync(Obj *obj)
+{
+}
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -34,6 +34,7 @@
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 char *coff32namidx(void);
extern int coff32getsyms(Obj *obj);
+extern int coff32sync(Obj *obj);
--- /dev/null
+++ b/src/libmach/objaddseg.c
@@ -1,0 +1,9 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+int
+objaddseg(Obj *obj, void *seg)
+{
+ return 0;
+}
--- /dev/null
+++ b/src/libmach/objsync.c
@@ -1,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);
+}