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;