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 )