libmach: Remove polymorphic struct - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 6b7bd71741d013c4b2a0abd66852070b89584fe3
 (DIR) parent c411ea5ee205b0f8c6e575d166f8a3b762e6b659
 (HTM) 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:
         M include/bits/scc/coff32.h           |      20 --------------------
         M include/bits/scc/elf64.h            |      18 ------------------
         M include/bits/scc/mach.h             |       3 +--
         M src/cmd/scc-objdump/main.c          |       2 +-
         M src/libmach/coff32/Makefile         |       1 -
         D src/libmach/coff32/coff32.c         |      24 ------------------------
         M src/libmach/coff32/coff32del.c      |       1 +
         M src/libmach/coff32/coff32getidx.c   |       1 +
         M src/libmach/coff32/coff32getsec.c   |       1 +
         M src/libmach/coff32/coff32getsym.c   |       1 +
         M src/libmach/coff32/coff32loadmap.c  |       1 +
         M src/libmach/coff32/coff32new.c      |       1 +
         M src/libmach/coff32/coff32pc2line.c  |       1 +
         M src/libmach/coff32/coff32probe.c    |       1 +
         M src/libmach/coff32/coff32read.c     |       1 +
         M src/libmach/coff32/coff32setidx.c   |       1 +
         M src/libmach/coff32/coff32setsec.c   |       1 +
         M src/libmach/coff32/coff32setsym.c   |       1 +
         M src/libmach/coff32/coff32strip.c    |       1 +
         M src/libmach/coff32/coff32type.c     |       1 +
         M src/libmach/coff32/coff32write.c    |       1 +
         M src/libmach/coff32/coff32xgetidx.c  |       1 +
         M src/libmach/coff32/coff32xsetidx.c  |       1 +
         A src/libmach/coff32/fun.h            |      19 +++++++++++++++++++
         M src/libmach/delobj.c                |      13 ++++++++++---
         M src/libmach/elf64/elf64.c           |      17 +----------------
         M src/libmach/elf64/elf64del.c        |       1 +
         M src/libmach/elf64/elf64getsec.c     |       1 +
         M src/libmach/elf64/elf64getsym.c     |       1 +
         M src/libmach/elf64/elf64new.c        |       1 +
         M src/libmach/elf64/elf64probe.c      |       1 +
         M src/libmach/elf64/elf64read.c       |       1 +
         M src/libmach/elf64/elf64type.c       |       1 +
         A src/libmach/elf64/fun.h             |      17 +++++++++++++++++
         M src/libmach/getindex.c              |       9 ++++++++-
         M src/libmach/getsec.c                |      10 +++++++++-
         M src/libmach/getsym.c                |      10 +++++++++-
         M src/libmach/libmach.h               |      30 ------------------------------
         M src/libmach/loadmap.c               |       9 ++++++++-
         D src/libmach/mach.c                  |      11 -----------
         M src/libmach/newobj.c                |      11 +++++++++--
         M src/libmach/objprobe.c              |      18 ++++++++++++------
         M src/libmach/objtype.c               |      18 ++++++++++++------
         M src/libmach/pc2line.c               |       9 ++++++++-
         M src/libmach/readobj.c               |      10 +++++++++-
         M src/libmach/setindex.c              |       9 ++++++++-
         M src/libmach/setsec.c                |       9 ++++++++-
         M src/libmach/setsym.c                |       9 ++++++++-
         M src/libmach/strip.c                 |       9 ++++++++-
         M src/libmach/writeobj.c              |       9 ++++++++-
       
       50 files changed, 197 insertions(+), 151 deletions(-)
       ---
 (DIR) 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 *);
        
        
 (DIR) 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 */
 (DIR) 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;
 (DIR) 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;
 (DIR) 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\
 (DIR) 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,
       -};
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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;
 (DIR) 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)
 (DIR) 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)
 (DIR) 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 *);
 (DIR) 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
       +}
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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)
 (DIR) 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 *);
 (DIR) 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);
        }
        
 (DIR) 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);
        }
 (DIR) 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);
        }
 (DIR) 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;
 (DIR) 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);
        }
 (DIR) 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,
       -};
 (DIR) 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;
                }
 (DIR) 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;
 (DIR) 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;
 (DIR) 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);
        }
 (DIR) 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);
        }
 (DIR) 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);
        }
        
 (DIR) 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);
        }
 (DIR) 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);
        }
 (DIR) 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);
        }
 (DIR) 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);
        }