2 * Copyright (c) 2001 William L. Pitts
3 * Modifications (c) 2004 Felix Domke
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
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
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
;
38 if (ehdr
->e_type
!= ET_EXEC
)
41 if (ehdr
->e_machine
!= EM_PPC
)
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
)
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) {
78 shdr
->sh_addr
&= 0x3FFFFFFF;
79 shdr
->sh_addr
|= 0x80000000;
82 printf ("%sing section %s @ 0x%08x (0x%08x bytes)\n",
83 (shdr
->sh_type
== SHT_NOBITS
) ?
85 &strtab
[shdr
->sh_name
],
90 if (shdr
->sh_type
== SHT_NOBITS
) {
91 memset ((void *) shdr
->sh_addr
, 0, shdr
->sh_size
);
93 image
= (u8
*) addr
+ shdr
->sh_offset
;
94 memcpy ((void *) shdr
->sh_addr
,
98 DCFlushRangeNoSync ((void *) shdr
->sh_addr
, shdr
->sh_size
);
101 return (ehdr
->e_entry
& 0x3FFFFFFF) | 0x80000000;