commit 6b7bd71741d013c4b2a0abd66852070b89584fe3 parent c411ea5ee205b0f8c6e575d166f8a3b762e6b659 Author: Roberto E. Vargas Caballero <k0ga@shike2.com> Date: Fri, 24 Jan 2025 12:41:15 +0100 libmach: Remove polymorphic struct This struct was pulling the full library in every binary, when it was not needed. Having an array per function is maybe less comfortable, but it avoids many references to symbols and avoid pulling them. Diffstat:
50 files changed, 197 insertions(+), 151 deletions(-)
diff --git a/include/bits/scc/coff32.h b/include/bits/scc/coff32.h @@ -46,26 +46,6 @@ struct arch { int flags; }; -extern int coff32new(Obj *, int); -extern int coff32read(Obj *, FILE *); -extern int coff32setidx(long, char **, long *, FILE *); -extern int coff32getidx(long *, char ***, long **, FILE *); -extern int coff32pc2line(Obj *, unsigned long long, char *, int *); -extern int coff32strip(Obj *); -extern void coff32del(Obj *); -extern int coff32write(Obj *, Map *, FILE *); -extern int coff32probe(unsigned char *, char **); -extern int coff32type(char *); - -extern int coff32xsetidx(int, long , char *[], long[], FILE *); -extern int coff32xgetidx(int, long *, char ***, long **, FILE *); - -extern Symbol *coff32getsym(Obj *, int *, Symbol *); -extern Symbol *coff32setsym(Obj *, int *, Symbol *); -extern Section *coff32getsec(Obj *, int *, Section *); -extern Section *coff32setsec(Obj *, int *, Section *); -extern Map *coff32loadmap(Obj *, FILE *); - extern char *coff32str(Coff32 *, void *); diff --git a/include/bits/scc/elf64.h b/include/bits/scc/elf64.h @@ -42,24 +42,6 @@ struct arch { int type; }; -extern int elf64new(Obj *, int); -extern int elf64read(Obj *, FILE *); -extern int elf64setidx(long, char **, long *, FILE *); -extern int elf64getidx(long *, char ***, long **, FILE *); -extern int elf64pc2line(Obj *, unsigned long long , char *, int *); -extern int elf64strip(Obj *); -extern void elf64del(Obj *); -extern int elf64write(Obj *, Map *, FILE *); -extern int elf64probe(unsigned char *, char **); -extern int elf64type(char *); - -extern int elf64xsetidx(int long , char *[], long [], FILE *); -extern int elf64xgetidx(int, long *, char ***, long **, FILE *); - -extern Symbol *elf64getsym(Obj *, int *, Symbol *); -extern Section *elf64getsec(Obj *, int *, Section *); -extern Map *elf64loadmap(Obj *, FILE *); - extern char *elf64str(Obj *, int n, long); /* globals */ diff --git a/include/bits/scc/mach.h b/include/bits/scc/mach.h @@ -10,11 +10,11 @@ #define FORMAT(t) ((t) & 0x1f) #define ARCH(t) (((t) >> 5) & 0x1f) #define ORDER(t) (((t) >> 10) & 0x1f) +#define objfmt(o) FORMAT((o)->type) typedef struct segment Segment; typedef struct section Section; typedef struct symbol Symbol; -typedef struct objops Objops; typedef struct obj Obj; typedef struct map Map; typedef struct mapsec Mapsec; @@ -72,7 +72,6 @@ struct ar_hdr; struct obj { char *index; - Objops *ops; int type; long pos; void *data; diff --git a/src/cmd/scc-objdump/main.c b/src/cmd/scc-objdump/main.c @@ -272,7 +272,7 @@ dumpobj(FILE *fp, int type, char *fmt) goto err; } - switch (FORMAT(obj->type)) { + switch (objfmt(obj)) { case COFF32: op = &ops[COFF32]; break; diff --git a/src/libmach/coff32/Makefile b/src/libmach/coff32/Makefile @@ -4,7 +4,6 @@ PROJECTDIR =../../.. include $(PROJECTDIR)/scripts/rules.mk OBJS =\ - coff32.o\ coff32archs.o\ coff32del.o\ coff32getidx.o\ diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c @@ -1,24 +0,0 @@ -#include <stdio.h> - -#include <scc/mach.h> -#include <scc/coff32.h> - -#include "../libmach.h" - -struct objops coff32 = { - .type = coff32type, - .probe = coff32probe, - .new = coff32new, - .read = coff32read, - .getidx = coff32getidx, - .setidx = coff32setidx, - .pc2line = coff32pc2line, - .strip = coff32strip, - .del = coff32del, - .write = coff32write, - .getsym = coff32getsym, - .setsym = coff32setsym, - .getsec = coff32getsec, - .setsec = coff32setsec, - .loadmap = coff32loadmap, -}; diff --git a/src/libmach/coff32/coff32del.c b/src/libmach/coff32/coff32del.c @@ -5,6 +5,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" void coff32del(Obj *obj) diff --git a/src/libmach/coff32/coff32getidx.c b/src/libmach/coff32/coff32getidx.c @@ -4,6 +4,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32getidx(long *nsyms, char ***namep, long **offsp, FILE *fp) diff --git a/src/libmach/coff32/coff32getsec.c b/src/libmach/coff32/coff32getsec.c @@ -4,6 +4,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" Section * coff32getsec(Obj *obj, int *idx, Section *sec) diff --git a/src/libmach/coff32/coff32getsym.c b/src/libmach/coff32/coff32getsym.c @@ -6,6 +6,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" static int typeof(Coff32 *coff, SYMENT *ent) diff --git a/src/libmach/coff32/coff32loadmap.c b/src/libmach/coff32/coff32loadmap.c @@ -4,6 +4,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" Map * coff32loadmap(Obj *obj, FILE *fp) diff --git a/src/libmach/coff32/coff32new.c b/src/libmach/coff32/coff32new.c @@ -5,6 +5,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32new(Obj *obj, int type) diff --git a/src/libmach/coff32/coff32pc2line.c b/src/libmach/coff32/coff32pc2line.c @@ -3,6 +3,7 @@ #include <scc/mach.h> #include "../libmach.h" +#include "fun.h" int coff32pc2line(Obj *obj, unsigned long long addr, char *fname, int *line) diff --git a/src/libmach/coff32/coff32probe.c b/src/libmach/coff32/coff32probe.c @@ -4,6 +4,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32probe(unsigned char *buf, char **name) diff --git a/src/libmach/coff32/coff32read.c b/src/libmach/coff32/coff32read.c @@ -9,6 +9,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" static void unpack_hdr(int order, unsigned char *buf, FILHDR *hdr) diff --git a/src/libmach/coff32/coff32setidx.c b/src/libmach/coff32/coff32setidx.c @@ -4,6 +4,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32setidx(long nsymbols, char *names[], long offs[], FILE *fp) diff --git a/src/libmach/coff32/coff32setsec.c b/src/libmach/coff32/coff32setsec.c @@ -7,6 +7,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" static char * secname(Coff32 *coff, SCNHDR *scn, Section *sec) diff --git a/src/libmach/coff32/coff32setsym.c b/src/libmach/coff32/coff32setsym.c @@ -7,6 +7,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" static int defent(Coff32 *coff, SYMENT *ent, Symbol *sym) diff --git a/src/libmach/coff32/coff32strip.c b/src/libmach/coff32/coff32strip.c @@ -5,6 +5,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32strip(Obj *obj) diff --git a/src/libmach/coff32/coff32type.c b/src/libmach/coff32/coff32type.c @@ -5,6 +5,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32type(char *name) diff --git a/src/libmach/coff32/coff32write.c b/src/libmach/coff32/coff32write.c @@ -9,6 +9,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" struct strtbl { char *s; diff --git a/src/libmach/coff32/coff32xgetidx.c b/src/libmach/coff32/coff32xgetidx.c @@ -7,6 +7,7 @@ #include <scc/coff32.h> #include "../libmach.h" +#include "fun.h" int coff32xgetidx(int order, long *nsyms, char ***namep, long **offsp, FILE *fp) diff --git a/src/libmach/coff32/coff32xsetidx.c b/src/libmach/coff32/coff32xsetidx.c @@ -4,6 +4,7 @@ #include <scc/mach.h> #include "../libmach.h" +#include "fun.h" int coff32xsetidx(int order, long nsyms, char *names[], long offs[], FILE *fp) diff --git a/src/libmach/coff32/fun.h b/src/libmach/coff32/fun.h @@ -0,0 +1,19 @@ +extern int coff32new(Obj *, int); +extern int coff32read(Obj *, FILE *); +extern int coff32setidx(long, char **, long *, FILE *); +extern int coff32getidx(long *, char ***, long **, FILE *); +extern int coff32pc2line(Obj *, unsigned long long, char *, int *); +extern int coff32strip(Obj *); +extern void coff32del(Obj *); +extern int coff32write(Obj *, Map *, FILE *); +extern int coff32probe(unsigned char *, char **); +extern int coff32type(char *); + +extern int coff32xsetidx(int, long , char *[], long[], FILE *); +extern int coff32xgetidx(int, long *, char ***, long **, FILE *); + +extern Symbol *coff32getsym(Obj *, int *, Symbol *); +extern Symbol *coff32setsym(Obj *, int *, Symbol *); +extern Section *coff32getsec(Obj *, int *, Section *); +extern Section *coff32setsec(Obj *, int *, Section *); +extern Map *coff32loadmap(Obj *, FILE *); diff --git a/src/libmach/delobj.c b/src/libmach/delobj.c @@ -5,9 +5,17 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static void (*ops[NFORMATS])(Obj *) = { + [COFF32] = coff32del, + [ELF64] = elf64del, +}; + void delobj(Obj *obj) { - (*obj->ops->del)(obj); + (*ops[objfmt(obj)])(obj); free(obj); -} -\ No newline at end of file +} diff --git a/src/libmach/elf64/elf64.c b/src/libmach/elf64/elf64.c @@ -4,22 +4,7 @@ #include <scc/elf64.h> #include "../libmach.h" - -struct objops elf64 = { - .type = elf64type, - .probe = elf64probe, - .new = elf64new, - .read = elf64read, - .getidx = NULL, - .setidx = NULL, - .pc2line = NULL, - .strip = NULL, - .del = elf64del, - .write = NULL, - .getsym = elf64getsym, - .getsec = elf64getsec, - .loadmap = NULL, -}; +#include "fun.h" char * elf64str(Obj *obj, int n, long stroff) diff --git a/src/libmach/elf64/elf64del.c b/src/libmach/elf64/elf64del.c @@ -5,6 +5,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" void elf64del(Obj *obj) diff --git a/src/libmach/elf64/elf64getsec.c b/src/libmach/elf64/elf64getsec.c @@ -4,6 +4,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" Section * elf64getsec(Obj *obj, int *idx, Section *sec) diff --git a/src/libmach/elf64/elf64getsym.c b/src/libmach/elf64/elf64getsym.c @@ -7,6 +7,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" static int typeof(Elf64 *elf, Elf_Sym *ent, char *name) diff --git a/src/libmach/elf64/elf64new.c b/src/libmach/elf64/elf64new.c @@ -5,6 +5,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" int elf64new(Obj *obj, int type) diff --git a/src/libmach/elf64/elf64probe.c b/src/libmach/elf64/elf64probe.c @@ -4,6 +4,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" int elf64probe(unsigned char *buf, char **name) diff --git a/src/libmach/elf64/elf64read.c b/src/libmach/elf64/elf64read.c @@ -6,6 +6,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" static int unpack_hdr(int order, unsigned char *buf, Elf_Ehdr *hdr) diff --git a/src/libmach/elf64/elf64type.c b/src/libmach/elf64/elf64type.c @@ -5,6 +5,7 @@ #include <scc/elf64.h> #include "../libmach.h" +#include "fun.h" int elf64type(char *name) diff --git a/src/libmach/elf64/fun.h b/src/libmach/elf64/fun.h @@ -0,0 +1,17 @@ +extern int elf64new(Obj *, int); +extern int elf64read(Obj *, FILE *); +extern int elf64setidx(long, char **, long *, FILE *); +extern int elf64getidx(long *, char ***, long **, FILE *); +extern int elf64pc2line(Obj *, unsigned long long , char *, int *); +extern int elf64strip(Obj *); +extern void elf64del(Obj *); +extern int elf64write(Obj *, Map *, FILE *); +extern int elf64probe(unsigned char *, char **); +extern int elf64type(char *); + +extern int elf64xsetidx(int long , char *[], long [], FILE *); +extern int elf64xgetidx(int, long *, char ***, long **, FILE *); + +extern Symbol *elf64getsym(Obj *, int *, Symbol *); +extern Section *elf64getsec(Obj *, int *, Section *); +extern Map *elf64loadmap(Obj *, FILE *); diff --git a/src/libmach/getindex.c b/src/libmach/getindex.c @@ -5,6 +5,13 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(long *, char ***, long **, FILE *) = { + [COFF32] = coff32getidx, +}; + int getindex(int type, long *nsyms, char ***names, long **offs, FILE *fp) { @@ -16,6 +23,6 @@ getindex(int type, long *nsyms, char ***names, long **offs, FILE *fp) return -1; } - return (*objops[fmt]->getidx)(nsyms, names, offs, fp); + return (*ops[fmt])(nsyms, names, offs, fp); } diff --git a/src/libmach/getsec.c b/src/libmach/getsec.c @@ -4,8 +4,16 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static Section *(*ops[NFORMATS])(Obj *, int *, Section *) = { + [COFF32] = coff32getsec, + [ELF64] = elf64getsec, +}; + Section * getsec(Obj *obj, int *idx, Section *sec) { - return (*obj->ops->getsec)(obj, idx, sec); + return (*ops[objfmt(obj)])(obj, idx, sec); } diff --git a/src/libmach/getsym.c b/src/libmach/getsym.c @@ -4,8 +4,16 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static Symbol *(*ops[NFORMATS])(Obj *, int *, Symbol *) = { + [COFF32] = coff32getsym, + [ELF64] = elf64getsym, +}; + Symbol * getsym(Obj *obj, int *index, Symbol *sym) { - return (*obj->ops->getsym)(obj, index, sym); + return (*ops[objfmt(obj)])(obj, index, sym); } diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -1,28 +1,3 @@ - -struct objops { - int (*type)(char *); - int (*probe)(unsigned char *, char **); - - int (*new)(Obj *, int); - void (*del)(Obj *); - - int (*read)(Obj *, FILE *); - int (*write)(Obj *, Map *, FILE *); - - int (*strip)(Obj *); - int (*pc2line)(Obj *, unsigned long long , char *, int *); - - Map *(*loadmap)(Obj *, FILE *); - - Symbol *(*getsym)(Obj *, int *, Symbol *); - Symbol *(*setsym)(Obj *, int *, Symbol *); - Section *(*getsec)(Obj *, int *, Section *); - Section *(*setsec)(Obj *, int *, Section *); - - int (*setidx)(long, char *[], long[], FILE *); - int (*getidx)(long *, char ***, long **, FILE *); -}; - struct map { int n; struct mapsec { @@ -37,8 +12,3 @@ struct map { /* common functions */ extern int pack(int order, unsigned char *dst, char *fmt, ...); extern int unpack(int order, unsigned char *src, char *fmt, ...); - -/* globals */ -extern Objops *objops[]; -extern Objops coff32; -extern Objops elf64; diff --git a/src/libmach/loadmap.c b/src/libmach/loadmap.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static Map *(*ops[NFORMATS])(Obj *, FILE *) = { + [COFF32] = coff32loadmap, +}; + Map * loadmap(Obj *obj, FILE *fp) { - return (*obj->ops->loadmap)(obj, fp); + return (*ops[objfmt(obj)])(obj, fp); } diff --git a/src/libmach/mach.c b/src/libmach/mach.c @@ -1,11 +0,0 @@ -#include <stdio.h> - -#include <scc/mach.h> - -#include "libmach.h" - -Objops *objops[] = { - [COFF32] = &coff32, - [ELF64] = &elf64, - [NFORMATS] = NULL, -}; diff --git a/src/libmach/newobj.c b/src/libmach/newobj.c @@ -7,6 +7,14 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(Obj *, int) = { + [COFF32] = coff32new, + [ELF64] = elf64new, +}; + Obj * newobj(int type) { @@ -23,9 +31,8 @@ newobj(int type) return NULL; obj->type = type; - obj->ops = objops[fmt]; obj->next = NULL; - if ((*obj->ops->new)(obj, type) < 0) { + if ((*ops[fmt])(obj, type) < 0) { free(obj); return NULL; } diff --git a/src/libmach/objprobe.c b/src/libmach/objprobe.c @@ -4,12 +4,20 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(unsigned char *, char **) = { + [COFF32] = coff32probe, + [ELF64] = elf64probe, +}; + int objprobe(FILE *fp, char **name) { int n, t; fpos_t pos; - Objops **opsp, *ops; + int (**bp)(unsigned char *, char **); unsigned char buf[NBYTES]; fgetpos(fp, &pos); @@ -19,11 +27,9 @@ objprobe(FILE *fp, char **name) if (n != 1 || ferror(fp)) return -1; - for (opsp = objops; ops = *opsp; ++opsp) { - t = (*ops->probe)(buf, name); - if (t < 0) - continue; - return t; + for (bp = ops; bp < &ops[NFORMATS]; ++bp) { + if ((t = (**bp)(buf, name)) >= 0) + return t; } return -1; diff --git a/src/libmach/objtype.c b/src/libmach/objtype.c @@ -4,17 +4,23 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(char *) = { + [COFF32] = coff32type, + [ELF64] = elf64type, +}; + int objtype(char *name) { int t; - Objops **opsp, *ops; + int (**bp)(char *); - for (opsp = objops; ops = *opsp; ++opsp) { - t = (*ops->type)(name); - if (t < 0) - continue; - return t; + for (bp = ops; bp < &ops[NFORMATS]; ++bp) { + if ((t = (**bp)(name)) >= 0) + return t; } return -1; diff --git a/src/libmach/pc2line.c b/src/libmach/pc2line.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(Obj *, unsigned long long , char *, int *) = { + [COFF32] = coff32pc2line, +}; + int pc2line(Obj *obj, unsigned long long pc, char *fname, int *ln) { - return (*obj->ops->pc2line)(obj, pc, fname, ln); + return (*ops[objfmt(obj)])(obj, pc, fname, ln); } diff --git a/src/libmach/readobj.c b/src/libmach/readobj.c @@ -4,6 +4,14 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(Obj *, FILE *) = { + [COFF32] = coff32read, + [ELF64] = elf64read, +}; + int readobj(Obj *obj, FILE *fp) { @@ -13,5 +21,5 @@ readobj(Obj *obj, FILE *fp) return -1; obj->pos = off; - return (*obj->ops->read)(obj, fp); + return (*ops[objfmt(obj)])(obj, fp); } diff --git a/src/libmach/setindex.c b/src/libmach/setindex.c @@ -5,6 +5,13 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(long, char **, long *, FILE *) = { + [COFF32] = coff32setidx, +}; + int setindex(int type, long nsyms, char **names, long *offs, FILE *fp) { @@ -16,6 +23,6 @@ setindex(int type, long nsyms, char **names, long *offs, FILE *fp) return -1; } - return (*objops[fmt]->setidx)(nsyms, names, offs, fp); + return (*ops[fmt])(nsyms, names, offs, fp); } diff --git a/src/libmach/setsec.c b/src/libmach/setsec.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static Section *(*ops[NFORMATS])(Obj *, int *, Section *) = { + [COFF32] = coff32setsec, +}; + Section * setsec(Obj *obj, int *idx, Section *sec) { - return (*obj->ops->setsec)(obj, idx, sec); + return (*ops[objfmt(obj)])(obj, idx, sec); } diff --git a/src/libmach/setsym.c b/src/libmach/setsym.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static Symbol *(*ops[NFORMATS])(Obj *, int *, Symbol *) = { + [COFF32] = coff32setsym, +}; + Symbol * setsym(Obj *obj, int *index, Symbol *sym) { - return (*obj->ops->setsym)(obj, index, sym); + return (*ops[objfmt(obj)])(obj, index, sym); } diff --git a/src/libmach/strip.c b/src/libmach/strip.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(Obj *) = { + [COFF32] = coff32strip, +}; + int strip(Obj *obj) { - return (*obj->ops->strip)(obj); + return (*ops[objfmt(obj)])(obj); } diff --git a/src/libmach/writeobj.c b/src/libmach/writeobj.c @@ -4,8 +4,15 @@ #include "libmach.h" +#include "elf64/fun.h" +#include "coff32/fun.h" + +static int (*ops[NFORMATS])(Obj *, Map *, FILE *) = { + [COFF32] = coff32write, +}; + int writeobj(Obj *obj, Map *map, FILE *fp) { - return (obj->ops->write)(obj, map, fp); + return (*ops[objfmt(obj)])(obj, map, fp); }