libspe2  0.9a
Data Structures | Macros | Functions
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
 

Macros

#define LS_SIZE   0x40000 /* 256K (in bytes) */
 
#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)
 

Macro Definition Documentation

#define LS_SIZE   0x40000 /* 256K (in bytes) */
#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().

202 {
203  Elf32_Ehdr *ehdr;
204  Elf32_Phdr *phdr;
205  Elf32_Phdr *ph, *prev_ph;
206 
207  Elf32_Shdr *shdr;
208  Elf32_Shdr *sh;
209 
210  Elf32_Off toe_addr = 0;
211  long toe_size = 0;
212 
213  char* str_table = 0;
214 
215  int num_load_seg = 0;
216  void *elf_start;
217  int ret;
218 
219  DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle, ld_buffer);
220 
221  elf_start = handle->elf_image;
222 
223  DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle->elf_image, ld_buffer);
224  ehdr = (Elf32_Ehdr *)(handle->elf_image);
225 
226  /* Check for a Valid SPE ELF Image (again) */
227  if ((ret=check_spe_elf(ehdr)))
228  return ret;
229 
230  /* Start processing headers */
231  phdr = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff);
232  shdr = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff);
233  str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
234 
235  /* traverse the sections to locate the toe segment */
236  /* by specification, the toe sections are grouped together in a segment */
237  for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
238  {
239  DEBUG_PRINTF("section name: %s ( start: 0x%04x, size: 0x%04x)\n", str_table+sh->sh_name, sh->sh_offset, sh->sh_size );
240  if (strcmp(".toe", str_table+sh->sh_name) == 0) {
241  DEBUG_PRINTF("section offset: %d\n", sh->sh_offset);
242  toe_size += sh->sh_size;
243  if ((toe_addr == 0) || (toe_addr > sh->sh_addr))
244  toe_addr = sh->sh_addr;
245  }
246  /* Disabled : Actually not needed, only good for testing
247  if (strcmp(".bss", str_table+sh->sh_name) == 0) {
248  DEBUG_PRINTF("zeroing .bss section:\n");
249  DEBUG_PRINTF("section offset: 0x%04x\n", sh->sh_offset);
250  DEBUG_PRINTF("section size: 0x%04x\n", sh->sh_size);
251  memset(ld_buffer + sh->sh_offset, 0, sh->sh_size);
252  } */
253 
254 #ifdef DEBUG
255  if (strcmp(".note.spu_name", str_table+sh->sh_name) == 0)
256  display_debug_output(elf_start, sh);
257 #endif /*DEBUG*/
258  }
259 
260  /*
261  * Load all PT_LOAD segments onto the SPE local store buffer.
262  */
263  DEBUG_PRINTF("Segments: 0x%x\n", ehdr->e_phnum);
264  for (ph = phdr, prev_ph = NULL; ph < &phdr[ehdr->e_phnum]; ++ph) {
265  switch (ph->p_type) {
266  case PT_LOAD:
267  if (!overlay(ph, prev_ph)) {
268  if (ph->p_filesz < ph->p_memsz) {
269  DEBUG_PRINTF("padding loaded image with zeros:\n");
270  DEBUG_PRINTF("start: 0x%04x\n", ph->p_vaddr + ph->p_filesz);
271  DEBUG_PRINTF("length: 0x%04x\n", ph->p_memsz - ph->p_filesz);
272  memset(ld_buffer + ph->p_vaddr + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz);
273  }
274  copy_to_ld_buffer(handle, ld_buffer, ph,
275  toe_addr, toe_size);
276  num_load_seg++;
277  }
278  break;
279  case PT_NOTE:
280  DEBUG_PRINTF("SPE_LOAD found PT_NOTE\n");
281  break;
282  }
283  }
284  if (num_load_seg == 0)
285  {
286  DEBUG_PRINTF ("no segments to load");
287  errno = EINVAL;
288  return -errno;
289  }
290 
291  /* Remember where the code wants to be started */
292  ld_info->entry = ehdr->e_entry;
293  DEBUG_PRINTF ("entry = 0x%x\n", ehdr->e_entry);
294 
295  return 0;
296 
297 }
#define DEBUG_PRINTF(fmt, args...)
Definition: elf_loader.c:45
unsigned int entry
Definition: elf_loader.h:36
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.

113 {
114  Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image;
115  Elf32_Phdr *phdr;
116 
117  if (!ehdr) {
118  DEBUG_PRINTF("No ELF image has been loaded\n");
119  errno = EINVAL;
120  return -errno;
121  }
122 
123  if (ehdr->e_phentsize != sizeof(*phdr)) {
124  DEBUG_PRINTF("Invalid program header format (phdr size=%d)\n",
125  ehdr->e_phentsize);
126  errno = EINVAL;
127  return -errno;
128  }
129 
130  if (ehdr->e_phnum != 1) {
131  DEBUG_PRINTF("Invalid program header count (%d), expected 1\n",
132  ehdr->e_phnum);
133  errno = EINVAL;
134  return -errno;
135  }
136 
137  phdr = (Elf32_Phdr *)(handle->elf_image + ehdr->e_phoff);
138 
139  if (phdr->p_type != PT_LOAD || phdr->p_memsz == 0) {
140  DEBUG_PRINTF("SPE program segment is not loadable (type=%x)\n",
141  phdr->p_type);
142  errno = EINVAL;
143  return -errno;
144  }
145 
146  if (addr)
147  *addr = (uint64_t)(unsigned long)
148  (handle->elf_image + phdr->p_offset);
149 
150  if (size)
151  *size = phdr->p_memsz;
152 
153  return 0;
154 }
#define DEBUG_PRINTF(fmt, args...)
Definition: elf_loader.c:45
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().

355 {
356  Elf32_Ehdr *ehdr;
357  Elf32_Shdr *shdr, *sh;
358  char *str_table;
359  char **ch;
360  int ret;
361  long toe_size;
362 
363  ehdr = (Elf32_Ehdr*) (speh->elf_image);
364  shdr = (Elf32_Shdr*) ((char*) ehdr + ehdr->e_shoff);
365  str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
366 
367  toe_size = 0;
368  for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
369  if (strcmp(".toe", str_table + sh->sh_name) == 0)
370  toe_size += sh->sh_size;
371 
372  ret = 0;
373  if (toe_size > 0) {
374  for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
375  if (sh->sh_type == SHT_SYMTAB || sh->sh_type ==
376  SHT_DYNSYM)
377  ret = toe_check_syms(ehdr, sh);
378  if (!ret && toe_size != 16) {
379  /* Paranoia */
380  fprintf(stderr, "Unexpected toe size of %ld\n",
381  toe_size);
382  errno = EINVAL;
383  ret = 1;
384  }
385  }
386  if (!ret && toe_size) {
387  /*
388  * Allocate toe_shadow, and fill it with elf_image.
389  */
390  speh->toe_shadow = malloc(toe_size);
391  if (speh->toe_shadow) {
392  ch = (char**) speh->toe_shadow;
393  if (sizeof(char*) == 8) {
394  ch[0] = (char*) speh->elf_image;
395  ch[1] = 0;
396  } else {
397  ch[0] = 0;
398  ch[1] = (char*) speh->elf_image;
399  ch[2] = 0;
400  ch[3] = 0;
401  }
402  } else {
403  errno = ENOMEM;
404  ret = 1;
405  }
406  }
407  return ret;
408 }
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().

100 {
101  Elf32_Ehdr *ehdr;
102  void *elf_start;
103 
104  elf_start = handle->elf_image;
105  ehdr = (Elf32_Ehdr *)(handle->elf_image);
106 
107  return check_spe_elf(ehdr);
108 }