scc

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

commit 6e437c91859e1364a61897e331d064d7697a0eec
parent 38f01a438be0d354c4f8fae5a23e37a4d4d0ad7e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 11 Feb 2019 19:25:55 +0000

[libmach] Add objsyms()

Don't do any load in objread(). This make the code
more orthogonal.

Diffstat:
Minclude/scc/scc/mach.h | 5+++--
Msrc/cmd/ld.c | 10+++++++---
Msrc/cmd/nm.c | 2+-
Msrc/cmd/ranlib.c | 2+-
Msrc/libmach/.gitignore | 1+
Msrc/libmach/Makefile | 16+++++++++-------
Msrc/libmach/coff32/Makefile | 1+
Asrc/libmach/coff32/coff32getsyms.c | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/coff32/coff32read.c | 86-------------------------------------------------------------------------------
Msrc/libmach/libmach.h | 2++
10 files changed, 115 insertions(+), 100 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -53,8 +53,6 @@ extern int formember(FILE *fp, int (*fn)(FILE *, char *, void *), void *data); -extern int archive(FILE *fp); -extern long armember(FILE *fp, char *member); extern int objtype(FILE *fp, char **name); extern Obj *objnew(int type); extern void objdel(Obj *obj); @@ -63,6 +61,9 @@ extern Objsym *objlookup(Obj *obj, char *name, int install); extern int objstrip(Obj *obj); extern int objwrite(Obj *obj, FILE *fp); extern int objsect(Obj *obj, Objsect **sect); +extern int objsyms(Obj *obj); +extern int archive(FILE *fp); +extern long armember(FILE *fp, char *member); extern long setindex(int type, long nsyms, Objsymdef *def, FILE *fp); extern int getindex(int type, long *nsyms, Objsymdef **def, FILE *fp); extern char *namindex(int type); diff --git a/src/cmd/ld.c b/src/cmd/ld.c @@ -207,10 +207,11 @@ loadobj(Obj *obj) return; } - if ((n = objsect(obj, &secp)) < 0) { - error("out of memory"); + if ((n = objsect(obj, &secp)) < 0) goto err1; - } + + if (objsyms(obj) < 0) + goto err2; lst->obj = obj; lst->next = NULL; @@ -227,8 +228,11 @@ loadobj(Obj *obj) return; +err2: + free(secp); err1: free(lst); + error("out of memory"); } static void diff --git a/src/cmd/nm.c b/src/cmd/nm.c @@ -155,7 +155,7 @@ newobject(FILE *fp, int type) return; } - if (objread(obj, fp) < 0) + if (objread(obj, fp) < 0 || objsyms(obj)) goto error; for (sym = obj->symbols; sym; sym = sym->next) diff --git a/src/cmd/ranlib.c b/src/cmd/ranlib.c @@ -144,7 +144,7 @@ newmember(FILE *fp, char *nam, void *data) return 0; } - if (objread(obj, fp) < 0) { + if (objread(obj, fp) < 0 || objsyms(obj) < 0) { error("file corrupted"); goto error; } diff --git a/src/libmach/.gitignore b/src/libmach/.gitignore @@ -10,3 +10,4 @@ getidx.c setidx.c namidx.c getsect.c +getsyms.c diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -4,17 +4,18 @@ include $(PROJECTDIR)/scripts/rules.mk TARGET = $(LIBDIR)/libmach.a -OBJS = addr2line.o \ - archive.o \ - armember.o \ - objdel.o \ - objlookup.o \ - objnew.o \ +OBJS = objnew.o \ objpos.o \ objread.o \ objfree.o \ objstrip.o \ objsect.o \ + objsyms.o \ + objdel.o \ + addr2line.o \ + archive.o \ + armember.o \ + objlookup.o \ getindex.o \ setindex.o \ namindex.o \ @@ -33,13 +34,14 @@ OBJS = addr2line.o \ setidx.o \ namidx.o \ getsect.o \ - + getsyms.o \ DIRS = coff32 TBLS = setidx.c \ getidx.c \ getsect.c \ + getsyms.c \ namidx.c \ new.c \ read.c \ diff --git a/src/libmach/coff32/Makefile b/src/libmach/coff32/Makefile @@ -14,6 +14,7 @@ OBJS = coff32del.o \ coff32getidx.o \ coff32namidx.o \ coff32getsect.o \ + coff32getsyms.o \ all: $(OBJS) diff --git a/src/libmach/coff32/coff32getsyms.c b/src/libmach/coff32/coff32getsyms.c @@ -0,0 +1,90 @@ +#include <stdio.h> +#include <ctype.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "coff32.h" + +static int +typeof(Coff32 *coff, SYMENT *ent) +{ + int c; + SCNHDR *scn; + long flags; + + switch (ent->n_scnum) { + case N_DEBUG: + c = 'N'; + break; + case N_ABS: + c = 'a'; + break; + case N_UNDEF: + c = (ent->n_value != 0) ? 'C' : 'U'; + break; + default: + if (ent->n_scnum > coff->hdr.f_nscns) + return -1; + scn = &coff->scns[ent->n_scnum-1]; + flags = scn->s_flags; + if (flags & STYP_TEXT) + c = 't'; + else if (flags & STYP_DATA) + c = 'd'; + else if (flags & STYP_BSS) + c = 'b'; + else + c = '?'; + break; + } + + if (ent->n_sclass == C_EXT) + c = toupper(c); + + return c; +} + +static char * +symname(Coff32 *coff, SYMENT *ent) +{ + long off; + + if (ent->n_zeroes != 0) + return ent->n_name; + + off = ent->n_offset; + if (off >= coff->strsiz) + return NULL; + return &coff->strtbl[off]; +} + +int +coff32getsyms(Obj *obj) +{ + int t; + long i; + char *s; + Objsym *sym; + SYMENT *ent; + Coff32 *coff = obj->data; + + for (i = 0; i < coff->hdr.f_nsyms; i += ent->n_numaux + 1) { + ent = &coff->ents[i]; + + if ((t = typeof(coff, ent)) < 0) + return 0; + + if ((s = symname(coff, ent)) == NULL) + return 0; + + if ((sym = objlookup(obj, s, 1)) == NULL) + return 0; + + sym->type = t; + sym->value = ent->n_value; + sym->size = (sym->type == 'C') ? ent->n_value : 0; + } + + return 1; +} diff --git a/src/libmach/coff32/coff32read.c b/src/libmach/coff32/coff32read.c @@ -1,5 +1,4 @@ #include <assert.h> -#include <ctype.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -245,89 +244,6 @@ readents(Obj *obj, FILE *fp) } static int -typeof(Coff32 *coff, SYMENT *ent) -{ - int c; - SCNHDR *scn; - long flags; - - switch (ent->n_scnum) { - case N_DEBUG: - c = 'N'; - break; - case N_ABS: - c = 'a'; - break; - case N_UNDEF: - c = (ent->n_value != 0) ? 'C' : 'U'; - break; - default: - if (ent->n_scnum > coff->hdr.f_nscns) - return -1; - scn = &coff->scns[ent->n_scnum-1]; - flags = scn->s_flags; - if (flags & STYP_TEXT) - c = 't'; - else if (flags & STYP_DATA) - c = 'd'; - else if (flags & STYP_BSS) - c = 'b'; - else - c = '?'; - break; - } - - if (ent->n_sclass == C_EXT) - c = toupper(c); - - return c; -} - -static char * -symname(Coff32 *coff, SYMENT *ent) -{ - long off; - - if (ent->n_zeroes != 0) - return ent->n_name; - - off = ent->n_offset; - if (off >= coff->strsiz) - return NULL; - return &coff->strtbl[off]; -} - -static int -loadsyms(Obj *obj) -{ - int t; - long i; - char *s; - Objsym *sym; - SYMENT *ent; - Coff32 *coff = obj->data; - - for (i = 0; i < coff->hdr.f_nsyms; i += ent->n_numaux + 1) { - ent = &coff->ents[i]; - - if ((t = typeof(coff, ent)) < 0) - return 0; - - if ((s = symname(coff, ent)) == NULL) - return 0; - - if ((sym = objlookup(obj, s, 1)) == NULL) - return 0; - - sym->type = t; - sym->value = ent->n_value; - sym->size = (sym->type == 'C') ? ent->n_value : 0; - } - - return 1; -} - -static int readscns(Obj *obj, FILE *fp) { FILHDR *hdr; @@ -440,8 +356,6 @@ coff32read(Obj *obj, FILE *fp) goto error; if (!readlines(obj, fp)) goto error; - if (!loadsyms(obj)) - goto error; return 0; error: diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -38,6 +38,7 @@ typedef long (*setidxfun_t)(int, long, Objsymdef *, FILE *); typedef int (*getidxfun_t)(int t, long *n, Objsymdef **def, FILE *fp); typedef int (*getsectfun_t)(Obj *obj, Objsect **secp); typedef char *(*namidxfun_t)(void); +typedef int (*getsymsfun_t)(Obj *obj); /* common functions */ extern int pack(int order, unsigned char *dst, char *fmt, ...); @@ -63,3 +64,4 @@ extern int coff32getidx(int order, long *nsyms, Objsymdef **def, FILE *fp); extern int coff32getsect(Obj *obj, Objsect **secp); extern char *coff32namidx(void); +extern int coff32getsyms(Obj *obj);