scc

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

commit 9cb39b5284c0779a969928f0e1cb00d976686bf6
parent 1e25f0265035bc1ca9a778dcd2f1ada69547a088
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue, 26 Oct 2021 21:30:56 +0200

libmach: Add elf64probe()

This function probes if a file if a known elf format.

Diffstat:
Msrc/libmach/deps.mk | 3+++
Msrc/libmach/elf64/elf64.c | 2+-
Asrc/libmach/elf64/elf64probe.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/libmach/elf64/rules.mk | 1+
Msrc/libmach/libmach.h | 2+-
5 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/src/libmach/deps.mk b/src/libmach/deps.mk @@ -56,6 +56,9 @@ elf64/elf64.o: elf64/elf64.h 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 diff --git 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, diff --git a/src/libmach/elf64/elf64probe.c b/src/libmach/elf64/elf64probe.c @@ -0,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; +} diff --git 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\ diff --git 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)