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:
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;
+}