30 #include <sys/types.h>
37 static void display_debug_output(Elf32_Ehdr *elf_start, Elf32_Shdr *sh);
40 #define __PRINTF(fmt, args...) { fprintf(stderr,fmt , ## args); }
42 #define DEBUG_PRINTF(fmt, args...) __PRINTF(fmt , ## args)
43 #define TAG DEBUG_PRINTF("TAG: %d@%s\n", __LINE__, __FILE__);
45 #define DEBUG_PRINTF(fmt, args...)
49 static const unsigned char expected[EI_PAD] = {
54 [EI_CLASS] = ELFCLASS32,
55 [EI_DATA] = ELFDATA2MSB,
56 [EI_VERSION] = EV_CURRENT,
57 [EI_OSABI] = ELFOSABI_SYSV,
62 check_spe_elf(Elf32_Ehdr *ehdr)
65 if (memcmp (ehdr->e_ident, expected, EI_PAD) != 0)
69 *(
long long *) expected, *(
long long *) (ehdr->e_ident));
75 if (ehdr->e_machine != 0x17)
83 if (ehdr->e_type != ET_EXEC)
86 DEBUG_PRINTF (
"SPE type %d != %d\n", ehdr->e_type, ET_EXEC);
105 ehdr = (Elf32_Ehdr *)(handle->
elf_image);
107 return check_spe_elf(ehdr);
112 uint64_t *addr, uint32_t *size)
114 Elf32_Ehdr *ehdr = (Elf32_Ehdr *)handle->
elf_image;
123 if (ehdr->e_phentsize !=
sizeof(*phdr)) {
124 DEBUG_PRINTF(
"Invalid program header format (phdr size=%d)\n",
130 if (ehdr->e_phnum != 1) {
131 DEBUG_PRINTF(
"Invalid program header count (%d), expected 1\n",
137 phdr = (Elf32_Phdr *)(handle->
elf_image + ehdr->e_phoff);
139 if (phdr->p_type != PT_LOAD || phdr->p_memsz == 0) {
140 DEBUG_PRINTF(
"SPE program segment is not loadable (type=%x)\n",
147 *addr = (uint64_t)(
unsigned long)
151 *size = phdr->p_memsz;
157 overlay(Elf32_Phdr *ph, Elf32_Phdr *prev_ph)
163 if (prev_ph && (ph->p_vaddr >= prev_ph->p_vaddr) &&
164 (ph->p_vaddr < (prev_ph->p_vaddr + prev_ph->p_memsz)))
172 *ph, Elf32_Off toe_addr,
long toe_size)
176 DEBUG_PRINTF(
"SPE_LOAD %p (0x%x) -> %p (0x%x) (%i bytes)\n",
177 buffer + ph->p_vaddr, ph->p_vaddr, start + ph->p_offset,
178 ph->p_offset, ph->p_filesz);
181 if (ph->p_vaddr == toe_addr) {
184 if (toe_size != ph->p_filesz && ph->p_filesz) {
186 memcpy(buffer + ph->p_vaddr, start + ph->p_offset,
191 DEBUG_PRINTF(
"loading toe %X %X\n", ph->p_offset, toe_addr);
192 memcpy(buffer + ph->p_vaddr, handle->
toe_shadow, toe_size);
193 }
else if (ph->p_filesz) {
194 memcpy(buffer + ph->p_vaddr, start + ph->p_offset,
205 Elf32_Phdr *ph, *prev_ph;
210 Elf32_Off toe_addr = 0;
215 int num_load_seg = 0;
219 DEBUG_PRINTF (
"load_spe_elf(%p, %p)\n", handle, ld_buffer);
224 ehdr = (Elf32_Ehdr *)(handle->
elf_image);
227 if ((ret=check_spe_elf(ehdr)))
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;
237 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
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) {
242 toe_size += sh->sh_size;
243 if ((toe_addr == 0) || (toe_addr > sh->sh_addr))
244 toe_addr = sh->sh_addr;
255 if (strcmp(
".note.spu_name", str_table+sh->sh_name) == 0)
256 display_debug_output(elf_start, sh);
264 for (ph = phdr, prev_ph = NULL; ph < &phdr[ehdr->e_phnum]; ++ph) {
265 switch (ph->p_type) {
267 if (!overlay(ph, prev_ph)) {
268 if (ph->p_filesz < ph->p_memsz) {
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);
274 copy_to_ld_buffer(handle, ld_buffer, ph,
284 if (num_load_seg == 0)
292 ld_info->
entry = ehdr->e_entry;
301 display_debug_output(Elf32_Ehdr *elf_start, Elf32_Shdr *sh)
305 unsigned long namesz;
306 unsigned long descsz;
312 ELF_NOTE *note = (ELF_NOTE *)((
void *)elf_start+sh->sh_offset);
313 printf (
"Loading SPE program : %s\n", note->lookupname);
314 printf (
"SPU LS Entry Addr : 0x%05x\n", elf_start->e_entry);
319 toe_check_syms(Elf32_Ehdr *ehdr, Elf32_Shdr *sh)
321 Elf32_Sym *sym, *sym_hdr, *sym_end;
327 shdr = (Elf32_Shdr*) ((
char*) ehdr + ehdr->e_shoff);
328 sym_hdr = (Elf32_Sym*) ((
char*) ehdr + sh->sh_offset);
329 sym_end = (Elf32_Sym*) ((
char*) ehdr + sh->sh_offset + sh->sh_size);
330 str_table = (
char*)ehdr + shdr[sh->sh_link].sh_offset;
333 for (sym = sym_hdr; sym < sym_end; sym++)
335 sym_name = str_table + sym->st_name;
336 if ((strncmp(sym_name,
"_EAR_", 5) == 0) &&
337 (strcmp(sym_name,
"_EAR_") != 0)) {
345 fprintf(stderr,
"Invalid _EAR_ symbol '%s'\n",
357 Elf32_Shdr *shdr, *sh;
364 shdr = (Elf32_Shdr*) ((
char*) ehdr + ehdr->e_shoff);
365 str_table = (
char*)ehdr + shdr[ehdr->e_shstrndx].sh_offset;
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;
374 for (sh = shdr; sh < &shdr[ehdr->e_shnum]; ++sh)
375 if (sh->sh_type == SHT_SYMTAB || sh->sh_type ==
377 ret = toe_check_syms(ehdr, sh);
378 if (!ret && toe_size != 16) {
380 fprintf(stderr,
"Unexpected toe size of %ld\n",
386 if (!ret && toe_size) {
393 if (
sizeof(
char*) == 8) {