shithub: scc

Download patch

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)