scc

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

commit 226c9b6665ee5cb3d0f50fad4be66a339af4f1d7
parent b0a24eced82c3e643a2722a1d8560338b653a51e
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 15 Feb 2024 16:59:28 +0100

libmach: Add objtype()

This function translate a textual description of a binary format
into the integer representation of that format that can be used
with newobj() to create a new object.

Diffstat:
Minclude/scc/scc/mach.h | 1+
Msrc/libmach/Makefile | 1+
Msrc/libmach/coff32/coff32.c | 1+
Msrc/libmach/coff32/coff32.h | 45+++++++++++++++++++++++++++------------------
Asrc/libmach/coff32/coff32archs.c | 12++++++++++++
Msrc/libmach/coff32/coff32probe.c | 14+-------------
Asrc/libmach/coff32/coff32type.c | 20++++++++++++++++++++
Msrc/libmach/coff32/rules.mk | 2++
Msrc/libmach/elf64/elf64.c | 1+
Msrc/libmach/elf64/elf64.h | 11+++++++++++
Asrc/libmach/elf64/elf64archs.c | 16++++++++++++++++
Msrc/libmach/elf64/elf64probe.c | 19+------------------
Asrc/libmach/elf64/elf64type.c | 20++++++++++++++++++++
Msrc/libmach/elf64/rules.mk | 2++
Msrc/libmach/libmach.h | 23++++++++++++-----------
Asrc/libmach/objtype.c | 21+++++++++++++++++++++
16 files changed, 149 insertions(+), 60 deletions(-)

diff --git a/include/scc/scc/mach.h b/include/scc/scc/mach.h @@ -111,6 +111,7 @@ extern int getindex(int, long *, char ***, long **, FILE *); extern Map *newmap(Map *, int); extern Map *remap(Map *, int); +extern int objtype(char *); extern Obj *newobj(int); extern void delobj(Obj *); diff --git a/src/libmach/Makefile b/src/libmach/Makefile @@ -24,6 +24,7 @@ OBJS =\ newobj.o\ objpos.o\ objprobe.o\ + objtype.o\ pack.o\ pc2line.o\ readobj.o\ diff --git a/src/libmach/coff32/coff32.c b/src/libmach/coff32/coff32.c @@ -6,6 +6,7 @@ #include "coff32.h" struct objops coff32 = { + .type = coff32type, .probe = coff32probe, .new = coff32new, .read = coff32read, diff --git a/src/libmach/coff32/coff32.h b/src/libmach/coff32/coff32.h @@ -18,21 +18,30 @@ struct coff32 { unsigned long strsiz; }; -extern int coff32new(Obj *obj); -extern int coff32read(Obj *obj, FILE *fp); -extern int coff32setidx(long nsyms, char **names, long *offs, FILE *fp); -extern int coff32getidx(long *nsyms, char ***namep, long **offsp, FILE *fp); -extern int coff32pc2line(Obj *, unsigned long long , char *, int *); -extern int coff32strip(Obj *obj); -extern void coff32del(Obj *obj); -extern int coff32write(Obj *obj, Map * map, FILE *fp); -extern int coff32probe(unsigned char *buf, char **name); - -extern int coff32xsetidx(int order, - long nsymbols, char *names[], long offs[], FILE *fp); -extern int coff32xgetidx(int order, - long *nsyms, char ***namep, long **offsp, FILE *fp); - -extern Symbol *coff32getsym(Obj *obj, int *idx, Symbol *sym); -extern Section *coff32getsec(Obj *obj, int *idx, Section *sec); -extern Map *coff32loadmap(Obj *obj, FILE *fp); +struct arch { + char *name; + unsigned char magic[2]; + int type; +}; + +extern int coff32new(Obj *); +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 Section *coff32getsec(Obj *, int *, Section *); +extern Map *coff32loadmap(Obj *, FILE *); + + +/* globals */ +extern struct arch coff32archs[]; diff --git a/src/libmach/coff32/coff32archs.c b/src/libmach/coff32/coff32archs.c @@ -0,0 +1,12 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "coff32.h" + +struct arch coff32archs[] = { + "coff32-i386", "\x4c\x01", OBJ(COFF32, ARCH386, LITTLE_ENDIAN), + "coff32-z80", "\x5a\x80", OBJ(COFF32, ARCHZ80, LITTLE_ENDIAN), + NULL, +}; diff --git a/src/libmach/coff32/coff32probe.c b/src/libmach/coff32/coff32probe.c @@ -5,24 +5,12 @@ #include "../libmach.h" #include "coff32.h" -struct arch { - char *name; - unsigned char magic[2]; - int type; -}; - -static struct arch archs[] = { - "coff32-i386", "\x4c\x01", OBJ(COFF32, ARCH386, LITTLE_ENDIAN), - "coff32-z80", "\x5a\x80", OBJ(COFF32, ARCHZ80, LITTLE_ENDIAN), - NULL, -}; - int coff32probe(unsigned char *buf, char **name) { struct arch *ap; - for (ap = archs; ap->name; ap++) { + for (ap = coff32archs; ap->name; ap++) { if (ap->magic[0] == buf[0] && ap->magic[1] == buf[1]) { if (name) *name = ap->name; diff --git a/src/libmach/coff32/coff32type.c b/src/libmach/coff32/coff32type.c @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <string.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "coff32.h" + +int +coff32type(char *name) +{ + struct arch *ap; + + for (ap = coff32archs; ap ->name; ap++) { + if (strcmp(ap->name, name) == 0) + return ap->type; + } + + return -1; +} diff --git a/src/libmach/coff32/rules.mk b/src/libmach/coff32/rules.mk @@ -1,7 +1,9 @@ COFF32_OBJS =\ coff32/coff32.o \ + coff32/coff32archs.o\ coff32/coff32del.o \ coff32/coff32new.o \ + coff32/coff32type.o \ coff32/coff32probe.o \ coff32/coff32read.o \ coff32/coff32strip.o \ diff --git a/src/libmach/elf64/elf64.c b/src/libmach/elf64/elf64.c @@ -6,6 +6,7 @@ #include "elf64.h" struct objops elf64 = { + .type = elf64type, .probe = elf64probe, .new = elf64new, .read = elf64read, diff --git a/src/libmach/elf64/elf64.h b/src/libmach/elf64/elf64.h @@ -35,6 +35,13 @@ struct elf64 { size_t nsym; }; +struct arch { + char *name; + int mach; + int endian; + int type; +}; + extern int elf64new(Obj *); extern int elf64read(Obj *, FILE *); extern int elf64setidx(long, char **, long *, FILE *); @@ -44,6 +51,7 @@ 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 *); @@ -53,3 +61,6 @@ extern Section *elf64getsec(Obj *, int *, Section *); extern Map *elf64loadmap(Obj *, FILE *); extern char *elf64str(Obj *, int n, long); + +/* globals */ +extern struct arch elf64archs[]; diff --git a/src/libmach/elf64/elf64archs.c b/src/libmach/elf64/elf64archs.c @@ -0,0 +1,16 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "elf64.h" + +struct arch elf64archs[] = { + { + .name = "elf64-amd64", + .mach = EM_X86_64, + .endian = ELFDATA2LSB, + .type = OBJ(ELF64, ARCHAMD64, LITTLE_ENDIAN), + }, + NULL, +}; diff --git a/src/libmach/elf64/elf64probe.c b/src/libmach/elf64/elf64probe.c @@ -5,23 +5,6 @@ #include "../libmach.h" #include "elf64.h" -struct arch { - char *name; - int mach; - int endian; - int type; -}; - -static struct arch archs[] = { - { - .name = "elf64-amd64", - .mach = EM_X86_64, - .endian = ELFDATA2LSB, - .type = OBJ(ELF64, ARCHAMD64, LITTLE_ENDIAN), - }, - NULL, -}; - int elf64probe(unsigned char *buf, char **name) { @@ -49,7 +32,7 @@ elf64probe(unsigned char *buf, char **name) return -1; endian = hdr.e_ident[EI_DATA]; - for (ap = archs; ap->name; ap++) { + for (ap = elf64archs; ap->name; ap++) { if (ap->mach == hdr.e_machine && ap->endian == endian) { if (name) *name = ap->name; diff --git a/src/libmach/elf64/elf64type.c b/src/libmach/elf64/elf64type.c @@ -0,0 +1,20 @@ +#include <stdio.h> +#include <string.h> + +#include <scc/mach.h> + +#include "../libmach.h" +#include "elf64.h" + +int +elf64type(char *name) +{ + struct arch *ap; + + for (ap = elf64archs; ap ->name; ap++) { + if (strcmp(ap->name, name) == 0) + return ap->type; + } + + return -1; +} diff --git a/src/libmach/elf64/rules.mk b/src/libmach/elf64/rules.mk @@ -1,8 +1,10 @@ ELF64_OBJS =\ elf64/elf64.o \ + elf64/elf64archs.o\ elf64/elf64new.o\ elf64/elf64probe.o\ elf64/elf64read.o\ + elf64/elf64type.o\ elf64/elf64getsec.o\ elf64/elf64del.o\ elf64/elf64getsym.o\ diff --git a/src/libmach/libmach.h b/src/libmach/libmach.h @@ -33,24 +33,25 @@ enum order { }; struct objops { - int (*probe)(unsigned char *buf, char **name); + int (*type)(char *); + int (*probe)(unsigned char *, char **); - int (*new)(Obj *obj); - void (*del)(Obj *obj); + int (*new)(Obj *); + void (*del)(Obj *); - int (*read)(Obj *obj, FILE *fp); - int (*write)(Obj *obj, Map *map, FILE *fp); + int (*read)(Obj *, FILE *); + int (*write)(Obj *, Map *, FILE *); - int (*strip)(Obj *obj); + int (*strip)(Obj *); int (*pc2line)(Obj *, unsigned long long , char *, int *); - Map *(*loadmap)(Obj *obj, FILE *fp); + Map *(*loadmap)(Obj *, FILE *); - Symbol *(*getsym)(Obj *obj, int *index, Symbol *sym); - Section *(*getsec)(Obj *obj, int *index, Section *sec); + Symbol *(*getsym)(Obj *, int *, Symbol *); + Section *(*getsec)(Obj *, int *, Section *); - int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp); - int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp); + int (*setidx)(long, char *[], long[], FILE *); + int (*getidx)(long *, char ***, long **, FILE *); }; struct map { diff --git a/src/libmach/objtype.c b/src/libmach/objtype.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +#include <scc/mach.h> + +#include "libmach.h" + +int +objtype(char *name) +{ + int t; + Objops **opsp, *ops; + + for (opsp = objops; ops = *opsp; ++opsp) { + t = (*ops->type)(name); + if (t < 0) + continue; + return t; + } + + return -1; +}