commit 03b5aecd77d410af75c8236b09f8d70071b0552d
parent e8e24d5c05305a29469c5e339f8674718e943b3d
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 1 Nov 2019 11:40:14 +0100
[ld] Recover pass2
Pass2 was disabled with the big rewrite of libmach. This patch
enables the code code again but further changes are needed.
Diffstat:
8 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h
@@ -23,6 +23,7 @@ struct obj {
int type;
long pos;
void *data;
+ Obj *next;
};
struct segment {
@@ -34,6 +35,7 @@ struct segment {
int type;
int align;
int nsec;
+ Section **sections;
};
struct section {
diff --git a/src/cmd/ld/Makefile b/src/cmd/ld/Makefile
@@ -9,8 +9,7 @@ OBJS =\
symbol.o\
section.o\
pass1.o\
-
-# pass2.o \
+ pass2.o \
# pass3.o \
# pass4.o \
# pass5.o \
diff --git a/src/cmd/ld/ld.h b/src/cmd/ld/ld.h
@@ -21,7 +21,7 @@ extern void debugsym(void);
extern Section *lookupsec(char *name);
extern void copy(Obj *obj, Section *osec, Section *sec);
extern void grow(Section *sec, int nbytes);
-
+extern void merge(Segment *seg);
extern void debugsec(void);
/* globals */
@@ -35,4 +35,5 @@ extern int dflag;
extern int gflag;
extern char *Dflag;
extern char *output, *entry;
+extern Obj *objhead;
extern Segment debug, text, rodata, data, bss;
diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c
@@ -66,10 +66,12 @@ static void
ld(int argc, char*argv[])
{
pass1(argc, argv);
-/* pass2(argc, argv);
+ pass2(argc, argv);
+/*
pass3(argc, argv);
pass4(argc, argv);
- pass5(argc, argv); */
+ pass5(argc, argv);
+*/
debugsym();
debugsec();
}
diff --git a/src/cmd/ld/pass1.c b/src/cmd/ld/pass1.c
@@ -17,6 +17,7 @@ enum {
};
int bintype = -1;
+Obj *objhead;
static int
is_needed(Obj *obj)
diff --git a/src/cmd/ld/pass2.c b/src/cmd/ld/pass2.c
@@ -9,49 +9,27 @@
static void
mksecs(void)
{
- Objlst *lp;
- Objsec *sp;
- Section *sec;
-
- for (lp = objhead; lp; lp = lp->next) {
- for (sp = lp->obj->secs; sp; sp = sp->next) {
- sec = section(sp->name);
- if (sec->type == '?') {
- sec->type = sp->type;
- sec->flags = sp->flags;
+ int i;
+ Obj *obj;
+ Section sec, *sp;
+
+ for (obj = objhead; obj; obj = obj->next) {
+ for (i = 0; getsec(obj, &i, &sec); i++) {
+ sp = lookupsec(sec.name);
+ if (sp->type == '?') {
+ sp->type = sec.type;
+ sp->flags = sec.flags;
}
- if (sec->type != sp->type || sec->flags != sp->flags) {
+ if (sp->type != sec.type || sp->flags != sec.flags) {
error("incompatible definitions of section '%s'",
- sec->name);
+ sp->name);
}
- /* TODO: use add symbol aligment */
- sec->size += sp->size;
- }
- }
-}
-
-static void
-merge(Segment *seg)
-{
- Section *sec, **p;
- int n = 0;
-
- for (sec = sechead; sec; sec = sec->next) {
- if (sec->type != seg->type)
- continue;
- p = realloc(seg->sections, (n+1) * sizeof(*p));
- if (!p) {
- error("ou of memory");
- exit(EXIT_FAILURE);
+ sp->size = sp->size+sp->align-1 & sp->align-1;
+ sp->size += sec.size;
}
- p[n++] = sec;
- seg->sections = p;
- seg->size += sec->size;
}
-
- seg->nsec = n;
}
static void
diff --git a/src/cmd/ld/section.c b/src/cmd/ld/section.c
@@ -74,7 +74,36 @@ lookupsec(char *name)
sp->hash = sectab[h];
sectab[h] = sp;
- return linksec(&secs, sec);
+ sp->next = &secs;
+ sp->prev = secs.prev;
+ secs.prev->next = sp;
+ secs.prev = sp;
+
+ return sec;
+}
+
+void
+merge(Segment *seg)
+{
+ struct sectab *sp;
+ Section *sec, **p;
+ int n = 0;
+
+ for (sp = secs.next; sp != &secs; sp = sp->next) {
+ sec = &sp->sec;
+ if (sec->type != seg->type)
+ continue;
+ p = realloc(seg->sections, (n+1) * sizeof(*p));
+ if (!p) {
+ error("out of memory");
+ exit(EXIT_FAILURE);
+ }
+ p[n++] = sec;
+ seg->sections = p;
+ seg->size += sec->size;
+ }
+
+ seg->nsec = n;
}
void
@@ -143,4 +172,4 @@ debugsec(void)
}
}
}
-#endif
-\ No newline at end of file
+#endif
diff --git a/src/libmach/newobj.c b/src/libmach/newobj.c
@@ -24,6 +24,7 @@ newobj(int type)
obj->type = type;
obj->ops = objops[fmt];
+ obj->next = NULL;
if ((*obj->ops->new)(obj) < 0) {
free(obj);
return NULL;