Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-elf-read.c view on Meta::CPAN
/* Get the machine and ABI values that we expect in the header */
_jit_gen_get_elf_info(&elf_info);
/* Open the file and read the ELF magic number information */
if((fd = sys_open(filename, O_RDONLY | O_BINARY, 0)) < 0)
{
return JIT_READELF_CANNOT_OPEN;
}
if(sys_read(fd, ehdr.e_ident, EI_NIDENT) != EI_NIDENT)
{
sys_close(fd);
return JIT_READELF_NOT_ELF;
}
/* Determine if the magic number matches what we expect to see */
if(ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3)
{
sys_close(fd);
return JIT_READELF_NOT_ELF;
}
#ifdef JIT_NATIVE_INT32
if(ehdr.e_ident[EI_CLASS] != ELFCLASS32)
{
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
#else
if(ehdr.e_ident[EI_CLASS] != ELFCLASS64)
{
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
#endif
un.value = 0x0102;
if(un.bytes[0] == 0x01)
{
/* Looking for a big-endian binary */
if(ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
{
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
}
else
{
/* Looking for a little-endian binary */
if(ehdr.e_ident[EI_DATA] != ELFDATA2LSB)
{
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
}
if(ehdr.e_ident[EI_VERSION] != EV_CURRENT)
{
sys_close(fd);
return JIT_READELF_BAD_FORMAT;
}
/* Read the rest of the ELF header and validate it */
if(sys_read(fd, &(ehdr.e_type), sizeof(Elf_Ehdr) - EI_NIDENT)
!= (sizeof(Elf_Ehdr) - EI_NIDENT))
{
sys_close(fd);
return JIT_READELF_BAD_FORMAT;
}
if(ehdr.e_type != ET_DYN)
{
/* We can only load files that are marked as dynamic shared objects */
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
if((flags & JIT_READELF_FLAG_FORCE) == 0)
{
if(ehdr.e_machine != elf_info.machine ||
ehdr.e_ident[EI_OSABI] != elf_info.abi ||
ehdr.e_ident[EI_ABIVERSION] != elf_info.abi_version)
{
/* The ELF binary does not pertain to this machine or ABI type */
sys_close(fd);
return JIT_READELF_WRONG_ARCH;
}
}
if(ehdr.e_version != EV_CURRENT)
{
sys_close(fd);
return JIT_READELF_BAD_FORMAT;
}
if(ehdr.e_ehsize < sizeof(ehdr))
{
sys_close(fd);
return JIT_READELF_BAD_FORMAT;
}
/* Allocate space for the ELF reader object */
if((readelf = jit_cnew(struct jit_readelf)) == 0)
{
sys_close(fd);
return JIT_READELF_MEMORY;
}
readelf->ehdr = ehdr;
phdr_size = ((unsigned int)(ehdr.e_phnum)) *
((unsigned int)(ehdr.e_phentsize));
shdr_size = ((unsigned int)(ehdr.e_shnum)) *
((unsigned int)(ehdr.e_shentsize));
if(phdr_size > 0)
{
readelf->phdrs = (unsigned char *)jit_malloc(phdr_size);
if(!(readelf->phdrs))
{
jit_free(readelf);
sys_close(fd);
return JIT_READELF_MEMORY;
}
}
if(shdr_size > 0)
{
readelf->shdrs = (unsigned char *)jit_malloc(shdr_size);
if(!(readelf->shdrs))
{
( run in 1.330 second using v1.01-cache-2.11-cpan-119454b85a5 )