scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit b2b440217796f450751690e4fb414c0eb53fc2a0
parent 72c4ba730f7a0013439dc6d8b6c77536999798c0
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 29 Aug 2019 18:51:11 +0100

[ld] Rewrite ld to use the new interfaces

This patch reintroduces ld and do some other small changes.

Diffstat:
Minclude/scc/scc/mach.h | 21++++++++++++++++++---
Msrc/cmd/Makefile | 21+++++++++++----------
Msrc/cmd/ld/Makefile | 17++++++++++-------
Msrc/cmd/ld/ld.h | 60++++++++++++------------------------------------------------
Msrc/cmd/ld/main.c | 12++++--------
Msrc/cmd/ld/pass1.c | 319+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/cmd/ld/pass3.c | 1+
Asrc/cmd/ld/section.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/cmd/ld/symbol.c | 197++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc/cmd/ranlib.c | 2+-
Msrc/libmach/Makefile | 37++++++++++++++++++++-----------------
Asrc/libmach/mapsec.c | 11+++++++++++
Asrc/libmach/rebase.c | 11+++++++++++
13 files changed, 473 insertions(+), 377 deletions(-)

diff --git 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 @@ struct obj { 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 @@ struct symbol { unsigned long long size; unsigned long long value; int index; - char class; + int section; char type; }; @@ -53,7 +65,10 @@ extern int writeobj(Obj *obj, FILE *fp); 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); diff --git 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 \ - -DIRS = as scc +TARGET =\ + $(BINDIR)/nm\ + $(BINDIR)/ar\ + $(BINDIR)/strip\ + $(BINDIR)/size\ + $(BINDIR)/ranlib\ + $(BINDIR)/objdump\ + $(BINDIR)/objcopy\ + $(BINDIR)/addr2line\ + +DIRS = ld as scc LIBMACH = $(LIBDIR)/libmach.a LIBSCC = $(LIBDIR)/libscc.a diff --git a/src/cmd/ld/Makefile b/src/cmd/ld/Makefile @@ -4,13 +4,16 @@ include $(PROJECTDIR)/scripts/rules.mk 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) diff --git 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 pass4(int argc, char *argv[]); 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 dflag; 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; diff --git 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 @@ Segment debug = {.type = 'N'}; char *output = "a.out", *entry = "start"; static int status; -char * -errstr(void) -{ - return strerror(errno); -} - void error(char *fmt, ...) { @@ -67,10 +62,10 @@ 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(); } @@ -131,6 +126,7 @@ main(int argc, char *argv[]) break; case 'u': case 'l': + /* FIXME: This way of handling options is wrong */ arg = (cp[1]) ? cp+1 : *++ap; if (!arg) goto usage; diff --git 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,227 +17,138 @@ enum { }; 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; } return 0; } - -static int -newsym(Objsym *osym, Obj *obj) +static void +newsec(Section *osec, Obj *obj) { - Symbol *sym; - - 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; + int align; + Section *sec; + unsigned long long base; + + 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; } 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; char **names; Symbol *sym; - if ((*binops->getidx)(&n, &names, &offs, fp) < 0) { + if (getindex(bintype, &n, &names, &offs, fp) < 0) { error("corrupted index"); return; } 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()); - goto clean; - } - - if ((t = objtype(fp, NULL)) == -1) { - error("library file corrupted"); - goto clean; - } - - if (t != bintype) { - error("incompatible library"); + error(strerror(errno)); goto clean; } - newobject(fp, t, OUTLIB); + load(fp, OUTLIB); added = 1; } @@ -250,62 +162,66 @@ clean: 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; - } - - if (*nmemb++ == 0) { - if (!strncmp(name, "/", SARNAM) || - !strncmp(name, "__.SYMDEF", SARNAM)) { - addlib(fp); - return 0; - } + return; } - membname = name; - if ((t = objtype(fp, NULL)) == -1) - return 1; + cur = ftell(fp); + if ((off = armember(fp, memb)) < 0) + goto corrupted; - if (bintype != t) { - error("wrong object file format"); - return 1; + if (strcmp(memb, "/") == 0 || strcmp(memb, "__.SYMDEF") == 0) { + scanindex(fp); + return; } - newobject(fp, t, INLIB); - membname = NULL; - - return 1; -} - -static int -newlibrary(FILE *fp) -{ - int nmemb = 0; + 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; + } + } - return formember(fp, newmember, &nmemb); +corrupted: + error(strerror(errno)); + error("library corrupted"); } 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; 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 @@ openfile(char *name, char *buffer) 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 @@ openfile(char *name, char *buffer) 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 @@ openfile(char *name, char *buffer) } 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 @@ pass1(int argc, char *argv[]) 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; } } diff --git 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) { diff --git a/src/cmd/ld/section.c b/src/cmd/ld/section.c @@ -0,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 < &sectab[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 diff --git 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,134 +10,165 @@ #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; +}; + +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}; + +static Symbol * +unlinksym(Symbol *sym) +{ + struct symtab *sp = (struct symtab *) sym; -Section *sechead; + sp->next->prev = sp->prev; + sp->prev->next = sp->next; -Symbol * -lookup(char *name) + 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); +} + +Symbol * +define(Symbol *osym, Obj *obj) +{ + struct symtab *lst; + Symbol *sym = lookupsym(osym->name); + struct symtab *sp = (struct symtab *) sym; + + assert(osym->type != 'U'); + sp->where = obj; + + 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; } - sec->name = memcpy(s, name, len); - sec->type = '?'; - sec->base = 0; - sec->size = 0; - sec->flags = 0; - sec->hash = sectab[h]; - sectab[h] = sec; - - if (!sechead) - sechead = sec; - else - seclast->next = sec; - sec->next = NULL; - - return seclast = sec; + return sym; } #ifndef NDEBUG 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 < &sectab[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 diff --git a/src/cmd/ranlib.c b/src/cmd/ranlib.c @@ -201,7 +201,7 @@ readsyms(FILE *fp) 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); diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -4,23 +4,26 @@ include $(PROJECTDIR)/scripts/rules.mk 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 diff --git a/src/libmach/mapsec.c b/src/libmach/mapsec.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +int +mapsec(Obj *obj, int idx, FILE *fp) +{ + return 0; +} diff --git a/src/libmach/rebase.c b/src/libmach/rebase.c @@ -0,0 +1,11 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +int +rebase(Obj *obj, long idx, unsigned long base) +{ + return 0; +}