ref: adc39da8ab9cb40357ddfedeea5e7190f72bcdfd
parent: d2f2f98130f28e9e02a4210f1096c1bd3afffb93
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Aug 29 14:51:11 EDT 2019
[ld] Rewrite ld to use the new interfaces This patch reintroduces ld and do some other small changes.
--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -1,5 +1,6 @@
-typedef struct symbol Symbol;
+typedef struct segment Segment;
typedef struct section Section;
+typedef struct symbol Symbol;
typedef struct objops Objops;
typedef struct obj Obj;
@@ -22,13 +23,24 @@
void *data;
};
-struct section {
+struct segment {
char *name;
unsigned long long base;
unsigned long long size;
unsigned flags;
+ int index;
int type;
+ int align;
+ int nsec;
+};
+
+struct section {
+ char *name;
+ unsigned long long base;
+ unsigned long long size;
+ unsigned flags;
int index;
+ int type;
int align;
};
@@ -37,7 +49,7 @@
unsigned long long size;
unsigned long long value;
int index;
- char class;
+ int section;
char type;
};
@@ -53,7 +65,10 @@
extern int strip(Obj *obj);
extern int pc2line(Obj *obj, unsigned long long pc, char *fname, int *ln);
+extern int rebase(Obj *obj, long index, unsigned long offset);
+extern int mapsec(Obj *obj, int idx, FILE *fp);
+/* TODO: Change index to int */
extern Symbol *getsym(Obj *obj, long *index, Symbol *sym);
extern Section *getsec(Obj *obj, long *index, Section *sec);
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -3,16 +3,17 @@
PROJECTDIR = ../..
include $(PROJECTDIR)/scripts/rules.mk
-TARGET = $(BINDIR)/nm \
- $(BINDIR)/ar \
- $(BINDIR)/strip \
- $(BINDIR)/size \
- $(BINDIR)/ranlib \
- $(BINDIR)/objdump \
- $(BINDIR)/objcopy \
- $(BINDIR)/addr2line \
+TARGET =\
+ $(BINDIR)/nm\
+ $(BINDIR)/ar\
+ $(BINDIR)/strip\
+ $(BINDIR)/size\
+ $(BINDIR)/ranlib\
+ $(BINDIR)/objdump\
+ $(BINDIR)/objcopy\
+ $(BINDIR)/addr2line\
-DIRS = as scc
+DIRS = ld as scc
LIBMACH = $(LIBDIR)/libmach.a
LIBSCC = $(LIBDIR)/libscc.a
--- a/src/cmd/ld/Makefile
+++ b/src/cmd/ld/Makefile
@@ -4,13 +4,16 @@
TARGET = $(BINDIR)/ld
-OBJS = main.o \
- symbol.o \
- pass1.o \
- pass2.o \
- pass3.o \
- pass4.o \
- pass5.o \
+OBJS =\
+ main.o\
+ symbol.o\
+ section.o\
+ pass1.o\
+
+# pass2.o \
+# pass3.o \
+# pass4.o \
+# pass5.o \
all: $(TARGET)
--- a/src/cmd/ld/ld.h
+++ b/src/cmd/ld/ld.h
@@ -1,44 +1,3 @@
-struct obj;
-struct objsym;
-
-typedef struct objlst Objlst;
-typedef struct symbol Symbol;
-typedef struct section Section;
-typedef struct segment Segment;
-
-struct section {
- char *name;
- unsigned long long base;
- unsigned long size;
- unsigned flags;
- int type;
- FILE *fp;
- Section *hash;
- Section *next;
-};
-
-struct segment {
- int type;
- int nsec;
- unsigned long long base;
- unsigned long size;
- Section **sections;
-};
-
-struct objlst {
- struct obj *obj;
- struct objlst *next;
-};
-
-struct symbol {
- char *name;
- struct obj *obj;
- struct objsym *def;
- unsigned long long size, value;
- struct symbol *next, *prev;
- struct symbol *hash;
-};
-
/* passes */
extern void pass1(int argc, char *argv[]);
extern void pass2(int argc, char *argv[]);
@@ -47,14 +6,21 @@
extern void pass5(int argc, char *argv[]);
/* main.c */
-extern char *errstr(void);
extern void error(char *fmt, ...);
/* symbol.c */
-extern Symbol *lookup(char *name);
-extern Symbol *install(char *name);
-extern Section *section(char *name);
+extern int hasref(char *name);
+extern Symbol *lookupsym(char *name);
+extern int moreundef(void);
+extern void listundef(void);
+extern Symbol *define(Symbol *osym, Obj *obj);
extern void debugsym(void);
+
+/* section.c */
+extern Section *lookupsec(char *name);
+extern void copy(Obj *obj, Section *osec, Section *sec);
+extern void grow(Section *sec, int nbytes);
+
extern void debugsec(void);
/* globals */
@@ -67,6 +33,4 @@
extern int gflag;
extern char *Dflag;
extern char *output, *entry;
-extern Objlst *objhead;
-extern Section *sechead;
-extern Segment text, rodata, data, bss;
+extern Segment debug, text, rodata, data, bss;
--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -4,6 +4,7 @@
#include <stdlib.h>
#include <string.h>
+#include <scc/mach.h>
#include <scc/syslibs.h>
#include "ld.h"
@@ -27,12 +28,6 @@
char *output = "a.out", *entry = "start";
static int status;
-char *
-errstr(void)
-{
- return strerror(errno);
-}
-
void
error(char *fmt, ...)
{
@@ -67,10 +62,10 @@
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();
}
@@ -131,6 +126,7 @@
break;
case 'u':
case 'l':
+ /* FIXME: This way of handling options is wrong */
arg = (cp[1]) ? cp+1 : *++ap;
if (!arg)
goto usage;
--- a/src/cmd/ld/pass1.c
+++ b/src/cmd/ld/pass1.c
@@ -1,3 +1,4 @@
+#include <errno.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
@@ -16,94 +17,15 @@
};
int bintype = -1;
-static Objops *binops;
-static Symbol refhead = {
- .next = &refhead,
- .prev = &refhead,
-};
-Symbol defhead = {
- .next = &defhead,
- .prev = &defhead,
-};
-static Objlst *objlast;
-
-Objlst *objhead;
-
-static Symbol *
-linksym(Symbol *list, Symbol *sym)
-{
- sym->next = list;
- sym->prev = list->prev;
- list->prev->next = sym;
- list->prev = sym;
- return sym;
-}
-
-static Symbol *
-unlinksym(Symbol *sym)
-{
- sym->next->prev = sym->prev;
- sym->prev->next = sym->next;
- return sym;
-}
-
-static Symbol *
-undef(char *name)
-{
- return linksym(&refhead, install(name));
-}
-
-static Symbol *
-define(Objsym *osym, Obj *obj)
-{
- Symbol *sym = lookup(osym->name);
-
- if (!sym) {
- sym = undef(osym->name);
- } else if (sym->def && sym->def->type != 'C') {
- error("%s: symbol redefined", osym->name);
- return NULL;
- }
-
- /* TODO: deal with C symbols */
-
- sym->obj = obj;
- sym->def = osym;
- sym->size = osym->size;
- sym->value = osym->value;
-
- unlinksym(sym);
- linksym(&defhead, sym);
-
- return sym;
-}
-
static int
-moreundef(void)
-{
- return refhead.next != &refhead;
-}
-
-static void
-listundef(void)
-{
- Symbol *sym;
-
- for (sym = refhead.next; sym != &refhead; sym = sym->next) {
- fprintf(stderr,
- "ld: symbol '%s' not defined\n",
- sym->name);
- }
-}
-
-static int
is_needed(Obj *obj)
{
- Symbol *sym;
+ long i;
+ Symbol sym;
- for (sym = refhead.next; sym != &refhead; sym = sym->next) {
- if (objlookup(obj, sym->name, 0))
+ for (i = 0; getsym(obj, &i, &sym); i++) {
+ if (hasref(sym.name))
return 1;
}
@@ -110,84 +32,78 @@
return 0;
}
-
-static int
-newsym(Objsym *osym, Obj *obj)
+static void
+newsec(Section *osec, Obj *obj)
{
- Symbol *sym;
+ int align;
+ Section *sec;
+ unsigned long long base;
- switch (osym->type) {
- case 'U':
- if ((sym = lookup(osym->name)) == NULL)
- sym = undef(osym->name);
- break;
- case '?':
- case 'N':
- break;
- case 'C':
- sym = lookup(osym->name);
- if (!sym || !sym->def) {
- sym = define(osym, obj);
- break;
+ sec = lookupsec(osec->name);
+ if (sec->type != 'U') {
+ if (sec->type != osec->type
+ || sec->flags != osec->flags
+ || sec->base != osec->base
+ || sec->align != osec->align) {
+ error("incompatible definition of section %s", sec->name);
+ return;
}
- if (sym->def->type != 'C')
- break;
- if (sym->size < osym->size)
- sym->size = osym->size;
- break;
- default:
- if (isupper(osym->type))
- define(osym, obj);
- break;
+ align = osec->align;
+ align -= sec->size & align-1;
+ grow(sec, align);
+ rebase(obj, osec->index, sec->size);
+ } else {
+ sec->type = osec->type;
+ sec->base = osec->base;
+ sec->size = osec->size;
+ sec->flags = osec->flags;
}
- return 1;
+ copy(obj, osec, sec);
}
static void
-addobj(Obj *obj, FILE *fp)
+newsym(Symbol *sym, Obj *obj)
{
- int n;
- Objlst *lst;
- Objsym *sym;
- Objsec *secp;
+ long id;
+ Section sec;
- if ((lst = malloc(sizeof(*lst))) == NULL) {
- error("out of memory");
+ if (sym->type == 'U' || islower(sym->type))
return;
- }
- lst->obj = obj;
- lst->next = NULL;
-
- if (!objlast)
- objlast = objhead = lst;
- else
- objlast = objlast->next = lst;
-
- for (sym = obj->syms; sym; sym = sym->next)
- newsym(sym, obj);
+ sym = define(sym, obj);
+ id = sym->section;
+ getsec(obj, &id, &sec);
+ sym->value += sec.base;
}
static void
-newobject(FILE *fp, int type, int inlib)
+load(FILE *fp, int inlib)
{
+ int t;
+ long i;
Obj *obj;
-
- if (bintype != -1 && bintype != type) {
+ Section sec;
+ Symbol sym;
+
+ if ((t = objtype(fp, NULL)) < 0) {
+ error("bad format");
+ return;
+ }
+
+ if (bintype != -1 && bintype != t) {
error("not compatible object file");
return;
}
- bintype = type;
- binops = obj->ops;
+ bintype = t;
- if ((obj = objnew(type)) == NULL) {
- error("out of memory");
+ if ((obj = newobj(t)) == NULL) {
+ error(strerror(errno));
return;
}
- if ((*binops->read)(obj, fp) < 0) {
- error("object file corrupted");
+ if (readobj(obj, fp) < 0) {
+ error(strerror(errno));
goto delete;
}
@@ -194,16 +110,23 @@
if (inlib && !is_needed(obj))
goto delete;
- addobj(obj, fp);
+ for (i = 0; getsec(obj, &i, &sec); i++)
+ newsec(&sec, obj);
+
+ for ( i = 0; getsym(obj, &i, &sym); i++)
+ newsym(&sym, obj);
+
+ /* TODO: link the object */
+
return;
delete:
- (*binops->del)(obj);
+ delobj(obj);
return;
}
static void
-addlib(FILE *fp)
+scanindex(FILE *fp)
{
int t, added;
long n, i, *offs;
@@ -210,7 +133,7 @@
char **names;
Symbol *sym;
- if ((*binops->getidx)(&n, &names, &offs, fp) < 0) {
+ if (getindex(bintype, &n, &names, &offs, fp) < 0) {
error("corrupted index");
return;
}
@@ -217,26 +140,15 @@
for (added = 0; moreundef(); added = 0) {
for (i = 0; i < n; i++) {
- sym = lookup(names[i]);
- if (!sym || sym->def)
+ if (!hasref(names[i]))
continue;
if (fseek(fp, offs[i], SEEK_SET) == EOF) {
- error(errstr());
+ error(strerror(errno));
goto clean;
}
- if ((t = objtype(fp, NULL)) == -1) {
- error("library file corrupted");
- goto clean;
- }
-
- if (t != bintype) {
- error("incompatible library");
- goto clean;
- }
-
- newobject(fp, t, OUTLIB);
+ load(fp, OUTLIB);
added = 1;
}
@@ -250,55 +162,59 @@
free(offs);
}
-static int
-newmember(FILE *fp, char *name, void *data)
+void
+scanlib(FILE *fp)
{
- int t;
- int *nmemb = data;
+ long cur, off;
+ char memb[SARNAM+1];
if (bintype == -1) {
error("an object file is needed before any library");
- return 0;
+ return;
}
- if (*nmemb++ == 0) {
- if (!strncmp(name, "/", SARNAM) ||
- !strncmp(name, "__.SYMDEF", SARNAM)) {
- addlib(fp);
- return 0;
- }
+ cur = ftell(fp);
+ if ((off = armember(fp, memb)) < 0)
+ goto corrupted;
+
+ if (strcmp(memb, "/") == 0 || strcmp(memb, "__.SYMDEF") == 0) {
+ scanindex(fp);
+ return;
}
- membname = name;
- if ((t = objtype(fp, NULL)) == -1)
- return 1;
-
- if (bintype != t) {
- error("wrong object file format");
- return 1;
+ fseek(fp, cur, SEEK_SET);
+ for (;;) {
+ cur = ftell(fp);
+ off = armember(fp, memb);
+ switch (off) {
+ case -1:
+ goto corrupted;
+ case 0:
+ return;
+ default:
+ membname = memb;
+ if (objtype(fp, NULL) != -1)
+ load(fp, INLIB);
+ membname = NULL;
+ fseek(fp, cur, SEEK_SET);
+ fseek(fp, off, SEEK_CUR);
+ break;
+ }
}
- newobject(fp, t, INLIB);
- membname = NULL;
-
- return 1;
+corrupted:
+ error(strerror(errno));
+ error("library corrupted");
}
-static int
-newlibrary(FILE *fp)
-{
- int nmemb = 0;
-
- return formember(fp, newmember, &nmemb);
-}
-
static FILE *
-openfile(char *name, char *buffer)
+openfile(char *name)
{
size_t pathlen, len;
FILE *fp;
char **bp;
char libname[FILENAME_MAX];
+ static char buffer[FILENAME_MAX];
extern char *syslibs[];
filename = name;
@@ -305,7 +221,7 @@
membname = NULL;
if (name[0] != '-' || name[1] != 'l') {
if ((fp = fopen(name, "rb")) == NULL)
- error(errstr());
+ error(strerror(errno));
return fp;
}
@@ -317,7 +233,7 @@
strcat(strcpy(buffer, "lib"), name+2);
filename = buffer;
- if ((fp = fopen(libname, "rb")) != NULL)
+ if ((fp = fopen(buffer, "rb")) != NULL)
return fp;
for (bp = syslibs; *bp; ++bp) {
@@ -328,7 +244,7 @@
memcpy(libname+pathlen+1, buffer, len);
buffer[pathlen] = '/';
- if ((fp = fopen(buffer, "rb")) != NULL)
+ if ((fp = fopen(libname, "rb")) != NULL)
return fp;
}
@@ -337,21 +253,20 @@
}
static void
-load(char *name)
+process(char *name)
{
int t;
FILE *fp;
- char buff[FILENAME_MAX];
- if ((fp = openfile(name, buff)) == NULL)
+ if ((fp = openfile(name)) == NULL)
return;
- if ((t = objtype(fp, NULL)) != -1)
- newobject(fp, t, OUTLIB);
- else if (archive(fp))
- newlibrary(fp);
+ if (archive(fp))
+ scanlib(fp);
else
- error("bad format");
+ load(fp, OUTLIB);
+
+ fclose(fp);
}
/*
@@ -364,18 +279,20 @@
for (ap = argv+1; *ap; ++ap) {
if (ap[0][0] != '-') {
- load(*ap);
+ process(*ap);
continue;
}
for (cp = &ap[0][1]; *cp; ++cp) {
switch (*cp) {
case 'l':
+ /* FIXME: we proccess arg again after this */
arg = (cp[1]) ? cp+1 : *++ap;
- load(arg);
+ process(arg);
continue;
case 'u':
+ /* FIXME: we proccess arg again after this */
arg = (cp[1]) ? cp+1 : *++ap;
- undef(arg);
+ lookupsym(arg);
continue;
}
}
--- a/src/cmd/ld/pass3.c
+++ b/src/cmd/ld/pass3.c
@@ -6,6 +6,7 @@
#include "ld.h"
+/* TODO: This function must go in pass2 */
static void
rebase(Obj *obj)
{
--- /dev/null
+++ b/src/cmd/ld/section.c
@@ -1,0 +1,140 @@
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <scc/mach.h>
+#include <scc/scc.h>
+
+#include "ld.h"
+
+#define NR_SECTION 32
+
+struct sectab {
+ Section sec;
+ FILE *tmpfp;
+ struct sectab *hash;
+ struct sectab *next, *prev;
+};
+
+static struct sectab *sectab[NR_SECTION];
+static struct sectab secs = {.next = &secs, .prev = &secs};
+
+static Section *
+linksec(struct sectab *lst, Section *sec)
+{
+ struct sectab *sp = (struct sectab *) sec;
+
+ sp->next = lst;
+ sp->prev = lst->prev;
+ lst->prev->next = sp;
+ lst->prev = sp;
+
+ return sec;
+}
+
+Section *
+lookupsec(char *name)
+{
+ unsigned h;
+ size_t len;
+ char *s;
+ Section *sec;
+ struct sectab *sp;
+
+ h = genhash(name) % NR_SECTION;
+ for (sp = sectab[h]; sp; sp = sp->hash) {
+ if (!strcmp(name, sp->sec.name))
+ return &sp->sec;
+ }
+
+ len = strlen(name) + 1;
+ s = malloc(len);
+ sp = malloc(sizeof(*sp));
+ if (!s || !sp) {
+ error(strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ sec = &sp->sec;
+ sec->name = memcpy(s, name, len);
+ sec->type = 'U';
+ sec->base = 0;
+ sec->size = 0;
+ sec->align = 0;
+ sec->index = 0;
+ sec->flags = 0;
+ sp->tmpfp;
+ sp->hash = sectab[h];
+ sectab[h] = sp;
+
+ return linksec(&secs, sec);
+}
+
+void
+copy(Obj *obj, Section *osec, Section *sec)
+{
+ struct sectab *sp = (struct sectab *) sec;
+
+ if (sec->size > ULLONG_MAX - osec->size) {
+ error("%s: section too long", sec->name);
+ return;
+ }
+
+ if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
+ error(strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (mapsec(obj, osec->index, sp->tmpfp) < 0) {
+ error(strerror(errno));
+ return;
+ }
+
+ sec->size += osec->size;
+}
+
+void
+grow(Section *sec, int nbytes)
+{
+ struct sectab *sp = (struct sectab *) sec;
+
+ if (sec->size > ULLONG_MAX - nbytes) {
+ error("%s: section too long", sec->name);
+ return;
+ }
+
+ if (!sp->tmpfp && (sp->tmpfp = tmpfile()) == NULL) {
+ error(strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ while (nbytes-- > 0)
+ putc(0, sp->tmpfp);
+
+ sec->size += nbytes;
+}
+
+#ifndef NDEBUG
+void
+debugsec(void)
+{
+ struct sectab **spp, *sp;
+ Section *sec;
+
+ fputs("Sections:\n", stderr);
+ for (spp = sectab; spp < §ab[NR_SECTION]; spp++) {
+ for (sp = *spp; sp; sp = sp->hash) {
+ sec = &sp->sec;
+ fprintf(stderr,
+ "sec: %s - %c (%#llx,%#lx)\n",
+ sec->name,
+ sec->type,
+ sec->base,
+ sec->size);
+ }
+ }
+}
+#endif
\ No newline at end of file
--- a/src/cmd/ld/symbol.c
+++ b/src/cmd/ld/symbol.c
@@ -1,3 +1,5 @@
+#include <assert.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -8,95 +10,147 @@
#include "ld.h"
#define NR_SYMBOL 128
-#define NR_SECTIONS 32
-static Symbol *symtab[NR_SYMBOL];
-static Section *sectab[NR_SECTIONS];
-static Section *seclast;
+/*
+ * struct symtab and struct sectab have a Symbol and a
+ * Section as first field because the code is going to
+ * cast from the symbols and the sections to the tab.
+ */
+struct symtab {
+ Symbol sym;
+ Obj *where;
+ struct symtab *hash;
+ struct symtab *next, *prev;
+};
-Section *sechead;
+static struct symtab *symtab[NR_SYMBOL];
+static struct symtab undef = {.next = &undef, .prev = &undef};
+static struct symtab def = {.next = &def, .prev = &def};
+static struct symtab common = {.next = &common, .prev = &common};
-Symbol *
-lookup(char *name)
+static Symbol *
+unlinksym(Symbol *sym)
{
+ struct symtab *sp = (struct symtab *) sym;
+
+ sp->next->prev = sp->prev;
+ sp->prev->next = sp->next;
+
+ return sym;
+}
+
+static Symbol *
+linksym(struct symtab *lst, Symbol *sym)
+{
+ struct symtab *sp = (struct symtab *) sym;
+
+ sp->next = lst;
+ sp->prev = lst->prev;
+ lst->prev->next = sp;
+ lst->prev = sp;
+
+ return sym;
+}
+
+int
+hasref(char *name)
+{
unsigned h;
- Symbol *sym;
+ struct symtab *sp;
h = genhash(name) % NR_SYMBOL;
- for (sym = symtab[h]; sym; sym = sym->hash) {
- if (!strcmp(name, sym->name))
- return sym;
+ for (sp = symtab[h]; sp; sp = sp->hash) {
+ if (!strcmp(name, sp->sym.name))
+ return sp->sym.type == 'U';
}
-
- return NULL;
+ return 0;
}
Symbol *
-install(char *name)
+lookupsym(char *name)
{
unsigned h;
size_t len;
- Symbol *sym;
char *s;
+ Symbol *sym;
+ struct symtab *sp;
h = genhash(name) % NR_SYMBOL;
+ for (sp = symtab[h]; sp; sp = sp->hash) {
+ if (!strcmp(name, sp->sym.name))
+ return &sp->sym;
+ }
len = strlen(name) + 1;
s = malloc(len);
- sym = malloc(sizeof(*sym));
- if (!s || !sym) {
- error("out of memory");
+ sp = malloc(sizeof(*sp));
+ if (!s || !sp) {
+ error(strerror(errno));
exit(EXIT_FAILURE);
}
- sym->obj = NULL;
+ sym = &sp->sym;
sym->name = memcpy(s, name, len);
- sym->hash = symtab[h];
- symtab[h] = sym;
sym->value = 0;
sym->size = 0;
- sym->next = sym->prev = NULL;
+ sym->index = 0;
+ sym->type = 'U';
+ sp->where = NULL;
+ sp->hash = symtab[h];
+ symtab[h] = sp;
- return sym;
+ return linksym(&undef, sym);;
}
-Section *
-section(char *name)
+
+int
+moreundef(void)
{
- unsigned h;
- size_t len;
- char *s;
- Section *sec;
+ return undef.next != &undef;
+}
- h = genhash(name) % NR_SECTIONS;
- for (sec = sectab[h]; sec; sec = sec->hash) {
- if (!strcmp(name, sec->name))
- return sec;
- }
+void
+listundef(void)
+{
+ struct symtab *sp;
- len = strlen(name) + 1;
- s = malloc(len);
- sec = malloc(sizeof(*sec));
- if (!s || !sec) {
- error("out of memory");
- exit(EXIT_FAILURE);
- }
+ for (sp = undef.next; sp != &undef; sp = sp->next)
+ error("ld: symbol '%s' not defined", sp->sym.name);
+}
- sec->name = memcpy(s, name, len);
- sec->type = '?';
- sec->base = 0;
- sec->size = 0;
- sec->flags = 0;
- sec->hash = sectab[h];
- sectab[h] = sec;
+Symbol *
+define(Symbol *osym, Obj *obj)
+{
+ struct symtab *lst;
+ Symbol *sym = lookupsym(osym->name);
+ struct symtab *sp = (struct symtab *) sym;
- if (!sechead)
- sechead = sec;
- else
- seclast->next = sec;
- sec->next = NULL;
+ assert(osym->type != 'U');
+ sp->where = obj;
- return seclast = sec;
+ switch (sym->type) {
+ case 'U':
+ sym->value = osym->value;
+ sym->size = osym->size;
+ lst = (osym->type == 'C') ? &common : &def;
+ linksym(lst, unlinksym(sym));
+ break;
+ case 'C':
+ if (osym->type != 'C') {
+ sym->size = osym->size;
+ sym->value = osym->size;
+ linksym(&def, unlinksym(sym));
+ } else if (sym->size < osym->size) {
+ sym->value = osym->value;
+ sym->size = osym->size;
+ }
+ break;
+ defaul:
+ error("%s: symbol redefined", sym->name);
+ break;
+ }
+
+ return sym;
}
#ifndef NDEBUG
@@ -103,39 +157,18 @@
void
debugsym(void)
{
- Symbol **symp, *sym;
+ struct symtab **spp, *sp;
+ Symbol*sym;
fputs("Symbols:\n", stderr);
- for (symp = symtab; symp < &symtab[NR_SYMBOL]; symp++) {
- for (sym = *symp; sym; sym = sym->hash)
+ for (spp = symtab; spp < &symtab[NR_SYMBOL]; spp++) {
+ for (sp = *spp; sp; sp = sp->hash) {
+ sym = &sp->sym;
fprintf(stderr,
"sym: %s (%#llx)\n",
sym->name,
sym->value);
- }
-}
-
-void
-debugsec(void)
-{
- Section **secp, *sec;
-
- fputs("Sections:\n", stderr);
- for (secp = sectab; secp < §ab[NR_SECTIONS]; secp++) {
- for (sec = *secp; sec; sec = sec->hash)
- fprintf(stderr,
- "sec: %s - %c (%#llx,%#lx)\n",
- sec->name,
- sec->type,
- sec->base,
- sec->size);
- }
-
- for (sec = sechead; sec; sec = sec->next) {
- fprintf(stderr,
- "%s %s",
- sec->name,
- sec->next ? "->" : "\n");
+ }
}
}
#endif
--- a/src/cmd/ranlib.c
+++ b/src/cmd/ranlib.c
@@ -201,7 +201,7 @@
if (strcmp(memb, "/") == 0 || strcmp(memb, "__.SYMDEF") == 0)
cur = ftell(fp) + off;
- fseek(fp, SEEK_SET, cur);
+ fseek(fp, cur, SEEK_SET);
for (;;) {
cur = ftell(fp);
off = armember(fp, memb);
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -4,23 +4,26 @@
TARGET = $(LIBDIR)/libmach.a
-OBJS = mach.o \
- newobj.o \
- delobj.o \
- objpos.o \
- archive.o \
- armember.o \
- objtype.o \
- readobj.o \
- writeobj.o \
- getsym.o \
- getsec.o \
- strip.o \
- pc2line.o \
- pack.o \
- unpack.o \
- setindex.o \
- getindex.o \
+OBJS =\
+ mach.o\
+ newobj.o \
+ delobj.o\
+ objpos.o\
+ archive.o\
+ armember.o\
+ objtype.o\
+ readobj.o\
+ writeobj.o\
+ getsym.o\
+ getsec.o\
+ rebase.o\
+ mapsec.o\
+ strip.o\
+ pc2line.o\
+ pack.o\
+ unpack.o\
+ setindex.o\
+ getindex.o\
DIRS = coff32
--- /dev/null
+++ b/src/libmach/mapsec.c
@@ -1,0 +1,11 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+int
+mapsec(Obj *obj, int idx, FILE *fp)
+{
+ return 0;
+}
--- /dev/null
+++ b/src/libmach/rebase.c
@@ -1,0 +1,11 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#include "libmach.h"
+
+int
+rebase(Obj *obj, long idx, unsigned long base)
+{
+ return 0;
+}