mirror of
https://github.com/FIX94/hbc.git
synced 2024-12-29 12:41:50 +01:00
114 lines
2.5 KiB
C
114 lines
2.5 KiB
C
|
/*
|
||
|
* Copyright (c) 2001 William L. Pitts
|
||
|
* Modifications (c) 2004 Felix Domke
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms are freely
|
||
|
* permitted provided that the above copyright notice and this
|
||
|
* paragraph and the following disclaimer are duplicated in all
|
||
|
* such forms.
|
||
|
*
|
||
|
* This software is provided "AS IS" and without any express or
|
||
|
* implied warranties, including, without limitation, the implied
|
||
|
* warranties of merchantability and fitness for a particular
|
||
|
* purpose.
|
||
|
*/
|
||
|
|
||
|
#include "common.h"
|
||
|
#include "elf_abi.h"
|
||
|
#include "string.h"
|
||
|
|
||
|
int valid_elf_image (void *addr) {
|
||
|
Elf32_Ehdr *ehdr; /* Elf header structure pointer */
|
||
|
|
||
|
ehdr = (Elf32_Ehdr *) addr;
|
||
|
|
||
|
if (!IS_ELF (*ehdr))
|
||
|
return 0;
|
||
|
|
||
|
if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
|
||
|
return -1;
|
||
|
|
||
|
if (ehdr->e_ident[EI_DATA] != ELFDATA2MSB)
|
||
|
return -1;
|
||
|
|
||
|
if (ehdr->e_ident[EI_VERSION] != EV_CURRENT)
|
||
|
return -1;
|
||
|
|
||
|
if (ehdr->e_type != ET_EXEC)
|
||
|
return -1;
|
||
|
|
||
|
if (ehdr->e_machine != EM_PPC)
|
||
|
return -1;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
u32 load_elf_image(void *addr) {
|
||
|
Elf32_Ehdr *ehdr;
|
||
|
Elf32_Phdr *phdrs;
|
||
|
u8 *image;
|
||
|
int i;
|
||
|
|
||
|
ehdr = (Elf32_Ehdr *)addr;
|
||
|
|
||
|
if(ehdr->e_phoff == 0 || ehdr->e_phnum == 0) {
|
||
|
printf("ELF has no phdrs\n");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if(ehdr->e_phentsize != sizeof(Elf32_Phdr)) {
|
||
|
printf("Invalid ELF phdr size\n");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
phdrs = (Elf32_Phdr*)(addr + ehdr->e_phoff);
|
||
|
|
||
|
for(i = 0; i < ehdr->e_phnum; i++) {
|
||
|
if(phdrs[i].p_type != PT_LOAD) {
|
||
|
printf("skip PHDR %d of type %d\n", i, phdrs[i].p_type);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// translate paddr to this BAT setup
|
||
|
phdrs[i].p_paddr &= 0x3FFFFFFF;
|
||
|
phdrs[i].p_paddr |= 0x80000000;
|
||
|
|
||
|
printf("PHDR %d 0x%08x [0x%x] -> 0x%08x [0x%x] <", i,
|
||
|
phdrs[i].p_offset, phdrs[i].p_filesz,
|
||
|
phdrs[i].p_paddr, phdrs[i].p_memsz);
|
||
|
|
||
|
if(phdrs[i].p_flags & PF_R)
|
||
|
printf("R");
|
||
|
if(phdrs[i].p_flags & PF_W)
|
||
|
printf("W");
|
||
|
if(phdrs[i].p_flags & PF_X)
|
||
|
printf("X");
|
||
|
printf(">\n");
|
||
|
|
||
|
if(phdrs[i].p_filesz > phdrs[i].p_memsz) {
|
||
|
printf("-> file size > mem size\n");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if(phdrs[i].p_filesz) {
|
||
|
printf("-> load 0x%x\n", phdrs[i].p_filesz);
|
||
|
image = (u8 *)(addr + phdrs[i].p_offset);
|
||
|
memcpy((void *)phdrs[i].p_paddr, (const void *)image,
|
||
|
phdrs[i].p_filesz);
|
||
|
memset((void *)image, 0, phdrs[i].p_filesz);
|
||
|
|
||
|
sync_after_write((void *)phdrs[i].p_paddr, phdrs[i].p_memsz);
|
||
|
|
||
|
if(phdrs[i].p_flags & PF_X)
|
||
|
sync_before_exec((void *)phdrs[i].p_paddr, phdrs[i].p_memsz);
|
||
|
} else {
|
||
|
printf ("-> skip\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// entry point of the ELF _has_ to be correct - no translation done
|
||
|
return ehdr->e_entry;
|
||
|
}
|
||
|
|