commit 2a53cf364037e35fffa1a6950083ac55eb91c5e3
parent b99f13d9205071c49ee3bd5c6f10777f26913634
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Wed, 30 May 2018 19:48:46 +0100
[as] Add push() and pop()
These functions push and pop an object file from the list of
object files that has to be loaded.
Diffstat:
3 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/ld/coff32.c b/ld/coff32.c
@@ -371,6 +371,8 @@ static void
unload(Obj *obj)
{
/* TODO */
+ pop(obj);
+ delobj(obj);
}
static void
@@ -379,7 +381,6 @@ pass1(Obj *obj)
load(obj);
if (obj->member && !obj->define)
unload(obj);
-
}
static void
@@ -422,8 +423,7 @@ probe(char *fname, char *member, FILE *fp)
return NULL;
}
- obj = newobj(fname, member);
- obj->fp = fp;
+ obj = newobj(fname, member, fp);
obj->unpack = unpack;
obj->align = align;
obj->fmt = &coff32;
diff --git a/ld/ld.h b/ld/ld.h
@@ -8,6 +8,7 @@ struct obj {
char *member;
FILE *fp;
Fmt *fmt;
+ long offset;
void *filhdr;
void *scnhdr;
@@ -22,7 +23,7 @@ struct obj {
int align;
int define;
- struct obj *next;
+ struct obj *next, *prev;
};
struct symbol {
@@ -43,7 +44,10 @@ struct objfmt {
};
/* 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 */
diff --git 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 @@ static char sccsid[] = "@(#) ./ld/obj.c";
#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 @@ newobj(char *fname, char *member)
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;
}