Alien-LibJIT
view release on metacpan or search on metacpan
libjit/jit/jit-elf-read.c view on Meta::CPAN
Elf_Off memory_size;
Elf_Off start, end;
Elf_Phdr *phdr;
unsigned int index;
void *base_address;
unsigned char *segment_address;
/* Get the maximum file and memory sizes for the program.
The bytes between "file_size" and "memory_size" are bss */
file_size = 0;
memory_size = 0;
for(index = 0; index < readelf->ehdr.e_phnum; ++index)
{
phdr = get_phdr(readelf, index);
if(!phdr)
{
continue;
}
start = phdr->p_offset;
end = start + phdr->p_filesz;
if(end > file_size)
{
file_size = end;
}
start = phdr->p_vaddr;
end = start + phdr->p_memsz;
if(end > memory_size)
{
memory_size = end;
}
}
if(memory_size < file_size)
{
memory_size = file_size;
}
/* Try to map the program segments into memory using mmap */
base_address = 0;
#ifdef JIT_USE_MMAP_TO_LOAD
{
Elf_Off page_size;
Elf_Off rounded_file_size;
Elf_Off temp_start;
Elf_Off temp_end;
int zero_fd, prot;
/* Round the total memory and file sizes up to the CPU page size */
page_size = (Elf_Off)(jit_vmem_page_size());
end = memory_size;
if((end % page_size) != 0)
{
end += page_size - (end % page_size);
}
rounded_file_size = file_size;
if((rounded_file_size % page_size) != 0)
{
rounded_file_size += page_size - (rounded_file_size % page_size);
}
/* Allocate memory for the program from /dev/zero. Once we have
the memory, we will overlay the program segments on top */
zero_fd = sys_open("/dev/zero", O_RDWR, 0);
if(zero_fd < -1)
{
goto failed_mmap;
}
base_address = mmap(0, (size_t)end, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, zero_fd, 0);
close(zero_fd);
if(base_address == (void *)(jit_nint)(-1))
{
base_address = 0;
goto failed_mmap;
}
/* Lay down the program sections at their mapped locations */
for(index = 0; index < readelf->ehdr.e_phnum; ++index)
{
phdr = get_phdr(readelf, index);
if(phdr)
{
temp_start = phdr->p_offset;
temp_end = temp_start + phdr->p_filesz;
temp_start -= (temp_start % page_size);
if((temp_end % page_size) != 0)
{
temp_end += page_size - (temp_end % page_size);
}
start = phdr->p_vaddr;
start -= (start % page_size);
if(temp_start < temp_end)
{
segment_address =
((unsigned char *)base_address) + (jit_nuint)start;
prot = 0;
if((phdr->p_flags & PF_X) != 0)
{
prot |= PROT_EXEC;
}
if((phdr->p_flags & PF_W) != 0)
{
prot |= PROT_WRITE;
}
if((phdr->p_flags & PF_R) != 0)
{
prot |= PROT_READ;
}
if(mmap(segment_address, (size_t)(temp_end - temp_start),
prot, MAP_COPY | MAP_FILE | MAP_FIXED, fd,
(off_t)temp_start) == (void *)(jit_nint)(-1))
{
munmap(base_address, (size_t)end);
base_address = 0;
goto failed_mmap;
}
}
}
}
/* We need to free the memory with munmap when the program is closed */
readelf->free_with_munmap = 1;
( run in 0.735 second using v1.01-cache-2.11-cpan-d59ab9ce9b0 )