shithub: scc

Download patch

ref: c21c4a5a605800e23251b85c8a94a8873b144868
parent: 8dd55ccfd79facf3ec5e404f9c502a8a8637ca66
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 1 07:40:14 EDT 2019

[ld] Recover pass2

Pass2 was disabled with the big rewrite of libmach. This patch
enables the code code again but further changes are needed.

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -23,6 +23,7 @@
 	int type;
 	long pos;
 	void *data;
+	Obj *next;
 };
 
 struct segment {
@@ -34,6 +35,7 @@
 	int type;
 	int align;
 	int nsec;
+	Section **sections;
 };
 
 struct section {
--- a/src/cmd/ld/Makefile
+++ b/src/cmd/ld/Makefile
@@ -9,8 +9,7 @@
 	symbol.o\
 	section.o\
 	pass1.o\
-
-#       pass2.o \
+	pass2.o \
 #       pass3.o \
 #       pass4.o \
 #       pass5.o \
--- a/src/cmd/ld/ld.h
+++ b/src/cmd/ld/ld.h
@@ -21,7 +21,7 @@
 extern Section *lookupsec(char *name);
 extern void copy(Obj *obj, Section *osec, Section *sec);
 extern void grow(Section *sec, int nbytes);
-
+extern void merge(Segment *seg);
 extern void debugsec(void);
 
 /* globals */
@@ -35,4 +35,5 @@
 extern int gflag;
 extern char *Dflag;
 extern char *output, *entry;
+extern Obj *objhead;
 extern Segment debug, text, rodata, data, bss;
--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -66,10 +66,12 @@
 ld(int argc, char*argv[])
 {
 	pass1(argc, argv);
-/*	pass2(argc, argv);
+	pass2(argc, argv);
+/*
 	pass3(argc, argv);
 	pass4(argc, argv);
-	pass5(argc, argv); */
+	pass5(argc, argv);
+*/
 	debugsym();
 	debugsec();
 }
--- a/src/cmd/ld/pass1.c
+++ b/src/cmd/ld/pass1.c
@@ -17,6 +17,7 @@
 };
 
 int bintype = -1;
+Obj *objhead;
 
 static int
 is_needed(Obj *obj)
--- a/src/cmd/ld/pass2.c
+++ b/src/cmd/ld/pass2.c
@@ -9,49 +9,27 @@
 static void
 mksecs(void)
 {
-	Objlst *lp;
-	Objsec *sp;
-	Section *sec;
+	int i;
+	Obj *obj;
+	Section sec, *sp;
 
-	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;
+	for (obj = objhead; obj; obj = obj->next) {
+		for (i = 0; getsec(obj, &i, &sec); i++) {
+			sp = lookupsec(sec.name);
+			if (sp->type == '?') {
+				sp->type = sec.type;
+				sp->flags = sec.flags;
 			}
 
-			if (sec->type != sp->type || sec->flags != sp->flags) {
+			if (sp->type != sec.type || sp->flags != sec.flags) {
 				error("incompatible definitions of section '%s'",
-				      sec->name);
+				      sp->name);
 			}
 
-			/* TODO: use add symbol aligment */
-			sec->size += sp->size;
+			sp->size = sp->size+sp->align-1 & sp->align-1;
+			sp->size += sec.size;
 		}
 	}
-}
-
-static void
-merge(Segment *seg)
-{
-	Section *sec, **p;
-	int n = 0;
-
-	for (sec = sechead; sec; sec = sec->next) {
-		if (sec->type != seg->type)
-			continue;
-		p = realloc(seg->sections, (n+1) * sizeof(*p));
-		if (!p) {
-			error("ou of memory");
-			exit(EXIT_FAILURE);
-		}
-		p[n++] = sec;
-		seg->sections = p;
-		seg->size += sec->size;
-	}
-
-	seg->nsec = n;
 }
 
 static void
--- a/src/cmd/ld/section.c
+++ b/src/cmd/ld/section.c
@@ -74,10 +74,39 @@
 	sp->hash = sectab[h];
 	sectab[h] = sp;
 
-	return linksec(&secs, sec);
+	sp->next = &secs;
+	sp->prev = secs.prev;
+	secs.prev->next = sp;
+	secs.prev = sp;
+
+	return sec;
 }
 
 void
+merge(Segment *seg)
+{
+	struct sectab *sp;
+	Section *sec, **p;
+	int n = 0;
+
+	for (sp = secs.next; sp != &secs; sp = sp->next) {
+		sec = &sp->sec;
+		if (sec->type != seg->type)
+			continue;
+		p = realloc(seg->sections, (n+1) * sizeof(*p));
+		if (!p) {
+			error("out of memory");
+			exit(EXIT_FAILURE);
+		}
+		p[n++] = sec;
+		seg->sections = p;
+		seg->size += sec->size;
+	}
+
+	seg->nsec = n;
+}
+
+void
 copy(Obj *obj, Section *osec, Section *sec)
 {
 	struct sectab *sp = (struct sectab *) sec;
@@ -143,4 +172,4 @@
 		}
 	}
 }
-#endif
\ No newline at end of file
+#endif
--- a/src/libmach/newobj.c
+++ b/src/libmach/newobj.c
@@ -24,6 +24,7 @@
 
 	obj->type = type;
 	obj->ops = objops[fmt];
+	obj->next = NULL;
 	if ((*obj->ops->new)(obj) < 0) {
 		free(obj);
 		return NULL;