libmach: Add objtype() - 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 226c9b6665ee5cb3d0f50fad4be66a339af4f1d7
 (DIR) parent b0a24eced82c3e643a2722a1d8560338b653a51e
 (HTM) 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:
         M include/scc/scc/mach.h              |       1 +
         M src/libmach/Makefile                |       1 +
         M src/libmach/coff32/coff32.c         |       1 +
         M src/libmach/coff32/coff32.h         |      45 +++++++++++++++++++-------------
         A src/libmach/coff32/coff32archs.c    |      12 ++++++++++++
         M src/libmach/coff32/coff32probe.c    |      14 +-------------
         A src/libmach/coff32/coff32type.c     |      20 ++++++++++++++++++++
         M src/libmach/coff32/rules.mk         |       2 ++
         M src/libmach/elf64/elf64.c           |       1 +
         M src/libmach/elf64/elf64.h           |      11 +++++++++++
         A src/libmach/elf64/elf64archs.c      |      16 ++++++++++++++++
         M src/libmach/elf64/elf64probe.c      |      19 +------------------
         A src/libmach/elf64/elf64type.c       |      20 ++++++++++++++++++++
         M src/libmach/elf64/rules.mk          |       2 ++
         M src/libmach/libmach.h               |      23 ++++++++++++-----------
         A src/libmach/objtype.c               |      21 +++++++++++++++++++++
       
       16 files changed, 149 insertions(+), 60 deletions(-)
       ---
 (DIR) 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 *);
        
 (DIR) 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\
 (DIR) 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,
 (DIR) 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[];
 (DIR) 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,
       +};
 (DIR) 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;
 (DIR) 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;
       +}
 (DIR) 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 \
 (DIR) 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,
 (DIR) 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[];
 (DIR) 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,
       +};
 (DIR) 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;
 (DIR) 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;
       +}
 (DIR) 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\
 (DIR) 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 {
 (DIR) 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;
       +}