unsigned long elf_load_segments64(void *file_addr, signed long offset, int (*pre_load)(void*, long), void (*post_load)(void*, long)) { struct ehdr64 *ehdr = (struct ehdr64 *) file_addr; /* Calculate program header address */ struct phdr64 *phdr = get_phdr64(file_addr); int i; /* loop e_phnum times */ for (i = 0; i <= ehdr->e_phnum; i++) { /* PT_LOAD ? */ if (phdr->p_type == PT_LOAD) { if (phdr->p_paddr != phdr->p_vaddr) { printf("ELF64: VirtAddr(%lx) != PhysAddr(%lx) not supported, aborting\n", (long)phdr->p_vaddr, (long)phdr->p_paddr); return 0; } /* copy segment */ load_segment64(file_addr, phdr, offset, pre_load, post_load); } /* step to next header */ phdr = (struct phdr64 *)(((uint8_t *)phdr) + ehdr->e_phentsize); } /* Entry point is always a virtual address, so translate it * to physical before returning it */ return ehdr->e_entry; }
static unsigned long load_segments64(unsigned long *file_addr) { struct ehdr64 *ehdr64 = (struct ehdr64 *) file_addr; /* Calculate program header address */ struct phdr64 *phdr64 = (struct phdr64 *) (((unsigned char *) file_addr) + ehdr64->e_phoff); int i; /* loop e_phnum times */ for (i = 0; i <= ehdr64->e_phnum; i++) { /* PT_LOAD ? */ if (phdr64->p_type == 1) { /* copy segment */ load_segment64(file_addr, phdr64); } /* step to next header */ phdr64 = (struct phdr64 *) (((unsigned char *) phdr64) + ehdr64->e_phentsize); } return ehdr64->e_entry; }