commit 060d8fee07a5fb0b9e65e519c5bb8c9f1c127242
parent 6acacf91976286d477c1a5c16046eac597f86f73
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Wed, 20 Feb 2019 05:11:47 +0000
[ld] Load the sections in temporary files
Diffstat:
3 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h
@@ -21,6 +21,7 @@ struct objsect {
int type;
unsigned flags;
long offset;
+ int align;
unsigned long long size;
Objsect *next;
};
diff --git a/src/cmd/ld.c b/src/cmd/ld.c
@@ -17,6 +17,7 @@ static char sccsid[] = "@(#) ./ld/main.c";
typedef struct objlst Objlst;
typedef struct symbol Symbol;
+typedef struct section Section;
enum {
NOINSTALL,
@@ -28,9 +29,15 @@ enum {
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 @@ struct symbol {
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 local symbols */
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,7 +202,55 @@ newsym(Objsym *osym, Obj *obj)
}
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;
@@ -220,6 +276,9 @@ loadobj(Obj *obj)
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 @@ newobject(FILE *fp, int type, int inlib)
if (sym == p)
goto delete;
}
- loadobj(obj);
+ loadobj(obj, fp);
return;
diff --git a/src/libmach/coff32/coff32getsect.c b/src/libmach/coff32/coff32getsect.c
@@ -66,6 +66,7 @@ coff32getsect(Obj *obj)
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;