shithub: scc

Download patch

ref: 85d760f44e6c6622057d1db8aba52cd5902dca95
parent: 8ad82c1a61620e3b865bfbe937b4ff9440383091
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Feb 20 00:11:47 EST 2019

[ld] Load the sections in temporary files

--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -21,6 +21,7 @@
 	int type;
 	unsigned flags;
 	long offset;
+	int align;
 	unsigned long long size;
 	Objsect *next;
 };
--- a/src/cmd/ld.c
+++ b/src/cmd/ld.c
@@ -17,6 +17,7 @@
 
 typedef struct objlst Objlst;
 typedef struct symbol Symbol;
+typedef struct section Section;
 
 enum {
 	NOINSTALL,
@@ -28,9 +29,15 @@
 	INLIB,
 };
 
+struct section {
+	char *name;
+	unsigned long long size;
+	FILE *fp;
+	Section *next;
+};
+
 struct objlst {
 	Obj *obj;
-	Objsect *sect;
 	struct objlst *next;
 };
 
@@ -45,6 +52,7 @@
 
 char *output = "a.out", *entry = "start", *datasiz;
 
+static Section *sections;
 static int bintype = -1;
 static char *filename, *membname;
 static Objlst *objhead, *objlast;
@@ -59,7 +67,7 @@
 static int Xflag;		/* discard locals starting with 'L' */
 static int rflag;		/* preserve relocation bits */
 static int dflag;		/* define common even with rflag */
-static int gflag;              /* preserve debug symbols */
+static int gflag;               /* preserve debug symbols */
 
 static int status;
 
@@ -194,8 +202,56 @@
 }
 
 static void
-loadobj(Obj *obj)
+newsect(Objsect *secp, FILE *fp)
 {
+	int c;
+	unsigned long long align, size;
+	Section *sp;
+
+	for (sp = sections; sp; sp = sp->next) {
+		if (!strcmp(sp->name, secp->name))
+			break;
+	}
+
+	if (!sp) {
+		size_t len = strlen(secp->name) + 1;
+		char * s = malloc(len);
+		FILE *fp = tmpfile();
+
+		sp = malloc(sizeof(*sp));
+		if (!s || !sp || !fp)
+			goto err;
+
+		sp->name = memcpy(s, secp->name, len);
+		sp->size = 0;
+		sp->fp = fp;
+		sp->next = sections;
+
+		if (!sections)
+			sections = sp;
+	}
+
+	align = secp->align-1;
+	size = (sp->size + align) & ~align;
+
+	for (; secp->size < size; secp->size++)
+		putc(0, sp->fp);
+
+	fseek(fp, secp->offset, SEEK_SET);
+	while ((c = getc(fp)) != EOF)
+		putc(c, sp->fp);
+	fflush(sp->fp);
+
+	if (!ferror(fp) && !ferror(sp->fp))
+		return;
+
+err:
+	error(errstr());
+}
+
+static void
+loadobj(Obj *obj, FILE *fp)
+{
 	int n;
 	Objlst *lst;
 	Objsym *sym;
@@ -220,6 +276,9 @@
 	for (sym = obj->syms; sym; sym = sym->next)
 		newsym(sym, obj);
 
+	for (secp = obj->secs; secp; secp = secp->next)
+		newsect(secp, fp);
+
 	return;
 
 err1:
@@ -260,7 +319,7 @@
 		if (sym == p)
 			goto  delete;
 	}
-	loadobj(obj);
+	loadobj(obj, fp);
 
 	return;
 
--- a/src/libmach/coff32/coff32getsect.c
+++ b/src/libmach/coff32/coff32getsect.c
@@ -66,6 +66,7 @@
 		sp->offset = scn->s_scnptr;
 		sp->size = scn->s_size;
 		sp->type = type;
+		sp->align = 4; /* TODO: Check how align is defined in coff */
 	}
 	obj->secs = secs;
 	obj->nsecs = i;