scc

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

commit c2726e4e6f4030a92451b51612859d7a40c67885
parent 1a83b7b7311b8944a34d8e16ad9aa22aa7a4a051
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 14 Mar 2018 21:03:03 +0100

[ld/coff32] Add basic support for files

Diffstat:
Mld/Makefile | 2+-
Mld/coff32.c | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mld/ld.h | 18++++++++++++++++--
Mld/main.c | 5+++--
Ald/obj.c | 33+++++++++++++++++++++++++++++++++
5 files changed, 120 insertions(+), 7 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 = main.o formats.o coff32.o obj.o all: ld cp ld $(PROJECTDIR)/rootdir/bin diff --git a/ld/coff32.c b/ld/coff32.c @@ -1,6 +1,8 @@ static char sccsid[] = "@(#) ./ld/coff32.c"; +#include <assert.h> #include <errno.h> +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -11,12 +13,75 @@ static char sccsid[] = "@(#) ./ld/coff32.c"; #include "../inc/scc.h" #include "ld.h" -static int +static int (*unpack)(unsigned char *, char *, ...); +static long strtbl, symtbl, sectbl; + +static FILHDR * +getfhdr(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); + assert(n == FILHSZ); + return hdr; +} + +static void pass1(char *fname, char *member, FILE *fp) { + unsigned char buff[FILHSZ]; + FILHDR *hdr; + Obj *obj; + long siz, pos = ftell(fp); + char *str; + + if (fread(buff, FILHSZ, 1, fp) != 1) + goto bad_file; + + if ((hdr = malloc(sizeof(*hdr))) == NULL) + goto out_of_memory; + + obj = newobj(fname); + obj->hdr = getfhdr(buff, hdr); + + /* TODO: Check overflow */ + strtbl = pos + hdr->f_symptr + hdr->f_nsyms* SYMESZ; + symtbl = pos + hdr->f_symptr; + sectbl = pos + FILHSZ + hdr->f_opthdr; + + if (fseek(fp, strtbl, SEEK_SET) == EOF) + goto bad_file; + + if (fread(buff, 4, 1, fp) != 1) + goto bad_file; + + (*unpack)(buff, "l", &siz); + + if (siz > SIZE_MAX || (str = malloc(siz)) == NULL) + goto out_of_memory; + + if (fread(str, siz, 1, fp) != 1) + goto bad_file; + + obj->strtbl = str; + +out_of_memory: + die("ld: out of memory"); +bad_file: + if (ferror(fp)) + die("ld: %s: %s", fname, strerror(errno)); + die("ld: %s: corrupted file", fname); } -static int +static void pass2(char *fname, char *member, FILE *fp) { } diff --git a/ld/ld.h b/ld/ld.h @@ -1,6 +1,20 @@ +typedef struct obj Obj; + +struct obj { + char *fname; + void *hdr; + char *strtbl; + struct obj *next; +}; + +#ifdef stdin struct objfile { int (*probe)(char *fname, char *member, FILE *fp); - int (*pass1)(char *fname, char *member, FILE *fp); - int (*pass2)(char *fname, char *member, FILE *fp); + void (*pass1)(char *fname, char *member, FILE *fp); + void (*pass2)(char *fname, char *member, FILE *fp); }; +#endif + +/* obj.c */ +extern Obj *newobj(char *fname); diff --git a/ld/main.c b/ld/main.c @@ -21,7 +21,7 @@ object(char *fname, char *member, FILE *fp) extern struct objfile *formats[]; struct objfile **p, *obj; void *data; - int (*fun)(char *, char *, FILE *); + void (*fun)(char *, char *, FILE *); for (p = formats; *p; ++p) { obj = *p; @@ -32,7 +32,8 @@ object(char *fname, char *member, FILE *fp) return 0; fun = (pass == 1) ? obj->pass1 : obj->pass2; - return (*fun)(fname, member, fp); + (*fun)(fname, member, fp); + return 1; } static char * diff --git a/ld/obj.c b/ld/obj.c @@ -0,0 +1,33 @@ +static char sccsid[] = "@(#) ./ld/obj.c"; + +#include <stdlib.h> +#include <string.h> + +#include "../inc/scc.h" +#include "ld.h" + +Obj *objlst; +static Obj *tail; + +Obj * +newobj(char *fname) +{ + Obj *obj; + char *s; + size_t len = strlen(fname); + + obj = malloc(sizeof(*obj)); + s = malloc(len+1); + if (!obj || !s) + die("ld: out of memory"); + + obj->fname = memcpy(s, fname, len); + obj->next = NULL; + + if (!objlst) + tail = objlst = obj; + else + tail->next = obj; + + return obj; +}