shithub: scc

Download patch

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);
+}