commit 7cb608cbc6635b2baeb9b75b6312e987db7974c3
parent ef32f8d8da1196b6d6dbde048c4f1188408d7f4d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Tue, 5 Jun 2018 19:12:51 +0100
[as] Remove multi format support
This feature is really complex because it forces to have everything
in memory and to support multi-format relocations. This is to
complex, at least for a first version, so I am move the code out
of this complexity.
Diffstat:
M | ld/Makefile | | | 4 | +--- |
M | ld/coff32.c | | | 70 | ++++++---------------------------------------------------------------- |
D | ld/formats.c | | | 14 | -------------- |
M | ld/ld.h | | | 13 | +++++-------- |
M | ld/main.c | | | 81 | ++++++++++++++++++++++++++++++++----------------------------------------------- |
5 files changed, 45 insertions(+), 137 deletions(-)
diff --git a/ld/Makefile b/ld/Makefile
@@ -4,7 +4,7 @@ PROJECTDIR = ..
include $(PROJECTDIR)/rules.mk
include $(LIBDIR)/libdep.mk
-OBJ = main.o formats.o coff32.o obj.o
+OBJ = main.o coff32.o obj.o
all: ld
cp ld $(PROJECTDIR)/rootdir/bin
@@ -26,8 +26,6 @@ coff32.o: ./../inc/coff32/scnhdr.h
coff32.o: ./../inc/coff32/syms.h
coff32.o: ./../inc/scc.h
coff32.o: ./ld.h
-formats.o: ./../inc/scc.h
-formats.o: ./ld.h
main.o: ./../inc/ar.h
main.o: ./../inc/scc.h
main.o: ./../inc/syslibs.h
diff --git a/ld/coff32.c b/ld/coff32.c
@@ -260,39 +260,7 @@ symname(Obj *obj, SYMENT *ent)
return &obj->strtbl[off];
}
-static int
-needed(Obj *obj)
-{
- FILHDR *hdr = obj->filhdr;
- SYMENT *ent, *ents = obj->enthdr;
- long aux, i;
-
- aux = 0;
- for (i = 0; i < hdr->f_nsyms; i++) {
- if (aux > 0) {
- aux--;
- continue;
- }
- ent = ents + i;
- if (ent->n_sclass != C_EXT)
- continue;
-
- switch (ent->n_scnum) {
- case N_DEBUG:
- case N_UNDEF:
- continue;
- case N_ABS:
- default:
- if (!lookup(symname(obj, ent), NOINSTALL))
- continue;
- return 1;
- }
- }
-
- return 0;
-}
-
-static Obj *
+Obj *
load(Obj *obj)
{
FILHDR *hdr = obj->filhdr;
@@ -300,6 +268,8 @@ load(Obj *obj)
SYMENT *ent, *ents = obj->enthdr;
int nsect, aux;
+ readobj(obj);
+
for (scn = scns; scn < &scns[hdr->f_nscns]; ++scn) {
/* TODO: padding */
Section *sect = slookup(scn->s_name);
@@ -346,33 +316,12 @@ load(Obj *obj)
}
}
- return obj;
-}
-
-static void
-pass1(Obj *obj)
-{
- readobj(obj);
-
- if (obj->member) {
- if (!needed(obj)) {
- delobj(obj);
- return;
- }
- }
-
- add(obj);
- load(obj);
-}
+ /* TODO: Check if the object in library is needed: delobj(obj) */
-static void
-pass2(Obj *obj)
-{
+ return add(obj);
}
-Fmt coff32;
-
-static Obj *
+Obj *
probe(char *fname, char *member, FILE *fp)
{
int c;
@@ -408,14 +357,7 @@ probe(char *fname, char *member, FILE *fp)
obj = newobj(fname, member, fp);
obj->unpack = unpack;
obj->align = align;
- obj->fmt = &coff32;
obj->offset = pos;
return obj;
}
-
-Fmt coff32 = {
- .probe = probe,
- .pass1 = pass1,
- .pass2 = pass2,
-};
diff --git a/ld/formats.c b/ld/formats.c
@@ -1,14 +0,0 @@
-static char sccsid[] = "@(#) ./ld/probe.c";
-
-#include <stdio.h>
-
-#include "../inc/scc.h"
-#include "ld.h"
-
-/* TODO: Autogenerate this file */
-struct objfmt coff32;
-
-struct objfmt *formats[] = {
- &coff32,
- NULL,
-};
diff --git a/ld/ld.h b/ld/ld.h
@@ -4,14 +4,12 @@
typedef struct obj Obj;
typedef struct symbol Symbol;
-typedef struct objfmt Fmt;
typedef struct section Section;
struct obj {
char *fname;
char *member;
FILE *fp;
- Fmt *fmt;
long offset;
void *filhdr;
@@ -49,12 +47,6 @@ struct section {
struct section *next;
};
-struct objfmt {
- Obj *(*probe)(char *fname, char *member, FILE *fp);
- void (*pass1)(Obj *obj);
- void (*pass2)(Obj *obj);
-};
-
/* obj.c */
extern Obj *newobj(char *fname, char *member, FILE *fp);
extern Obj *add(Obj *obj);
@@ -67,6 +59,10 @@ extern void outmem(void);
extern void corrupted(char *fname, char *member);
extern void redefined(Obj *obj, Symbol *sym);
+/* object format */
+extern Obj *probe(char *fname, char *member, FILE *fp);
+extern Obj *load(Obj *obj);
+
/*
* Definition of globals variables
*/
@@ -77,3 +73,4 @@ extern int Xflag;
extern int rflag;
extern int dflag;
extern int gflag;
+extern Obj *objlst;
diff --git a/ld/main.c b/ld/main.c
@@ -51,21 +51,12 @@ outmem(void)
static int
object(char *fname, char *member, FILE *fp)
{
- extern Fmt *formats[];
- Fmt **p, *fmt;
Obj *obj;
- void (*fun)(Obj *obj);
- for (p = formats; *p; ++p) {
- fmt = *p;
- obj = (*fmt->probe)(fname, member, fp);
- if (obj)
- break;
- }
- if (*p == NULL)
+ obj = probe(fname, member, fp);
+ if (!obj)
return 0;
-
- (*obj->fmt->pass1)(obj);
+ load(obj);
return 1;
}
@@ -98,35 +89,36 @@ ar(char *fname, FILE *fp)
goto file_error;
while (fread(&hdr, sizeof(hdr), 1, fp) == 1) {
- pos = ftell(fp);
if (strncmp(hdr.ar_fmag, ARFMAG, sizeof(hdr.ar_fmag)))
- goto corrupted;
+ corrupted(fname, NULL);
siz = 0;
sscanf(hdr.ar_size, "%10ld", &siz);
- if (siz == 0)
- goto corrupted;
-
if (siz & 1)
siz++;
- if (pos == -1 || pos > LONG_MAX - siz)
- die("ld: %s: overflow in size of archive", fname);
+ if (siz == 0)
+ corrupted(fname, NULL);
+
+ pos = ftell(fp);
+ if (pos == -1 || pos > LONG_MAX - siz) {
+ fprintf(stderr,
+ "ld: %s(%s): overflow in size of archive",
+ fname, member);
+ exit(EXIT_FAILURE);
+ }
pos += siz;
getfname(&hdr, member);
object(fname, member, fp);
if (fseek(fp, pos, SEEK_SET) == EOF)
- goto file_error;
+ break;
}
- if (ferror(fp))
- goto file_error;
- return;
-
-corrupted:
- die("ld: %s: corrupted archive", fname);
file_error:
- die("ld: %s: %s", fname, strerror(errno));
+ if (ferror(fp)) {
+ fprintf(stderr, "ld: %s: %s\n", fname, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
}
static int
@@ -140,7 +132,7 @@ archive(char *fname, FILE *fp)
fsetpos(fp, &pos);
if (ferror(fp))
- die("ld: %s: %s", fname, strerror(errno));
+ return 0;
if (strncmp(magic, ARMAG, SARMAG) != 0)
return 0;
@@ -149,34 +141,27 @@ archive(char *fname, FILE *fp)
}
static void
-process(char *fname)
+pass1(int argc, char *argv[])
{
FILE *fp;
+ char *s;
- if ((fp = fopen(fname, "rb")) == NULL)
- die("ld: %s: %s", fname, strerror(errno));
-
- if (!object(fname, NULL, fp) && !archive(fname, fp))
- die("ld: %s: File format not recognized", fname);
-
- if (ferror(fp))
- die("ld: %s: %s", fname, strerror(errno));
-
- fclose(fp);
-}
-
-static void
-pass1(int argc, char *argv[])
-{
- pass = 1;
- while (*argv)
- process(*argv++);
+ while ((s = *argv++) != NULL) {
+ if ((fp = fopen(s, "rb")) == NULL) {
+ fprintf(stderr, "ld: %s: %s\n", s, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ if (!object(s, NULL, fp) && !archive(s, fp)) {
+ fprintf(stderr, "ld: %s: File format not recognized\n", s);
+ exit(EXIT_FAILURE);
+ }
+ fclose(fp);
+ }
}
static void
pass2(int argc, char *argv[])
{
- pass = 2;
}
static void