shithub: scc

Download patch

ref: 715f312b3c3a3faa943e7a8c3905bbc768d89d89
parent: 1da7f45ae0e42aff174c695d948449bf22bf4b33
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed May 30 15:48:46 EDT 2018

[as] Add push() and pop()

These functions push and pop an object file from the list of
object files that has to be loaded.

--- a/ld/coff32.c
+++ b/ld/coff32.c
@@ -371,6 +371,8 @@
 unload(Obj *obj)
 {
 	/* TODO */
+	pop(obj);
+	delobj(obj);
 }
 
 static void
@@ -379,7 +381,6 @@
 	load(obj);
 	if (obj->member && !obj->define)
 		unload(obj);
-		
 }
 
 static void
@@ -422,8 +423,7 @@
 		return NULL;
 	}
 
-	obj = newobj(fname, member);
-	obj->fp = fp;
+	obj = newobj(fname, member, fp);
 	obj->unpack = unpack;
 	obj->align = align;
 	obj->fmt = &coff32;
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -8,6 +8,7 @@
 	char *member;
 	FILE *fp;
 	Fmt *fmt;
+	long offset;
 
 	void *filhdr;
 	void *scnhdr;
@@ -22,7 +23,7 @@
 	int align;
 	int define;
 
-	struct obj *next;
+	struct obj *next, *prev;
 };
 
 struct symbol {
@@ -43,7 +44,10 @@
 };
 
 /* obj.c */
-extern Obj *newobj(char *fname, char *member);
+extern Obj *newobj(char *fname, char *member, FILE *fp);
+extern void delobj(Obj *obj);
+extern void pop(Obj *obj);
+extern void push(Obj *obj);
 extern Symbol *lookup(char *name);
 
 /* main.c */
--- a/ld/obj.c
+++ b/ld/obj.c
@@ -1,5 +1,6 @@
 static char sccsid[] = "@(#) ./ld/obj.c";
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -10,12 +11,53 @@
 #define NR_SYM_HASH 64
 
 Obj *objlst;
-static Obj *tail;
+static Obj *objtail;
 
+Symbol *sectlst;
 static Symbol *symtbl[NR_SYM_HASH];
 
+/*
+ * This function is always called with the last object created,
+ * so we can be sure that we only have to pop off the last
+ * object created
+ */
+void
+pop(Obj *obj)
+{
+	objtail = objtail->prev;
+	if (!objtail)
+		objlst = NULL;
+}
+
+void
+push(Obj *obj)
+{
+	obj->prev = objlst;
+	obj->next = NULL;
+
+	if (!objlst) {
+		objtail = objlst = obj;
+	} else {
+		objtail->next = obj;
+		objtail = obj;
+	}
+}
+
+void
+delobj(Obj *obj)
+{
+	free(obj->strtbl);
+	free(obj->sections);
+	free(obj->symbols);
+	free(obj->scnhdr);
+	free(obj->filhdr);
+	free(obj->fname);
+	free(obj->member);
+	free(obj);
+}
+
 Obj *
-newobj(char *fname, char *member)
+newobj(char *fname, char *member, FILE *fp)
 {
 	Obj *obj;
 	char *s, *t;
@@ -37,12 +79,12 @@
 			outmem();
 		obj->member = memcpy(s, member, len);
 	}
-	obj->next = NULL;
 
-	if (!objlst)
-		tail = objlst = obj;
-	else
-		tail->next = obj;
+	obj->fp = fp;
+	if ((obj->offset = ftell(fp)) == EOF) {
+		fprintf(stderr, "ld: %s: %s\n", fname, strerror(errno));
+		exit(1);
+	}
 
 	return obj;
 }