scc

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

elf64probe.c (1058B)


      1 #include <stdio.h>
      2 
      3 #include <scc/mach.h>
      4 
      5 #include "../libmach.h"
      6 #include "elf64.h"
      7 
      8 struct arch {
      9 	char *name;
     10 	int mach;
     11 	int endian;
     12 	int type;
     13 };
     14 
     15 static struct arch archs[] = {
     16 	{
     17 		.name = "elf64-amd64",
     18 		.mach = EM_X86_64,
     19 		.endian = ELFDATA2LSB,
     20 		.type = OBJ(ELF64, ARCHAMD64, LITTLE_ENDIAN),
     21 	},
     22 	NULL,
     23 };
     24 
     25 int
     26 elf64probe(unsigned char *buf, char **name)
     27 {
     28 	int endian;
     29 	Elf_Ehdr hdr;
     30 	struct arch *ap;
     31 
     32 	unpack(buf[EI_DATA] == ELFDATA2LSB ? LITTLE_ENDIAN : BIG_ENDIAN,
     33 	       buf,
     34 	       "'16sss",
     35 	       hdr.e_ident,
     36 	       &hdr.e_type,
     37 	       &hdr.e_machine,
     38 	       &hdr.e_version);
     39 
     40 	if (!IS_ELF(hdr)
     41 	||  buf[EI_CLASS] != ELFCLASS64
     42 	||  buf[EI_DATA] == ELFDATANONE
     43 	||  buf[EI_VERSION] != EV_CURRENT
     44 	||  (buf[EI_DATA] != ELFDATA2LSB && buf[EI_DATA] != ELFDATA2MSB)) {
     45 		return -1;
     46 	}
     47 
     48 	if (hdr.e_version != EV_CURRENT)
     49 		return -1;
     50 
     51 	endian = hdr.e_ident[EI_DATA];
     52 	for (ap = archs; ap->name; ap++) {
     53 		if (ap->mach == hdr.e_machine &&  ap->endian == endian) {
     54 			if (name)
     55 				*name = ap->name;
     56 			return 0;
     57 		}
     58 	}
     59 
     60 	return -1;
     61 }