tcploader addded
[svpe-wii.git] / tcploader / wii / elf.c
blob8d1e8d73245e9840c09e1fafe3d0be99ef789782
1 /*
2 * Copyright (c) 2001 William L. Pitts
3 * Modifications (c) 2004 Felix Domke
4 * All rights reserved.
6 * Redistribution and use in source and binary forms are freely
7 * permitted provided that the above copyright notice and this
8 * paragraph and the following disclaimer are duplicated in all
9 * such forms.
11 * This software is provided "AS IS" and without any express or
12 * implied warranties, including, without limitation, the implied
13 * warranties of merchantability and fitness for a particular
14 * purpose.
17 #include <stdio.h>
18 #include <string.h>
20 #include <gccore.h>
22 #include "elf_abi.h"
24 /* ======================================================================
25 * Determine if a valid ELF image exists at the given memory location.
26 * First looks at the ELF header magic field, the makes sure that it is
27 * executable and makes sure that it is for a PowerPC.
28 * ====================================================================== */
29 s32 valid_elf_image (void *addr)
31 Elf32_Ehdr *ehdr; /* Elf header structure pointer */
33 ehdr = (Elf32_Ehdr *) addr;
35 if (!IS_ELF (*ehdr))
36 return 0;
38 if (ehdr->e_type != ET_EXEC)
39 return -1;
41 if (ehdr->e_machine != EM_PPC)
42 return -1;
44 return 1;
48 /* ======================================================================
49 * A very simple elf loader, assumes the image is valid, returns the
50 * entry point address.
51 * ====================================================================== */
52 u32 load_elf_image (void *addr)
54 Elf32_Ehdr *ehdr;
55 Elf32_Shdr *shdr;
56 u8 *strtab = 0;
57 u8 *image;
58 int i;
60 ehdr = (Elf32_Ehdr *) addr;
61 /* Find the section header string table for output info */
62 shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
63 (ehdr->e_shstrndx * sizeof (Elf32_Shdr)));
65 if (shdr->sh_type == SHT_STRTAB)
66 strtab = (u8 *) (addr + shdr->sh_offset);
68 /* Load each appropriate section */
69 for (i = 0; i < ehdr->e_shnum; ++i) {
70 shdr = (Elf32_Shdr *) (addr + ehdr->e_shoff +
71 (i * sizeof (Elf32_Shdr)));
73 if (!(shdr->sh_flags & SHF_ALLOC)
74 || shdr->sh_addr == 0 || shdr->sh_size == 0) {
75 continue;
78 shdr->sh_addr &= 0x3FFFFFFF;
79 shdr->sh_addr |= 0x80000000;
81 if (strtab) {
82 printf ("%sing section %s @ 0x%08x (0x%08x bytes)\n",
83 (shdr->sh_type == SHT_NOBITS) ?
84 "clear" : "load",
85 &strtab[shdr->sh_name],
86 (u32) shdr->sh_addr,
87 (u32) shdr->sh_size);
90 if (shdr->sh_type == SHT_NOBITS) {
91 memset ((void *) shdr->sh_addr, 0, shdr->sh_size);
92 } else {
93 image = (u8 *) addr + shdr->sh_offset;
94 memcpy ((void *) shdr->sh_addr,
95 (const void *) image,
96 shdr->sh_size);
98 DCFlushRangeNoSync ((void *) shdr->sh_addr, shdr->sh_size);
101 return (ehdr->e_entry & 0x3FFFFFFF) | 0x80000000;