1
/******************************************************************************
2
* Copyright (c) 2004, 2011 IBM Corporation
4
* This program and the accompanying materials
5
* are made available under the terms of the BSD License
6
* which accompanies this distribution, and is available at
7
* http://www.opensource.org/licenses/bsd-license.php
10
* IBM Corporation - initial implementation
11
*****************************************************************************/
54
get_phdr32(void *file_addr)
56
return (struct phdr32 *) (((unsigned char *)file_addr)
57
+ ((struct ehdr32 *)file_addr)->e_phoff);
61
load_segment(void *file_addr, struct phdr32 *phdr, signed long offset,
62
int (*pre_load)(void*, long),
63
void (*post_load)(void*, long))
65
unsigned long src = phdr->p_offset + (unsigned long) file_addr;
66
unsigned long destaddr;
68
destaddr = (unsigned long)phdr->p_paddr;
69
destaddr = destaddr + offset;
71
/* check if we're allowed to copy */
72
if (pre_load != NULL) {
73
if (pre_load((void*)destaddr, phdr->p_memsz) != 0)
77
/* copy into storage */
78
memmove((void *)destaddr, (void *)src, phdr->p_filesz);
81
memset((void *)(destaddr + phdr->p_filesz), 0,
82
phdr->p_memsz - phdr->p_filesz);
84
if (phdr->p_memsz && post_load) {
85
post_load((void*)destaddr, phdr->p_memsz);
90
elf_load_segments32(void *file_addr, signed long offset,
91
int (*pre_load)(void*, long),
92
void (*post_load)(void*, long))
94
struct ehdr32 *ehdr = (struct ehdr32 *) file_addr;
95
/* Calculate program header address */
96
struct phdr32 *phdr = get_phdr32(file_addr);
98
signed int virt2phys = 0; /* Offset between virtual and physical */
100
/* loop e_phnum times */
101
for (i = 0; i <= ehdr->e_phnum; i++) {
103
if (phdr->p_type == 1) {
105
virt2phys = phdr->p_paddr - phdr->p_vaddr;
108
load_segment(file_addr, phdr, offset, pre_load,
111
/* step to next header */
112
phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize);
115
/* Entry point is always a virtual address, so translate it
116
* to physical before returning it */
117
return ehdr->e_entry + virt2phys;
121
* Return the base address for loading (i.e. the address of the first PT_LOAD
123
* @param file_addr pointer to the ELF file in memory
124
* @return the base address
127
elf_get_base_addr32(void *file_addr)
129
struct ehdr32 *ehdr = (struct ehdr32 *) file_addr;
130
struct phdr32 *phdr = get_phdr32(file_addr);
133
/* loop e_phnum times */
134
for (i = 0; i <= ehdr->e_phnum; i++) {
136
if (phdr->p_type == 1) {
137
return phdr->p_paddr;
139
/* step to next header */
140
phdr = (struct phdr32 *)(((uint8_t *)phdr) + ehdr->e_phentsize);