shithub: scc

Download patch

ref: 561e2d1456fd352c6052532bf1bfb22c8dcf0f93
parent: 285830f3c70d81af18754aa53b16439c6a207a43
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Feb 26 12:52:28 EST 2019

[ld] Add 3rd pass

This pass updates the base address of every section that is going
to be linked.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -18,17 +18,19 @@
 
 struct objsect {
 	char *name;
+	int id;
 	int type;
-	unsigned flags;
-	long offset;
 	int align;
-	unsigned long long size;
+	unsigned flags;
+	long seek;
+	unsigned long long size, base;
 	Objsect *next;
 };
 
 struct objsym {
-	char type;
 	char *name;
+	int type;
+	int sect;
 	unsigned long long size;
 	unsigned long long value;
 	Objsym *next, *hash;
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -7,7 +7,6 @@
          $(BINDIR)/strip \
          $(BINDIR)/size \
          $(BINDIR)/ar \
-         $(BINDIR)/ld \
          $(BINDIR)/ranlib \
          $(BINDIR)/objdump \
          $(BINDIR)/objcopy \
--- a/src/cmd/ld/pass1.c
+++ b/src/cmd/ld/pass1.c
@@ -13,7 +13,7 @@
 Objlst *objhead, *objlast;
 
 static void
-loadobj(Obj *obj, FILE *fp)
+addobj(Obj *obj, FILE *fp)
 {
 	int n;
 	Objlst *lst;
@@ -70,7 +70,7 @@
 	 * some symbol needed.
 	 */
 	if (!inlib || defasym(obj)) {
-		loadobj(obj, fp);
+		addobj(obj, fp);
 		return;
 	}
 
@@ -80,9 +80,9 @@
 }
 
 static void
-loadlib(FILE *fp)
+addlib(FILE *fp)
 {
-	int t, loaded;
+	int t, added;
 	long n;
 	Objsymdef *def, *dp;
 	Symbol *sym;
@@ -92,9 +92,9 @@
 		return;
 	}
 
-	loaded = 1;
-	while (moreundef() && loaded) {
-		loaded = 0;
+	added = 1;
+	while (moreundef() && added) {
+		added = 0;
 		for (dp = def; dp; dp = dp->next) {
 			sym = lookup(dp->name, NOINSTALL);
 			if (!sym || sym->def)
@@ -116,7 +116,7 @@
 			}
 
 			newobject(fp, t, OUTLIB);
-			loaded = 1;
+			added = 1;
 		}
 	}
 clean:
@@ -137,7 +137,7 @@
 	if (*nmemb++ == 0) {
 		if (!strncmp(name, "/", SARNAM) ||
 		    !strncmp(name, "__.SYMDEF", SARNAM)) {
-			loadlib(fp);
+			addlib(fp);
 			return 0;
 		}
 	}
--- a/src/cmd/ld/pass3.c
+++ b/src/cmd/ld/pass3.c
@@ -1,3 +1,4 @@
+#include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -5,8 +6,35 @@
 
 #include "ld.h"
 
+static void
+rebase(Obj *obj)
+{
+	Symbol *aux;
+	Objsym *sym;
+
+	for (sym = obj->syms; sym; sym = sym->next) {
+		switch (toupper(sym->type)) {
+		case 'T':
+		case 'D':
+		case 'B':
+			aux = lookup(sym->name, NOINSTALL);
+			aux->value += obj->secs[sym->sect].base;
+		case 't':
+		case 'd':
+		case 'b':
+			sym->value += obj->secs[sym->sect].base;
+		case 'N':
+		case 'U':
+		case '?':
+			break;
+		default:
+			abort();
+		}
+	}
+}
+
 /*
- * relocate the sections
+ * rebase all the sections
  */
 void
 pass3(int argc, char *argv[])
@@ -14,21 +42,34 @@
 	Obj *obj;
 	Objlst *lst;
 	Objsect *sp;
-	unsigned long long text, data, bss;
+	unsigned long long *base, text, data, bss;
 
-	textbase = text = 0;
-	database = data = textsiz+3 & ~3;
-	bssbase = bss = data+datasiz+3 & ~3;
+	/*
+	 * TODO: deal with page aligment
+	 */
+	textbase = text = 0x100;
+	database = data = textsiz;
+	bssbase = bss = data+datasiz;
 
 	for (lst = objhead; lst; lst = lst->next) {
-		for (sp = lst->obj->secs; sp; sp = sp->next) {
+		obj = lst->obj;
+		for (sp = obj->secs; sp; sp = sp->next) {
 			switch (sp->type) {
 			case 'T':
+				base = &text;
+				break;
 			case 'D':
+				base = &data;
+				break;
 			case 'B':
+				base = &bss;
+				break;
 			default:
 				abort();
 			}
+			sp->base = *base;
+			*base += sp->size;
 		}
+		rebase(obj);
 	}
 }
--- a/src/libmach/coff32/coff32getsect.c
+++ b/src/libmach/coff32/coff32getsect.c
@@ -64,7 +64,8 @@
 			sflags &= ~SLOAD;
 
 		sp->name = scn->s_name;
-		sp->offset = scn->s_scnptr;
+		sp->id = i;
+		sp->seek = scn->s_scnptr;
 		sp->size = scn->s_size;
 		sp->type = type;
 		sp->flags = sflags;
--- a/src/libmach/coff32/coff32getsyms.c
+++ b/src/libmach/coff32/coff32getsyms.c
@@ -84,6 +84,7 @@
 		sym->type = t;
 		sym->value = ent->n_value;
 		sym->size = (sym->type == 'C') ? ent->n_value : 0;
+		sym->sect = ent->n_scnum-1;
 	}
 
 	return i;