elf_loader.h File Reference

#include "spebase.h"
#include <elf.h>
Include dependency graph for elf_loader.h:
This graph shows which files directly or indirectly include this file:

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 Documentation

#define LS_SIZE   0x40000
#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.


Function Documentation

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().

00100 {
00101         Elf32_Ehdr *ehdr;
00102         void *elf_start;
00103         
00104         elf_start = handle->elf_image;
00105         ehdr = (Elf32_Ehdr *)(handle->elf_image);
00106 
00107         return check_spe_elf(ehdr);
00108 }


Generated by  doxygen 1.6.2