libspe2 0.9a
|
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "elf_loader.h"
#include "spebase.h"
Go to the source code of this file.
Defines | |
#define | __PRINTF(fmt, args...) { fprintf(stderr,fmt , ## args); } |
#define | DEBUG_PRINTF(fmt, args...) |
#define | TAG |
Functions | |
int | _base_spe_verify_spe_elf_image (spe_program_handle_t *handle) |
int | _base_spe_parse_isolated_elf (spe_program_handle_t *handle, uint64_t *addr, uint32_t *size) |
int | _base_spe_load_spe_elf (spe_program_handle_t *handle, void *ld_buffer, struct spe_ld_info *ld_info) |
int | _base_spe_toe_ear (spe_program_handle_t *speh) |
#define __PRINTF | ( | fmt, | |
args... | |||
) | { fprintf(stderr,fmt , ## args); } |
Definition at line 40 of file elf_loader.c.
#define DEBUG_PRINTF | ( | fmt, | |
args... | |||
) |
Definition at line 45 of file elf_loader.c.
Referenced by _base_spe_context_create(), _base_spe_context_run(), _base_spe_count_physical_cpus(), _base_spe_count_physical_spes(), _base_spe_gang_context_create(), _base_spe_handle_library_callback(), _base_spe_load_spe_elf(), _base_spe_out_mbox_read(), _base_spe_parse_isolated_elf(), _base_spe_program_load(), and _base_spe_program_load_complete().
#define TAG |
Definition at line 46 of file elf_loader.c.
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().
{ Elf32_Ehdr *ehdr; Elf32_Phdr *phdr; Elf32_Phdr *ph, *prev_ph; Elf32_Shdr *shdr; Elf32_Shdr *sh; Elf32_Off toe_addr = 0; long toe_size = 0; char* str_table = 0; int num_load_seg = 0; void *elf_start; int ret; DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle, ld_buffer); elf_start = handle->elf_image; DEBUG_PRINTF ("load_spe_elf(%p, %p)\n", handle->elf_image, ld_buffer); ehdr = (Elf32_Ehdr *)(handle->elf_image); /* Check for a Valid SPE ELF Image (again) */ if ((ret=check_spe_elf(ehdr))) return ret; /* Start processing headers */ phdr = (Elf32_Phdr *) ((char *) ehdr + ehdr->e_phoff); shdr = (Elf32_Shdr *) ((char *) ehdr + ehdr->e_shoff); str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset; /* traverse the sections to locate the toe segment */ /* by specification, the toe sections are grouped together in a segment */ for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) { DEBUG_PRINTF("section name: %s ( start: 0x%04x, size: 0x%04x)\n", str_table+sh->sh_name, sh->sh_offset, sh->sh_size ); if (strcmp(".toe", str_table+sh->sh_name) == 0) { DEBUG_PRINTF("section offset: %d\n", sh->sh_offset); toe_size += sh->sh_size; if ((toe_addr == 0) || (toe_addr > sh->sh_addr)) toe_addr = sh->sh_addr; } /* Disabled : Actually not needed, only good for testing if (strcmp(".bss", str_table+sh->sh_name) == 0) { DEBUG_PRINTF("zeroing .bss section:\n"); DEBUG_PRINTF("section offset: 0x%04x\n", sh->sh_offset); DEBUG_PRINTF("section size: 0x%04x\n", sh->sh_size); memset(ld_buffer + sh->sh_offset, 0, sh->sh_size); } */ #ifdef DEBUG if (strcmp(".note.spu_name", str_table+sh->sh_name) == 0) display_debug_output(elf_start, sh); #endif /*DEBUG*/ } /* * Load all PT_LOAD segments onto the SPE local store buffer. */ DEBUG_PRINTF("Segments: 0x%x\n", ehdr->e_phnum); for (ph = phdr, prev_ph = NULL; ph < &phdr[ehdr->e_phnum]; ++ph) { switch (ph->p_type) { case PT_LOAD: if (!overlay(ph, prev_ph)) { if (ph->p_filesz < ph->p_memsz) { DEBUG_PRINTF("padding loaded image with zeros:\n"); DEBUG_PRINTF("start: 0x%04x\n", ph->p_vaddr + ph->p_filesz); DEBUG_PRINTF("length: 0x%04x\n", ph->p_memsz - ph->p_filesz); memset(ld_buffer + ph->p_vaddr + ph->p_filesz, 0, ph->p_memsz - ph->p_filesz); } copy_to_ld_buffer(handle, ld_buffer, ph, toe_addr, toe_size); num_load_seg++; } break; case PT_NOTE: DEBUG_PRINTF("SPE_LOAD found PT_NOTE\n"); break; } } if (num_load_seg == 0) { DEBUG_PRINTF ("no segments to load"); errno = EINVAL; return -errno; } /* Remember where the code wants to be started */ ld_info->entry = ehdr->e_entry; DEBUG_PRINTF ("entry = 0x%x\n", ehdr->e_entry); return 0; }
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.
{ Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->elf_image; Elf32_Phdr *phdr; if (!ehdr) { DEBUG_PRINTF("No ELF image has been loaded\n"); errno = EINVAL; return -errno; } if (ehdr->e_phentsize != sizeof(*phdr)) { DEBUG_PRINTF("Invalid program header format (phdr size=%d)\n", ehdr->e_phentsize); errno = EINVAL; return -errno; } if (ehdr->e_phnum != 1) { DEBUG_PRINTF("Invalid program header count (%d), expected 1\n", ehdr->e_phnum); errno = EINVAL; return -errno; } phdr = (Elf32_Phdr *)(handle->elf_image + ehdr->e_phoff); if (phdr->p_type != PT_LOAD || phdr->p_memsz == 0) { DEBUG_PRINTF("SPE program segment is not loadable (type=%x)\n", phdr->p_type); errno = EINVAL; return -errno; } if (addr) *addr = (uint64_t)(unsigned long) (handle->elf_image + phdr->p_offset); if (size) *size = phdr->p_memsz; return 0; }
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().
{ Elf32_Ehdr *ehdr; Elf32_Shdr *shdr, *sh; char *str_table; char **ch; int ret; long toe_size; ehdr = (Elf32_Ehdr*) (speh->elf_image); shdr = (Elf32_Shdr*) ((char*) ehdr + ehdr->e_shoff); str_table = (char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset; toe_size = 0; for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) if (strcmp(".toe", str_table + sh->sh_name) == 0) toe_size += sh->sh_size; ret = 0; if (toe_size > 0) { for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh) if (sh->sh_type == SHT_SYMTAB || sh->sh_type == SHT_DYNSYM) ret = toe_check_syms(ehdr, sh); if (!ret && toe_size != 16) { /* Paranoia */ fprintf(stderr, "Unexpected toe size of %ld\n", toe_size); errno = EINVAL; ret = 1; } } if (!ret && toe_size) { /* * Allocate toe_shadow, and fill it with elf_image. */ speh->toe_shadow = malloc(toe_size); if (speh->toe_shadow) { ch = (char**) speh->toe_shadow; if (sizeof(char*) == 8) { ch[0] = (char*) speh->elf_image; ch[1] = 0; } else { ch[0] = 0; ch[1] = (char*) speh->elf_image; ch[2] = 0; ch[3] = 0; } } else { errno = ENOMEM; ret = 1; } } return ret; }
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().