ref: ce65403b2ac6829078274cfcc5bddf11ae926677
parent: 1a3ab58b1e471ed3b38dfdb1d0c0a0bd30280fbf
parent: dc0e97ec6386afa3275f911facd075e699a022e3
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu May 3 12:03:11 EDT 2018
Merge branch 'master' of ssh://simple-cc.org:/var/gitrepos/scc
--- a/ld/Makefile
+++ b/ld/Makefile
@@ -4,7 +4,7 @@
include $(PROJECTDIR)/rules.mk
include $(LIBDIR)/libdep.mk
-OBJ = main.o formats.o coff32.o
+OBJ = main.o formats.o coff32.o obj.o
all: ld
cp ld $(PROJECTDIR)/rootdir/bin
--- a/ld/coff32.c
+++ b/ld/coff32.c
@@ -1,6 +1,8 @@
static char sccsid[] = "@(#) ./ld/coff32.c";
+#include <assert.h>
#include <errno.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -11,12 +13,75 @@
#include "../inc/scc.h"
#include "ld.h"
-static int
+static int (*unpack)(unsigned char *, char *, ...);
+static long strtbl, symtbl, sectbl;
+
+static FILHDR *
+getfhdr(unsigned char *buff, FILHDR *hdr)
+{
+ int n;
+
+ n = (*unpack)(buff,
+ "sslllss",
+ &hdr->f_magic,
+ &hdr->f_nscns,
+ &hdr->f_timdat,
+ &hdr->f_symptr,
+ &hdr->f_nsyms,
+ &hdr->f_opthdr,
+ &hdr->f_flags);
+ assert(n == FILHSZ);
+ return hdr;
+}
+
+static void
pass1(char *fname, char *member, FILE *fp)
{
+ unsigned char buff[FILHSZ];
+ FILHDR *hdr;
+ Obj *obj;
+ long siz, pos = ftell(fp);
+ char *str;
+
+ if (fread(buff, FILHSZ, 1, fp) != 1)
+ goto bad_file;
+
+ if ((hdr = malloc(sizeof(*hdr))) == NULL)
+ goto out_of_memory;
+
+ obj = newobj(fname);
+ obj->hdr = getfhdr(buff, hdr);
+
+ /* TODO: Check overflow */
+ strtbl = pos + hdr->f_symptr + hdr->f_nsyms* SYMESZ;
+ symtbl = pos + hdr->f_symptr;
+ sectbl = pos + FILHSZ + hdr->f_opthdr;
+
+ if (fseek(fp, strtbl, SEEK_SET) == EOF)
+ goto bad_file;
+
+ if (fread(buff, 4, 1, fp) != 1)
+ goto bad_file;
+
+ (*unpack)(buff, "l", &siz);
+
+ if (siz > SIZE_MAX || (str = malloc(siz)) == NULL)
+ goto out_of_memory;
+
+ if (fread(str, siz, 1, fp) != 1)
+ goto bad_file;
+
+ obj->strtbl = str;
+
+out_of_memory:
+ die("ld: out of memory");
+bad_file:
+ if (ferror(fp))
+ die("ld: %s: %s", fname, strerror(errno));
+ die("ld: %s: corrupted file", fname);
}
-static int
+static void
pass2(char *fname, char *member, FILE *fp)
{
}
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -1,6 +1,20 @@
+typedef struct obj Obj;
+
+struct obj {
+ char *fname;
+ void *hdr;
+ char *strtbl;
+ struct obj *next;
+};
+
+#ifdef stdin
struct objfile {
int (*probe)(char *fname, char *member, FILE *fp);
- int (*pass1)(char *fname, char *member, FILE *fp);
- int (*pass2)(char *fname, char *member, FILE *fp);
+ void (*pass1)(char *fname, char *member, FILE *fp);
+ void (*pass2)(char *fname, char *member, FILE *fp);
};
+#endif
+
+/* obj.c */
+extern Obj *newobj(char *fname);
--- a/ld/main.c
+++ b/ld/main.c
@@ -21,7 +21,7 @@
extern struct objfile *formats[];
struct objfile **p, *obj;
void *data;
- int (*fun)(char *, char *, FILE *);
+ void (*fun)(char *, char *, FILE *);
for (p = formats; *p; ++p) {
obj = *p;
@@ -32,7 +32,8 @@
return 0;
fun = (pass == 1) ? obj->pass1 : obj->pass2;
- return (*fun)(fname, member, fp);
+ (*fun)(fname, member, fp);
+ return 1;
}
static char *
--- /dev/null
+++ b/ld/obj.c
@@ -1,0 +1,33 @@
+static char sccsid[] = "@(#) ./ld/obj.c";
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../inc/scc.h"
+#include "ld.h"
+
+Obj *objlst;
+static Obj *tail;
+
+Obj *
+newobj(char *fname)
+{
+ Obj *obj;
+ char *s;
+ size_t len = strlen(fname);
+
+ obj = malloc(sizeof(*obj));
+ s = malloc(len+1);
+ if (!obj || !s)
+ die("ld: out of memory");
+
+ obj->fname = memcpy(s, fname, len);
+ obj->next = NULL;
+
+ if (!objlst)
+ tail = objlst = obj;
+ else
+ tail->next = obj;
+
+ return obj;
+}