#include "spebase.h"
#include <elf.h>
Go to the source code of this file.
Data Structures | |
union | addr64 |
struct | spe_ld_info |
Defines | |
#define | LS_SIZE 0x40000 |
#define | SPE_LDR_PROG_start (LS_SIZE - 512) |
#define | SPE_LDR_PARAMS_start (LS_SIZE - 128) |
Functions | |
int | _base_spe_verify_spe_elf_image (spe_program_handle_t *handle) |
int | _base_spe_load_spe_elf (spe_program_handle_t *handle, void *ld_buffer, struct spe_ld_info *ld_info) |
int | _base_spe_parse_isolated_elf (spe_program_handle_t *handle, uint64_t *addr, uint32_t *size) |
int | _base_spe_toe_ear (spe_program_handle_t *speh) |
#define LS_SIZE 0x40000 |
Definition at line 23 of file elf_loader.h.
Referenced by _base_spe_context_create(), _base_spe_context_run(), and _base_spe_ls_size_get().
#define SPE_LDR_PARAMS_start (LS_SIZE - 128) |
Definition at line 26 of file elf_loader.h.
#define SPE_LDR_PROG_start (LS_SIZE - 512) |
Definition at line 25 of file elf_loader.h.
int _base_spe_load_spe_elf | ( | spe_program_handle_t * | handle, | |
void * | ld_buffer, | |||
struct spe_ld_info * | ld_info | |||
) |
Definition at line 201 of file elf_loader.c.
References DEBUG_PRINTF, spe_program_handle::elf_image, and spe_ld_info::entry.
Referenced by _base_spe_program_load().
00202 { 00203 Elf32_Ehdr *ehdr; 00204 Elf32_Phdr *phdr; 00205 Elf32_Phdr *ph, *prev_ph; 00206 00207 Elf32_Shdr *shdr; 00208 Elf32_Shdr *sh; 00209 00210 Elf32_Off toe_addr = 0; 00211 long toe_size = 0; 00212 00213 char* str_table = 0; 00214 00215 int num_load_seg = 0; 00216 void *elf_start; 00217 int ret; 00218 00219 DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle, ld_buffer); 00220 00221 elf_start = handle->elf_image; 00222 00223 DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle->elf_image, ld_buffer); 00224 ehdr = (Elf32_Ehdr *)(handle->elf_image); 00225 00226 /* Check for a Valid SPE ELF Image (again) */ 00227 if ((ret=check_spe_elf(ehdr))) 00228 return ret; 00229 00230 /* Start processing headers */ 00231 phdr = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff); 00232 shdr = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); 00233 str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset; 00234 00235 /* traverse the sections to locate the toe segment */ 00236 /* by specification, the toe sections are grouped together in a segment */ 00237 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) 00238 { 00239 DEBUG_PRINTF("section name: %s ( start: 0x%04x, size: 0x%04x)\n", str_table+sh->sh_name, sh->sh_offset, sh->sh_size ); 00240 if (strcmp(".toe", str_table+sh->sh_name) == 0) { 00241 DEBUG_PRINTF("section offset: %d\n", sh->sh_offset); 00242 toe_size += sh->sh_size; 00243 if ((toe_addr == 0) || (toe_addr > sh->sh_addr)) 00244 toe_addr = sh->sh_addr; 00245 } 00246 /* Disabled : Actually not needed, only good for testing 00247 if (strcmp(".bss", str_table+sh->sh_name) == 0) { 00248 DEBUG_PRINTF("zeroing .bss section:\n"); 00249 DEBUG_PRINTF("section offset: 0x%04x\n", sh->sh_offset); 00250 DEBUG_PRINTF("section size: 0x%04x\n", sh->sh_size); 00251 memset(ld_buffer + sh->sh_offset, 0, sh->sh_size); 00252 } */ 00253 00254 #ifdef DEBUG 00255 if (strcmp(".note.spu_name", str_table+sh->sh_name) == 0) 00256 display_debug_output(elf_start, sh); 00257 #endif /*DEBUG*/ 00258 } 00259 00260 /* 00261 * Load all PT_LOAD segments onto the SPE local store buffer. 00262 */ 00263 DEBUG_PRINTF("Segments: 0x%x\n", ehdr->e_phnum); 00264 for (ph = phdr, prev_ph = NULL; ph < &phdr[ehdr->e_phnum]; ++ph) { 00265 switch (ph->p_type) { 00266 case PT_LOAD: 00267 if (!overlay(ph, prev_ph)) { 00268 if (ph->p_filesz < ph->p_memsz) { 00269 DEBUG_PRINTF("padding loaded image with zeros:\n"); 00270 DEBUG_PRINTF("start: 0x%04x\n", ph->p_vaddr + ph->p_filesz); 00271 DEBUG_PRINTF("length: 0x%04x\n", ph->p_memsz - ph->p_filesz); 00272 memset(ld_buffer + ph->p_vaddr + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); 00273 } 00274 copy_to_ld_buffer(handle, ld_buffer, ph, 00275 toe_addr, toe_size); 00276 num_load_seg++; 00277 } 00278 break; 00279 case PT_NOTE: 00280 DEBUG_PRINTF("SPE_LOAD found PT_NOTE\n"); 00281 break; 00282 } 00283 } 00284 if (num_load_seg == 0) 00285 { 00286 DEBUG_PRINTF ("no segments to load"); 00287 errno = EINVAL; 00288 return -errno; 00289 } 00290 00291 /* Remember where the code wants to be started */ 00292 ld_info->entry = ehdr->e_entry; 00293 DEBUG_PRINTF ("entry = 0x%x\n", ehdr->e_entry); 00294 00295 return 0; 00296 00297 }
int _base_spe_parse_isolated_elf | ( | spe_program_handle_t * | handle, | |
uint64_t * | addr, | |||
uint32_t * | size | |||
) |
Definition at line 111 of file elf_loader.c.
References DEBUG_PRINTF, and spe_program_handle::elf_image.
00113 { 00114 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image; 00115 Elf32_Phdr *phdr; 00116 00117 if (!ehdr) { 00118 DEBUG_PRINTF("No ELF image has been loaded\n"); 00119 errno = EINVAL; 00120 return -errno; 00121 } 00122 00123 if (ehdr->e_phentsize != sizeof(*phdr)) { 00124 DEBUG_PRINTF("Invalid program header format (phdr size=%d)\n", 00125 ehdr->e_phentsize); 00126 errno = EINVAL; 00127 return -errno; 00128 } 00129 00130 if (ehdr->e_phnum != 1) { 00131 DEBUG_PRINTF("Invalid program header count (%d), expected 1\n", 00132 ehdr->e_phnum); 00133 errno = EINVAL; 00134 return -errno; 00135 } 00136 00137 phdr = (Elf32_Phdr *)(handle->elf_image + ehdr->e_phoff); 00138 00139 if (phdr->p_type != PT_LOAD || phdr->p_memsz == 0) { 00140 DEBUG_PRINTF("SPE program segment is not loadable (type=%x)\n", 00141 phdr->p_type); 00142 errno = EINVAL; 00143 return -errno; 00144 } 00145 00146 if (addr) 00147 *addr = (uint64_t)(unsigned long) 00148 (handle->elf_image + phdr->p_offset); 00149 00150 if (size) 00151 *size = phdr->p_memsz; 00152 00153 return 0; 00154 }
int _base_spe_toe_ear | ( | spe_program_handle_t * | speh | ) |
Definition at line 354 of file elf_loader.c.
References spe_program_handle::elf_image, and spe_program_handle::toe_shadow.
Referenced by _base_spe_image_open().
00355 { 00356 Elf32_Ehdr *ehdr; 00357 Elf32_Shdr *shdr, *sh; 00358 char *str_table; 00359 char **ch; 00360 int ret; 00361 long toe_size; 00362 00363 ehdr = (Elf32_Ehdr*) (speh->elf_image); 00364 shdr = (Elf32_Shdr*) ((char*) ehdr + ehdr->e_shoff); 00365 str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset; 00366 00367 toe_size = 0; 00368 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) 00369 if (strcmp(".toe", str_table + sh->sh_name) == 0) 00370 toe_size += sh->sh_size; 00371 00372 ret = 0; 00373 if (toe_size > 0) { 00374 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) 00375 if (sh->sh_type == SHT_SYMTAB || sh->sh_type == 00376 SHT_DYNSYM) 00377 ret = toe_check_syms(ehdr, sh); 00378 if (!ret && toe_size != 16) { 00379 /* Paranoia */ 00380 fprintf(stderr, "Unexpected toe size of %ld\n", 00381 toe_size); 00382 errno = EINVAL; 00383 ret = 1; 00384 } 00385 } 00386 if (!ret && toe_size) { 00387 /* 00388 * Allocate toe_shadow, and fill it with elf_image. 00389 */ 00390 speh->toe_shadow = malloc(toe_size); 00391 if (speh->toe_shadow) { 00392 ch = (char**) speh->toe_shadow; 00393 if (sizeof(char*) == 8) { 00394 ch[0] = (char*) speh->elf_image; 00395 ch[1] = 0; 00396 } else { 00397 ch[0] = 0; 00398 ch[1] = (char*) speh->elf_image; 00399 ch[2] = 0; 00400 ch[3] = 0; 00401 } 00402 } else { 00403 errno = ENOMEM; 00404 ret = 1; 00405 } 00406 } 00407 return ret; 00408 }
int _base_spe_verify_spe_elf_image | ( | spe_program_handle_t * | handle | ) |
verifies integrity of an SPE image
Definition at line 99 of file elf_loader.c.
References spe_program_handle::elf_image.
Referenced by _base_spe_emulated_loader_present(), and _base_spe_image_open().