ref: 4c00c4e8204f98a5859ef6c0bfe8d2e4d6f168d2
parent: da1885ebccf5d31fb4a695764b96311e493bde09
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue May 29 14:17:24 EDT 2018
[ld] Redefine interface between main and object formats We only have to create once the object file.
--- a/ld/coff32.c
+++ b/ld/coff32.c
@@ -15,23 +15,20 @@
#include "../inc/scc.h"
#include "ld.h"
-static int (*unpack)(unsigned char *, char *, ...);
-static int align;
-
static FILHDR *
-getfhdr(unsigned char *buff, FILHDR *hdr)
+getfhdr(Obj *obj, 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);
+ n = (*obj->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;
}
@@ -49,7 +46,7 @@
if (fread(buff, 4, 1, obj->fp) != 1)
return -1;
- (*unpack)(buff, "l", &siz);
+ (*obj->unpack)(buff, "l", &siz);
siz -= 4;
if (siz == 0) {
@@ -71,22 +68,22 @@
}
static SCNHDR *
-getscn(unsigned char *buff, SCNHDR *scn)
+getscn(Obj *obj, unsigned char *buff, SCNHDR *scn)
{
int n;
- n = (*unpack)(buff,
- "'8llllllssl",
- scn->s_name,
- &scn->s_paddr,
- &scn->s_vaddr,
- &scn->s_size,
- &scn->s_scnptr,
- &scn->s_relptr,
- &scn->s_lnnoptr,
- &scn->s_nrelloc,
- &scn->s_nlnno,
- &scn->s_flags);
+ n = (*obj->unpack)(buff,
+ "'8llllllssl",
+ scn->s_name,
+ &scn->s_paddr,
+ &scn->s_vaddr,
+ &scn->s_size,
+ &scn->s_scnptr,
+ &scn->s_relptr,
+ &scn->s_lnnoptr,
+ &scn->s_nrelloc,
+ &scn->s_nlnno,
+ &scn->s_flags);
assert(n == SCNHSZ);
return scn;
}
@@ -94,7 +91,7 @@
static int
readsects(Obj *obj, long off)
{
- unsigned nsec, i;
+ unsigned a, nsec, i;
unsigned char buff[SCNHSZ];
SCNHDR *scn, *p;
FILHDR *hdr;
@@ -111,13 +108,14 @@
if (fseek(obj->fp, off, SEEK_SET) == EOF)
return -1;
+ a = obj->align - 1;
for (p = scn; p < &scn[nsec]; ++p) {
if (fread(buff, SCNHSZ, 1, obj->fp) != 1)
return -1;
- getscn(buff, p);
+ getscn(obj, buff, p);
sym = lookup(p->s_name);
- sym->size = (sym->size + align-1) & align-1;
+ sym->size = (sym->size + a) & a;
if (sym->size > ULLONG_MAX - p->s_size) {
fprintf(stderr,
"ld: %s: overflow in section '%s'\n",
@@ -132,25 +130,25 @@
}
static void
-getsym(unsigned char *buff, SYMENT *ent)
+getsym(Obj *obj, unsigned char *buff, SYMENT *ent)
{
int n;
long off, zero;
char *name;
- n = (*unpack)(buff,
- "'8lsscc",
- &ent->n_name,
- &ent->n_value,
- &ent->n_scnum,
- &ent->n_type,
- &ent->n_sclass,
- &ent->n_numaux);
+ n = (*obj->unpack)(buff,
+ "'8lsscc",
+ &ent->n_name,
+ &ent->n_value,
+ &ent->n_scnum,
+ &ent->n_type,
+ &ent->n_sclass,
+ &ent->n_numaux);
assert(n == SYMESZ);
name = ent->n_name;
if (!name[0] && !name[1] && !name[2] && !name[3])
- (*unpack)(buff, "ll", &ent->n_zeroes, &ent->n_offset);
+ (*obj->unpack)(buff, "ll", &ent->n_zeroes, &ent->n_offset);
}
static char *
@@ -267,7 +265,7 @@
if (fread(buff, SYMESZ, 1, obj->fp) != 1)
return -1;
- getsym(buff, &ent);
+ getsym(obj, buff, &ent);
name = symname(obj, &ent);
type = typeof(obj, &ent);
sym = lookup(name);
@@ -321,7 +319,7 @@
if ((hdr = malloc(sizeof(*hdr))) == NULL)
outmem();
- getfhdr(buff, hdr);
+ getfhdr(obj, buff, hdr);
obj->filhdr = hdr;
/* TODO: Check overflow */
@@ -344,28 +342,19 @@
}
static void
-pass1(char *fname, char *member, FILE *fp)
+pass1(Obj *obj)
{
- Obj *obj;
- SYMENT *ent;
- FILHDR *hdr;
- unsigned n, nsyms;
- int islib = member != NULL;
-
- obj = newobj(fname, member);
- obj->fp = fp;
readobj(obj);
-
- hdr = obj->filhdr;
- nsyms = hdr->f_nsyms;
}
static void
-pass2(char *fname, char *member, FILE *fp)
+pass2(Obj *obj)
{
}
-static int
+Fmt coff32;
+
+static Obj *
probe(char *fname, char *member, FILE *fp)
{
int c;
@@ -372,6 +361,9 @@
int c1, c2;
fpos_t pos;
unsigned short magic;
+ unsigned align;
+ int (*unpack)(unsigned char *, char *, ...);
+ Obj *obj;
fgetpos(fp, &pos);
c1 = getc(fp);
@@ -389,13 +381,21 @@
case COFF_Z80MAGIC:
unpack = lunpack;
align = 2;
- return 1;
+ break;
default:
- return 0;
+ return NULL;
}
+
+ obj = newobj(fname, member);
+ obj->fp = fp;
+ obj->unpack = unpack;
+ obj->align = align;
+ obj->fmt = &coff32;
+
+ return obj;
}
-struct objfile coff32 = {
+Fmt coff32 = {
.probe = probe,
.pass1 = pass1,
.pass2 = pass2,
--- a/ld/formats.c
+++ b/ld/formats.c
@@ -6,9 +6,9 @@
#include "ld.h"
/* TODO: Autogenerate this file */
-struct objfile coff32;
+struct objfmt coff32;
-struct objfile *formats[] = {
+struct objfmt *formats[] = {
&coff32,
NULL,
};
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -1,6 +1,7 @@
typedef struct obj Obj;
typedef struct symbol Symbol;
+typedef struct objfmt Fmt;
struct obj {
char *fname;
@@ -11,6 +12,9 @@
Symbol **symbols;
char *strtbl;
size_t strsiz;
+ int (*unpack)(unsigned char *, char *, ...);
+ int align;
+ Fmt *fmt;
struct obj *next;
};
@@ -24,10 +28,10 @@
struct symbol *hash;
};
-struct objfile {
- int (*probe)(char *fname, char *member, FILE *fp);
- void (*pass1)(char *fname, char *member, FILE *fp);
- void (*pass2)(char *fname, char *member, FILE *fp);
+struct objfmt {
+ Obj *(*probe)(char *fname, char *member, FILE *fp);
+ void (*pass1)(Obj *obj);
+ void (*pass2)(Obj *obj);
};
/* obj.c */
--- a/ld/main.c
+++ b/ld/main.c
@@ -31,21 +31,22 @@
static int
object(char *fname, char *member, FILE *fp)
{
- extern struct objfile *formats[];
- struct objfile **p, *obj;
- void *data;
- void (*fun)(char *, char *, FILE *);
+ extern Fmt *formats[];
+ Fmt **p, *fmt;
+ Obj *obj;
+ void (*fun)(Obj *obj);
for (p = formats; *p; ++p) {
- obj = *p;
- if ((*obj->probe)(fname, member, fp))
+ fmt = *p;
+ obj = (*fmt->probe)(fname, member, fp);
+ if (obj)
break;
}
if (*p == NULL)
return 0;
- fun = (pass == 1) ? obj->pass1 : obj->pass2;
- (*fun)(fname, member, fp);
+ (*obj->fmt->pass1)(obj);
+
return 1;
}
@@ -156,8 +157,6 @@
pass2(int argc, char *argv[])
{
pass = 2;
- while (*argv)
- process(*argv++);
}
static void