objdump: Use a 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 c411ea5ee205b0f8c6e575d166f8a3b762e6b659
 (DIR) parent f2f60fcbe4ac4096f4e0681f498c21167ac30166
 (HTM) Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Fri, 24 Jan 2025 12:05:11 +0100
       
       objdump: Use a polymorphic struct
       
       This removes the need of a switch for every function that depends
       of the type of the binary file.
       
       Diffstat:
         M src/cmd/scc-objdump/main.c          |      93 ++++++++++++-------------------
       
       1 file changed, 37 insertions(+), 56 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/scc-objdump/main.c b/src/cmd/scc-objdump/main.c
       @@ -14,12 +14,34 @@
        
        #include "objdump.h"
        
       +struct binops {
       +        void (*dumpsyms)(Obj *);
       +        void (*dumpsecs)(Obj *);
       +        void (*dumpfhdr)(Obj *, unsigned long long *, Flags *);
       +        int (*hasrelloc)(Obj *, Section *);
       +};
       +
        int tflag, fflag, hflag, pflag, aflag, rflag, sflag;
        char *argv0;
        
        static int status, nsecs;
        static char *filename, *membname, **secs;
        
       +static struct binops *op, ops[NFORMATS] = {
       +        [COFF32] = {
       +                .dumpsyms = coff32syms,
       +                .dumpsecs = coff32scns,
       +                .dumpfhdr = coff32fhdr,
       +                .hasrelloc = coff32hasrelloc,
       +        },
       +        [ELF64] = {
       +                .dumpsyms = elf64syms,
       +                .dumpsecs = elf64scns,
       +                .dumpfhdr = elf64fhdr,
       +                .hasrelloc = elf64hasrelloc,
       +        },
       +};
       +
        void
        error(char *fmt, ...)
        {
       @@ -86,18 +108,7 @@ dumpfhdr(Obj *obj, char *fmt)
        
                f.flags = 0;
        
       -        switch (FORMAT(obj->type)) {
       -        case COFF32:
       -                coff32fhdr(obj, &start, &f);
       -                break;
       -        case ELF64:
       -                elf64fhdr(obj, &start, &f);
       -                break;
       -        default:
       -                error("unknown fhdr binary format");
       -                return;
       -        }
       -
       +        (*op->dumpfhdr)(obj, &start, &f);
                printflags(&f);
                printf("start address 0x%08llx\n", start);
        }
       @@ -131,21 +142,6 @@ selected(char *secname)
                return 0;
        }
        
       -static int
       -hasrelloc(Obj *obj, Section *sec)
       -{
       -        switch (FORMAT(obj->type)) {
       -        case COFF32:
       -                coff32hasrelloc(obj, sec);
       -                break;
       -        case ELF64:
       -                elf64hasrelloc(obj, sec);
       -                break;
       -        default:
       -                return 0;
       -        }
       -}
       -
        static void
        dumpscns(Obj *obj)
        {
       @@ -186,7 +182,7 @@ dumpscns(Obj *obj)
                        debug = sec.type == 'N';
                        setflag(&f, flags & SALLOC, SEC_ALLOC);
                        setflag(&f, flags & SLOAD, SEC_LOAD);
       -                setflag(&f, hasrelloc(obj, &sec), SEC_RELOC);
       +                setflag(&f, (*op->hasrelloc)(obj, &sec), SEC_RELOC);
                        setflag(&f, (flags & SWRITE) == 0 && !debug, SEC_READONLY);
                        setflag(&f, flags & SEXEC, SEC_CODE);
                        setflag(&f, (flags & (SEXEC|SLOAD)) == SLOAD, SEC_DATA);
       @@ -198,17 +194,7 @@ dumpscns(Obj *obj)
        
                if (!pflag)
                        return;
       -
       -        switch (FORMAT(obj->type)) {
       -        case COFF32:
       -                coff32scns(obj);
       -                break;
       -        case ELF64:
       -                elf64scns(obj);
       -                break;
       -        default:
       -                error("unknown fhdr binary format");
       -        }
       +        (*op->dumpsecs)(obj);
        }
        
        static void
       @@ -267,22 +253,6 @@ errno_error:
        
        
        static void
       -dumpsyms(Obj *obj)
       -{
       -        puts("SYMBOL TABLE:");
       -        switch (FORMAT(obj->type)) {
       -        case COFF32:
       -                coff32syms(obj);
       -                break;
       -        case ELF64:
       -                elf64syms(obj);
       -                break;
       -        default:
       -                error("unknown symbol binary format");
       -        }
       -}
       -
       -static void
        dumpobj(FILE *fp, int type, char *fmt)
        {
                Obj *obj;
       @@ -302,6 +272,17 @@ dumpobj(FILE *fp, int type, char *fmt)
                        goto err;
                }
        
       +        switch (FORMAT(obj->type)) {
       +        case COFF32:
       +                op = &ops[COFF32];
       +                break;
       +        case ELF64:
       +                op = &ops[ELF64];
       +                break;
       +        default:
       +                error("unknown symbol binary format");
       +        }
       +
                if (fflag)
                        dumpfhdr(obj, fmt);
                if (hflag)
       @@ -309,7 +290,7 @@ dumpobj(FILE *fp, int type, char *fmt)
                if (sflag)
                        dumpdata(obj, fp);
                if (tflag)
       -                dumpsyms(obj);
       +                (*op->dumpsyms)(obj);
        
        err:
                delobj(obj);