scc

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

commit c411ea5ee205b0f8c6e575d166f8a3b762e6b659
parent f2f60fcbe4ac4096f4e0681f498c21167ac30166
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:
Msrc/cmd/scc-objdump/main.c | 93++++++++++++++++++++++++++++++++-----------------------------------------------
1 file changed, 37 insertions(+), 56 deletions(-)

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);