11#include "irx_imports.h"
17static void *heap_buffer_base = NULL;
18static void *heap_buffer = NULL;
19static void *heap_buffer_end = NULL;
21static int *allocate_heap_buffer(
unsigned int lower_bound,
unsigned int upper_bound)
23 unsigned int upper_bound_rounded;
28 upper_bound_rounded = upper_bound;
30 if ( (upper_bound_rounded & 3) != 0 )
32 upper_bound_rounded += (4 - (upper_bound_rounded & 3));
35 heap_buffer_base = AllocSysMemory(ALLOC_LAST, upper_bound_rounded, NULL);
37 if ( heap_buffer_base != NULL )
39 heap_buffer = heap_buffer_base;
40 heap_buffer_end = &(((u8 *)heap_buffer_base)[upper_bound_rounded]);
41 return heap_buffer_base;
43 printf(
"memory allocation failed.\n");
47static void *elf_load_alloc_buffer_from_heap(u32 alloc_size)
49 u32 alloc_size_rounded;
51 alloc_size_rounded = alloc_size;
53 if ( (alloc_size & 3) != 0 )
55 alloc_size_rounded += (4 - (alloc_size & 3));
61 new_ptr = heap_buffer;
63 new_ptr += alloc_size_rounded;
64 if ( (u8 *)new_ptr > (u8 *)heap_buffer_end )
74 new_ptr = heap_buffer;
76 ((u32 *)new_ptr)[0] = alloc_size_rounded;
77 new_ptr +=
sizeof(alloc_size_rounded);
80 new_ptr += alloc_size_rounded;
82 heap_buffer = new_ptr;
87static void elf_load_dealloc_buffer_from_heap(
void *alloc_memory)
91 if ( alloc_memory == NULL )
96 if ( (((u8 *)alloc_memory) - 4 < ((u8 *)heap_buffer_base)) || ((u8 *)alloc_memory) >= ((u8 *)heap_buffer_end) )
101 chunk_size = *((u32 *)(((u8 *)alloc_memory) - 4));
103 if ( ((u8 *)alloc_memory) + chunk_size != ((u8 *)heap_buffer) )
108 heap_buffer = ((u8 *)alloc_memory) - 4;
113 int index_of_ph_contents;
114 int offset_of_ph_contents;
122 if ( ehdr->e_ident[0] !=
'\x7F' )
126 if ( ehdr->e_ident[1] !=
'E' )
130 if ( ehdr->e_ident[2] !=
'L' )
134 if ( ehdr->e_ident[3] !=
'F' )
143 if ( flhs->elf_header.e_ident[4] != 1 )
147 if ( flhs->elf_header.e_ident[5] != 1 )
151 if ( flhs->elf_header.e_type != 2 )
155 if ( flhs->elf_header.e_machine != 8 )
159 if ( flhs->elf_header.e_ehsize != 52 )
163 if ( flhs->elf_header.e_phentsize != 32 )
167 if ( !flhs->elf_header.e_shnum )
171 if ( flhs->elf_header.e_shentsize != 40 )
185 pehdr = (
const loadfile_elf32_ehdr_t **)&allocate_info->ring_buffer_contents[allocate_info->ring_buffer_index];
186 hdrchkres = check_elf_header(pehdr);
187 ehdr = &flhs->elf_header;
190 printf(
"File is not ELF format(%d)\n", hdrchkres);
191 return KE_ILLEGAL_OBJECT;
193 memcpy(ehdr, *pehdr,
sizeof(*ehdr));
194 hdrchkres = check_elf_architecture(flhs);
197 printf(
"File is not for target architecture(%d)\n", hdrchkres);
198 return KE_ILLEGAL_OBJECT;
207 u8 *alloc_buffer_from_heap;
209 totalphsize = flhs->elf_header.e_phentsize * flhs->elf_header.e_phnum;
210 alloc_buffer_from_heap = elf_load_alloc_buffer_from_heap(totalphsize);
212 if ( alloc_buffer_from_heap == NULL )
217 alloc_buffer_from_heap,
218 &allocate_info->ring_buffer_contents[allocate_info->ring_buffer_index].buffer_base[flhs->elf_header.e_phoff],
226 u8 *alloc_buffer_from_heap;
228 lseek(flhs->fd, flhs->elf_header.e_shoff, 0);
229 totahshsize = flhs->elf_header.e_shentsize * flhs->elf_header.e_shnum;
230 alloc_buffer_from_heap = elf_load_alloc_buffer_from_heap(totahshsize);
232 if ( alloc_buffer_from_heap == NULL )
236 if ( read(flhs->fd, alloc_buffer_from_heap, totahshsize) != totahshsize )
238 elf_load_dealloc_buffer_from_heap(flhs->section_headers);
239 flhs->section_headers = 0;
248 u8 *alloc_buffer_from_heap;
250 shdr = &flhs->section_headers[flhs->elf_header.e_shstrndx];
251 if ( shdr->sh_type != 3 || shdr->sh_flags != 0 || shdr->sh_link != 0 || shdr->sh_info != 0 )
253 flhs->section_contents = 0;
254 return KE_ILLEGAL_OBJECT;
256 alloc_buffer_from_heap = elf_load_alloc_buffer_from_heap(shdr->sh_size);
257 flhs->section_contents = alloc_buffer_from_heap;
258 if ( alloc_buffer_from_heap == NULL )
262 lseek(flhs->fd, shdr->sh_offset, 0);
263 if ( (u32)(read(flhs->fd, flhs->section_contents, shdr->sh_size)) != shdr->sh_size )
265 elf_load_dealloc_buffer_from_heap(flhs->section_contents);
266 flhs->section_contents = 0;
278 szo1 = ph_size_offset_data + 1;
279 while ( ph_i1 < ph_count )
283 int index_of_ph_contents;
284 unsigned int offset_of_ph_contents;
287 index_of_ph_contents = szo1->index_of_ph_contents;
288 offset_of_ph_contents = szo1->offset_of_ph_contents;
290 szo3 = &ph_size_offset_data[ph_i2];
291 while ( ph_i2 >= 0 && offset_of_ph_contents < (u32)(szo3->offset_of_ph_contents) )
293 szo3[1].index_of_ph_contents = szo3->index_of_ph_contents;
294 szo3[1].offset_of_ph_contents = szo3->offset_of_ph_contents;
298 szo2 = &ph_size_offset_data[ph_i2];
299 szo2[1].index_of_ph_contents = index_of_ph_contents;
300 szo2[1].offset_of_ph_contents = offset_of_ph_contents;
308 int read_buffer_offset;
314 read_buffer_offset = allocate_info->read_buffer_offset;
315 rbc = &allocate_info->ring_buffer_contents[allocate_info->ring_buffer_index];
316 rbc->buffer_offset = read_buffer_offset;
317 read_res = read(fd, rbc->buffer_base, allocate_info->read_buffer_length);
318 rbc->buffer_length = read_res;
319 allocate_info->read_buffer_offset += read_res;
323static int elf_load_proc(
326 void *read_callback_userdata,
327 loadfile_read_chunk_callback_t read_callback)
331 unsigned int sh_offset_total;
332 unsigned int sh_size_for_offset;
333 int sh_size_for_alignment;
339 if ( flhs->program_header == NULL )
341 return KE_ILLEGAL_OBJECT;
347 for ( i = 0; i < flhs->elf_header.e_phnum; i += 1 )
351 phdr1 = &flhs->program_header[i];
352 if ( phdr1->p_type == 1 && phdr1->p_filesz )
354 phso[ph_count].index_of_ph_contents = i;
355 phso[ph_count].offset_of_ph_contents = phdr1->p_offset;
360 sort_ph_contents(ph_count, phso);
361 printf(
"Input ELF format filename = %s\n", flhs->filename);
362 for ( ph_i2 = 0; ph_i2 < ph_count; ph_i2 += 1 )
365 int index_of_ph_contents;
367 unsigned int sh_size_cur;
369 index_of_ph_contents = phso[ph_i2].index_of_ph_contents;
370 phdr2 = &flhs->program_header[index_of_ph_contents];
371 sh_size_cur = phdr2->p_filesz;
372 printf(
"%d %08x %08x ", index_of_ph_contents, phdr2->p_vaddr, sh_size_cur);
374 while ( sh_size_cur != 0 )
377 rbc = &allocate_info->ring_buffer_contents[allocate_info->ring_buffer_index];
378 while ( sceSifDmaStat(rbc->dma_handle) >= 0 )
380 sh_offset_total = phdr2->p_offset + total_offset;
381 while ( sh_offset_total >= (u32)(allocate_info->read_buffer_offset) )
383 if ( read_callback(flhs->fd, allocate_info, read_callback_userdata) != 0 )
388 sh_size_for_offset = sh_offset_total - rbc->buffer_offset;
389 sh_size_for_alignment = sh_size_cur;
390 if ( rbc->buffer_length - sh_size_for_offset < sh_size_cur )
391 sh_size_for_alignment = rbc->buffer_length - sh_size_for_offset;
392 dmat.src = &rbc->buffer_base[sh_size_for_offset];
393 sh_size_cur -= sh_size_for_alignment;
394 dmat.size = sh_size_for_alignment;
396 dmat.dest = (
void *)((phdr2->p_vaddr) + total_offset);
397 total_offset += sh_size_for_alignment;
399 rbc->dma_handle = sceSifSetDma(&dmat, 1);
401 allocate_info->ring_buffer_index = (allocate_info->ring_buffer_index + 1) & 1;
405 printf(
"Loaded, %s\n", flhs->filename);
409static int elf_load_single_section(
413 const char *section_name)
418 unsigned int sh_size;
426 if ( read(flhs->fd, &flhs->elf_header, 0x34) != 0x34 )
430 result = elf_read_header_section_headers(flhs);
435 result = elf_read_section_contents(flhs);
443 for ( i = 0; i < flhs->elf_header.e_shnum; i += 1 )
445 shdr = &flhs->section_headers[i];
446 if ( !strcmp((
const char *)&flhs->section_contents[shdr->sh_name], section_name) && shdr->sh_size )
451 if ( shdr == NULL || shdr->sh_addr < 0x80000 )
453 return KE_ILLEGAL_OBJECT;
456 lseek(flhs->fd, shdr->sh_offset, 0);
457 allocate_info->read_buffer_offset = shdr->sh_offset;
458 sh_size = shdr->sh_size;
459 printf(
"%s: %08x %08x ", section_name, shdr->sh_addr, sh_size);
460 while ( sh_size != 0 )
463 unsigned int sh_offset_total;
464 unsigned int sh_size_for_offset;
465 int sh_size_for_alignment;
468 rbc = &allocate_info->ring_buffer_contents[allocate_info->ring_buffer_index];
469 while ( sceSifDmaStat(rbc->dma_handle) >= 0 )
471 sh_offset_total = shdr->sh_offset + total_offset;
472 for ( i = allocate_info; sh_offset_total >= (u32)(allocate_info->read_buffer_offset); i = allocate_info )
473 fileio_reader_function(flhs->fd, i, 0);
474 sh_size_for_offset = sh_offset_total - rbc->buffer_offset;
475 sh_size_for_alignment = sh_size;
476 if ( rbc->buffer_length - sh_size_for_offset < sh_size )
477 sh_size_for_alignment = rbc->buffer_length - sh_size_for_offset;
478 dmat.src = &rbc->buffer_base[sh_size_for_offset];
479 sh_size -= sh_size_for_alignment;
480 dmat.size = sh_size_for_alignment;
482 dmat.dest = (
void *)((shdr->sh_addr) + total_offset);
484 total_offset += sh_size_for_alignment;
485 rbc->dma_handle = sceSifSetDma(&dmat, 1);
487 allocate_info->ring_buffer_index = (allocate_info->ring_buffer_index + 1) & 1;
489 printf(
"\nLoaded, %s:%s\n", flhs->filename, section_name);
493int elf_load_all_section(
497 int *result_module_out)
501 fileio_reader_function(flhs->fd, allocate_info, 0);
502 result = check_valid_ee_elf(allocate_info, flhs);
507 result = elf_get_program_header(allocate_info, flhs);
515 for ( i = 0; i < flhs->elf_header.e_phnum; i += 1 )
519 phdr1 = &(flhs->program_header[i]);
520 if ( phdr1->p_type == 1 && phdr1->p_filesz && phdr1->p_vaddr < 0x80000 )
522 return KE_ILLEGAL_OBJECT;
526 result = elf_load_proc(allocate_info, flhs, 0, fileio_reader_function);
531 *result_out = flhs->elf_header.e_entry;
532 *result_module_out = 0;
533 printf(
"start address %#08x\n", *result_out);
534 printf(
"gp address %#08x\n", *result_module_out);
542 flhs->section_contents = 0;
543 flhs->unknown_0C = 0;
544 flhs->program_header = 0;
545 flhs->section_headers = 0;
546 flhs->unknown_4C = 0;
549static int elf_load_common(
550 const char *filename,
int epc,
const char *section_name,
int *result_out,
int *result_module_out,
int is_mg_elf)
552 int *heap_buffer_cur;
560 CheckKelfPath_callback_t CheckKelfPath_fnc;
561 SetLoadfileCallbacks_callback_t SetLoadfileCallbacks_fnc;
565 printf(
"%s",
"loadelf version 3.30\n");
566 empty_loadfile_information(&flh);
567 flh.filename = filename;
568 flh.fd = open(filename, 1);
571 printf(
"Cannot openfile\n");
573 goto finish_returnresult;
575 heap_buffer_cur = allocate_heap_buffer(0, 0x10000);
577 if ( heap_buffer_cur == NULL )
579 printf(
"Error Can't Get heap buffer\n");
580 result = KE_NO_MEMORY;
585 while ( read_buffer == NULL )
590 read_buffer = (
char *)AllocSysMemory(ALLOC_LAST, bufsz, NULL);
596 if ( bufsz_divisor >= 8 )
598 printf(
"Error Can't Get read buffer\n");
599 result = KE_NO_MEMORY;
600 goto finish_freeheapbuffer;
603 allocate_info.ring_buffer_index = 0;
604 allocate_info.read_buffer_length = (
unsigned int)bufsz >> 1;
605 allocate_info.read_buffer_offset = 0;
609 for ( i = 0; i < 2; i += 1 )
611 allocate_info.ring_buffer_contents[i].buffer_offset = 0;
612 allocate_info.ring_buffer_contents[i].buffer_length = 0;
613 allocate_info.ring_buffer_contents[i].dma_handle = 0;
614 allocate_info.ring_buffer_contents[i].buffer_base = (u8 *)&read_buffer[allocate_info.read_buffer_length * i];
617 result = KE_ILLEGAL_OBJECT;
620 GetLoadfileCallbacks(&CheckKelfPath_fnc, &SetLoadfileCallbacks_fnc);
621 if ( SetLoadfileCallbacks_fnc )
623 loadfile_functions.elf_load_proc = elf_load_proc;
624 loadfile_functions.check_valid_ee_elf = check_valid_ee_elf;
625 loadfile_functions.elf_get_program_header = elf_get_program_header;
626 loadfile_functions.elf_load_alloc_buffer_from_heap = elf_load_alloc_buffer_from_heap;
627 loadfile_functions.elf_load_dealloc_buffer_from_heap = elf_load_dealloc_buffer_from_heap;
628 SetLoadfileCallbacks_fnc(&loadfile_functions);
629 if ( CheckKelfPath_fnc && CheckKelfPath_fnc(filename, &card_port, &card_slot) )
631 if ( loadfile_functions.load_kelf_from_card )
633 result = loadfile_functions.load_kelf_from_card(
634 &allocate_info, &flh, card_port, card_slot, result_out, result_module_out);
637 else if ( loadfile_functions.load_kelf_from_disk )
639 result = loadfile_functions.load_kelf_from_disk(&allocate_info, &flh, result_out, result_module_out);
643 else if ( !strcmp(section_name,
"all") )
645 result = elf_load_all_section(&allocate_info, &flh, result_out, result_module_out);
649 result = elf_load_single_section(&allocate_info, &flh, epc, section_name);
651 FreeSysMemory(read_buffer);
652finish_freeheapbuffer:
653 FreeSysMemory(heap_buffer_cur);
660int loadfile_elfload_innerproc(
661 const char *filename,
int epc,
const char *section_name,
int *result_out,
int *result_module_out)
663 if ( IsIllegalBootDevice(filename) != 0 )
665 return KE_ILLEGAL_OBJECT;
667 return elf_load_common(filename, epc, section_name, result_out, result_module_out, 0);
670int loadfile_mg_elfload_proc(
671 const char *filename,
int epc,
const char *section_name,
int *result_out,
int *result_module_out)
673 if ( strcmp(section_name,
"all") != 0 )
675 return KE_ILLEGAL_MODE;
677 return elf_load_common(filename, epc, section_name, result_out, result_module_out, 1);
int CpuResumeIntr(int state)
int CpuSuspendIntr(int *state)