ref: 3cc8de7beda4e1a99a33728014953fc1158a336a
parent: 844cf5ff2aa2a862b58d2e503e02534e133ad395
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Oct 26 17:30:56 EDT 2021
libmach: Add elf64probe() This function probes if a file if a known elf format.
--- a/src/libmach/deps.mk
+++ b/src/libmach/deps.mk
@@ -56,6 +56,9 @@
elf64/elf64new.o: $(INCDIR)/scc/scc/mach.h
elf64/elf64new.o: elf64/../libmach.h
elf64/elf64new.o: elf64/elf64.h
+elf64/elf64probe.o: $(INCDIR)/scc/scc/mach.h
+elf64/elf64probe.o: elf64/../libmach.h
+elf64/elf64probe.o: elf64/elf64.h
findsec.o: $(INCDIR)/scc/scc/mach.h
findsec.o: libmach.h
getindex.o: $(INCDIR)/scc/scc/mach.h
--- a/src/libmach/elf64/elf64.c
+++ b/src/libmach/elf64/elf64.c
@@ -6,7 +6,7 @@
#include "elf64.h"
struct objops coff32 = {
- .probe = NULL,
+ .probe = elf64probe,
.new = elf64new,
.read = NULL,
.getidx = NULL,
--- /dev/null
+++ b/src/libmach/elf64/elf64probe.c
@@ -1,0 +1,61 @@
+#include <stdio.h>
+
+#include <scc/mach.h>
+
+#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)
+{
+ int endian;
+ Elf_Ehdr hdr;
+ struct arch *ap;
+
+ unpack(buf[EI_DATA] == ELFDATA2LSB ? LITTLE_ENDIAN : BIG_ENDIAN,
+ buf,
+ "'16sss",
+ hdr.e_ident,
+ &hdr.e_type,
+ &hdr.e_machine,
+ &hdr.e_version);
+
+ if (!IS_ELF(hdr)
+ || buf[EI_CLASS] != ELFCLASS64
+ || buf[EI_DATA] == ELFDATANONE
+ || buf[EI_VERSION] != EV_CURRENT
+ || (buf[EI_DATA] != ELFDATA2LSB && buf[EI_DATA] != ELFDATA2MSB)) {
+ return -1;
+ }
+
+ if (hdr.e_version != EV_CURRENT)
+ return -1;
+
+ endian = hdr.e_ident[EI_DATA];
+ for (ap = archs; ap->name; ap++) {
+ if (ap->mach == hdr.e_machine && ap->endian == endian) {
+ if (name)
+ *name = ap->name;
+ return 0;
+ }
+ }
+
+ return -1;
+}
--- a/src/libmach/elf64/rules.mk
+++ b/src/libmach/elf64/rules.mk
@@ -1,3 +1,4 @@
ELF64_OBJS =\
elf64/elf64.o \
elf64/elf64new.o\
+ elf64/elf64probe.o\
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -1,4 +1,4 @@
-#define NBYTES 20
+#define NBYTES 32
#define OBJ(format,arch,order) ((order) << 10 | (arch) << 5 | (format))
#define FORMAT(t) ((t) & 0x1f)
#define ARCH(t) (((t) >> 5) & 0x1f)