Skip to content

Commit e7cd340

Browse files
committed
Moved elf parsing/scattering to elf.c, WIP sim
1 parent fb6ca43 commit e7cd340

8 files changed

Lines changed: 290 additions & 586 deletions

File tree

arch.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,9 @@ ifeq ($(TARGET),sim)
11251125
LD_END_GROUP=
11261126
BOOT_IMG=test-app/image.elf
11271127
CFLAGS+=-DARCH_SIM
1128-
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
1128+
ifneq ($(ELF_SCATTERED),1)
1129+
CFLAGS+=-DWOLFBOOT_USE_STDLIBC
1130+
endif
11291131
ifeq ($(FORCE_32BIT),1)
11301132
CFLAGS+=-m32
11311133
LDFLAGS+=-m32

hal/sim.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
#include "target.h"
4343
#include "printf.h"
4444

45+
#ifdef ELF_SCATTERED
46+
#include "elf.h"
47+
#endif
48+
4549
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
4650
#include "wolfhsm/wh_error.h"
4751
#include "wolfhsm/wh_client.h"
@@ -348,6 +352,19 @@ void do_boot(const uint32_t *app_offset)
348352

349353
main = (main_entry)((uint8_t*)pSymbolAddress + epc->entryoff);
350354
main(main_argc, main_argv, NULL, NULL);
355+
#elif defined ELF_SCATTERED
356+
unsigned long *entry_point = (unsigned long *)sim_ram_base;
357+
typedef int (*main_entry)(int, char**);
358+
main_entry main;
359+
360+
wolfBoot_printf("Loading ELF image with scattered segments...\n");
361+
ret = elf_store_image_scattered((void*)app_offset, entry_point, 0);
362+
if (ret != 0) {
363+
wolfBoot_printf( "Error loading ELF image!\n");
364+
exit(-1);
365+
}
366+
main = (main_entry)(entry_point);
367+
main(main_argc, main_argv);
351368
#else
352369
char *envp[1] = {NULL};
353370
int fd = memfd_create("test_app", 0);

include/elf.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extern "C" {
3232
#define ELF_IDENT_STR "\x7F""ELF"
3333

3434
/* header ident[4] */
35+
#define ELF_CLASS_OFF (4)
3536
#define ELF_CLASS_32 (1)
3637
#define ELF_CLASS_64 (2)
3738

@@ -161,7 +162,8 @@ typedef struct elf64_program_header {
161162

162163
typedef int (*elf_mmu_map_cb)(uint64_t, uint64_t, uint32_t);
163164
int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb);
164-
int elf_load_image(uint8_t *image, uintptr_t *entry);
165+
int elf_load_image(uint8_t *image, uintptr_t *entry, int is_ext);
166+
int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_out, int ext_flash);
165167

166168

167169
#ifdef __cplusplus

options.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,10 @@ ifeq ($(ELF),1)
786786
ifneq ($(DEBUG_ELF),)
787787
CFLAGS+=-DDEBUG_ELF=$(DEBUG_ELF)
788788
endif
789+
ifeq ($(ELF_SCATTERED),1)
790+
CFLAGS+=-D"ELF_SCATTERED=1"
791+
endif
792+
789793
endif
790794

791795
ifeq ($(MULTIBOOT2),1)

src/elf.c

Lines changed: 254 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "printf.h"
2828
#include "string.h"
2929
#include "elf.h"
30+
#include "hal.h"
3031

3132
#ifdef ARCH_PPC
3233
#include "hal/nxp_ppc.h"
@@ -43,6 +44,7 @@
4344
#endif
4445

4546

47+
#ifdef MMU
4648
/* Loader for elf32 or elf64 format program headers
4749
* Returns the entry point function
4850
*/
@@ -143,11 +145,262 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb)
143145

144146
return 0;
145147
}
148+
#endif /* MMU */
146149

147-
int elf_load_image(uint8_t *image, uintptr_t *entry)
150+
#if 0
151+
/**
152+
* @brief Compute the scattered hash by hashing PT_LOAD segments at their XIP
153+
* addresses. Note: This function assumes that the destination addresses for elf
154+
* loading have the same access patterns as the memory represented by img.
155+
* (e.g. if BOOT partition is external, then reads/writes to the load address
156+
* will use ext_flash_read/ext_flash_write.
157+
*
158+
* @param img Pointer to the wolfBoot image
159+
* @param hash Buffer to store the computed hash (must be at least
160+
* WOLFBOOT_SHA_DIGEST_SIZE bytes)
161+
* @return 0 on success, negative value on error
162+
*/
163+
static int wolfBoot_compute_scattered_hash(struct wolfBoot_image *img, uint8_t *hash)
148164
{
165+
uint8_t elf_header_buf[sizeof(elf64_header)];
166+
uint8_t program_header_buf[sizeof(elf64_program_header)];
167+
elf32_header* h32;
168+
elf64_header* h64;
169+
uint16_t entry_count, entry_size;
170+
uint32_t ph_offset;
171+
int is_elf32, is_le, i;
172+
#if defined(WOLFBOOT_HASH_SHA256)
173+
wc_Sha256 sha256_ctx;
174+
#elif defined(WOLFBOOT_HASH_SHA384)
175+
wc_Sha384 sha384_ctx;
176+
#elif defined(WOLFBOOT_HASH_SHA3_384)
177+
wc_Sha3 sha3_384_ctx;
178+
#endif
179+
180+
#ifdef EXT_FLASH
181+
if (PART_IS_EXT(img)) {
182+
/* Read ELF header from external flash */
183+
ext_flash_check_read((uintptr_t)(img->fw_base), elf_header_buf, sizeof(elf64_header));
184+
} else
185+
#endif
186+
{
187+
memcpy(elf_header_buf, (void*)(img->fw_base), sizeof(elf64_header));
188+
}
189+
190+
h32 = (elf32_header*)elf_header_buf;
191+
h64 = (elf64_header*)elf_header_buf;
192+
193+
/* Verify ELF header */
194+
if (memcmp(h32->ident, ELF_IDENT_STR, 4) != 0) {
195+
return -1; /* not valid header identifier */
196+
}
197+
198+
/* Load class and endianess */
199+
is_elf32 = (h32->ident[4] == ELF_CLASS_32);
200+
is_le = (h32->ident[5] == ELF_ENDIAN_LITTLE);
201+
(void)is_le;
202+
203+
/* Initialize hash context */
204+
#if defined(WOLFBOOT_HASH_SHA256)
205+
wc_InitSha256(&sha256_ctx);
206+
#elif defined(WOLFBOOT_HASH_SHA384)
207+
wc_InitSha384(&sha384_ctx);
208+
#elif defined(WOLFBOOT_HASH_SHA3_384)
209+
wc_Sha3_384_Init(&sha3_384_ctx, NULL, INVALID_DEVID);
210+
#endif
211+
212+
/* Get program headers info */
213+
ph_offset = is_elf32 ? GET32(h32->ph_offset) : GET32(h64->ph_offset);
214+
entry_size = is_elf32 ? GET16(h32->ph_entry_size) : GET16(h64->ph_entry_size);
215+
entry_count = is_elf32 ? GET16(h32->ph_entry_count) : GET16(h64->ph_entry_count);
216+
217+
/* Hash each loadable segment directly from its physical address */
218+
for (i = 0; i < entry_count; i++) {
219+
elf32_program_header* phdr32;
220+
elf64_program_header* phdr64;
221+
uint32_t type;
222+
uintptr_t paddr;
223+
uintptr_t file_size;
224+
225+
/* Read program header into buffer */
226+
#ifdef EXT_FLASH
227+
if (PART_IS_EXT(img)) {
228+
ext_flash_check_read((uintptr_t)(img->fw_base) + ph_offset + (i * entry_size),
229+
program_header_buf, entry_size);
230+
} else
231+
#endif
232+
{
233+
memcpy(program_header_buf,
234+
(uint8_t*)(img->fw_base) + ph_offset + (i * entry_size),
235+
entry_size);
236+
}
237+
238+
239+
phdr32 = (elf32_program_header*)program_header_buf;
240+
phdr64 = (elf64_program_header*)program_header_buf;
241+
type = (is_elf32 ? GET32(phdr32->type) : GET32(phdr64->type));
242+
paddr = (is_elf32 ? GET32(phdr32->paddr) : GET64(phdr64->paddr));
243+
file_size = (is_elf32 ? GET32(phdr32->file_size) : GET64(phdr64->file_size));
244+
245+
/* Only hash PT_LOAD segments with non-zero size */
246+
if (type == ELF_PT_LOAD && file_size > 0) {
247+
#ifdef DEBUG_ELF
248+
wolfBoot_printf("Hashing segment at %p (%d bytes)\r\n", (void*)paddr, (uint32_t)file_size);
249+
#endif
250+
/* Hash the segment data from physical address in blocks */
251+
uint32_t pos = 0;
252+
while (pos < file_size) {
253+
uint8_t *block;
254+
uint32_t blksz = WOLFBOOT_SHA_BLOCK_SIZE;
255+
256+
if (pos + blksz > file_size) {
257+
blksz = file_size - pos;
258+
}
259+
260+
block = get_sha_block_ptr(img, (const uint8_t *)(paddr + pos));
261+
if (block == NULL) {
262+
return -1;
263+
}
264+
265+
#if defined(WOLFBOOT_HASH_SHA256)
266+
wc_Sha256Update(&sha256_ctx, block, blksz);
267+
#elif defined(WOLFBOOT_HASH_SHA384)
268+
wc_Sha384Update(&sha384_ctx, block, blksz);
269+
#elif defined(WOLFBOOT_HASH_SHA3_384)
270+
wc_Sha3_384_Update(&sha3_384_ctx, block, blksz);
271+
#endif
272+
pos += blksz;
273+
}
274+
}
275+
}
276+
277+
/* Finalize hash */
278+
#if defined(WOLFBOOT_HASH_SHA256)
279+
wc_Sha256Final(&sha256_ctx, hash);
280+
#elif defined(WOLFBOOT_HASH_SHA384)
281+
wc_Sha384Final(&sha384_ctx, hash);
282+
#elif defined(WOLFBOOT_HASH_SHA3_384)
283+
wc_Sha3_384_Final(&sha3_384_ctx, hash);
284+
#endif
285+
286+
return 0;
287+
}
288+
#endif
289+
290+
int elf_store_image_scattered(const unsigned char *image, unsigned long *entry_out, int ext_flash) {
291+
const unsigned char *ident;
292+
int is_elf32;
293+
unsigned short entry_count;
294+
unsigned short entry_size;
295+
unsigned long entry_off;
296+
int i;
297+
298+
ident = image;
299+
300+
301+
/* Verify ELF header */
302+
if (memcmp(ident, ELF_IDENT_STR, 4) != 0) {
303+
return -1; /* not valid header identifier */
304+
}
305+
306+
is_elf32 = (ident[ELF_CLASS_OFF] == ELF_CLASS_32);
307+
308+
if (is_elf32) {
309+
const elf32_header *eh;
310+
const elf32_program_header *ph;
311+
312+
eh = (const elf32_header *)image;
313+
entry_count = eh->ph_entry_count;
314+
entry_size = eh->ph_entry_size;
315+
entry_off = eh->ph_offset;
316+
*entry_out = (unsigned long)eh->entry;
317+
318+
ph = (const elf32_program_header *)(image + entry_off);
319+
for (i = 0; i < entry_count; ++i) {
320+
unsigned long paddr;
321+
unsigned long filesz;
322+
unsigned long offset;
323+
324+
if (ph[i].type != ELF_PT_LOAD)
325+
continue;
326+
327+
paddr = (unsigned long)ph[i].paddr;
328+
offset = (unsigned long)ph[i].offset;
329+
filesz = (unsigned long)ph[i].file_size;
330+
#if 0
331+
#ifdef EXT_FLASH
332+
if (ext_flash) {
333+
ext_flash_unlock();
334+
ext_flash_erase(paddr, filesz);
335+
ext_flash_write(paddr, image + offset, filesz);
336+
ext_flash_lock();
337+
}
338+
else
339+
#endif
340+
{
341+
hal_flash_unlock();
342+
hal_flash_erase(paddr, filesz);
343+
hal_flash_write(paddr, image + offset, filesz);
344+
hal_flash_lock();
345+
}
346+
#endif
347+
}
348+
} else if (ident[ELF_CLASS_OFF] == ELF_CLASS_64) {
349+
const elf64_header *eh;
350+
const elf64_program_header *ph;
351+
352+
eh = (const elf64_header *)image;
353+
entry_count = eh->ph_entry_count;
354+
entry_size = eh->ph_entry_size;
355+
entry_off = eh->ph_offset;
356+
*entry_out = (unsigned long)eh->entry;
357+
358+
ph = (const elf64_program_header *)(image + entry_off);
359+
for (i = 0; i < entry_count; ++i) {
360+
unsigned long paddr;
361+
unsigned long filesz;
362+
unsigned long offset;
363+
364+
if (ph[i].type != ELF_PT_LOAD)
365+
continue;
366+
367+
paddr = (unsigned long)ph[i].paddr;
368+
offset = (unsigned long)ph[i].offset;
369+
filesz = (unsigned long)ph[i].file_size;
370+
#if 0
371+
#ifdef EXT_FLASH
372+
if (ext_flash) {
373+
ext_flash_unlock();
374+
ext_flash_erase(paddr, filesz);
375+
ext_flash_write(paddr, image + offset, filesz);
376+
ext_flash_lock();
377+
}
378+
else
379+
#endif
380+
{
381+
hal_flash_unlock();
382+
hal_flash_erase(paddr, filesz);
383+
hal_flash_write(paddr, image + offset, filesz);
384+
hal_flash_lock();
385+
}
386+
#endif
387+
}
388+
} else {
389+
/* Invalid elf header. */
390+
return -1;
391+
}
392+
393+
return 0;
394+
}
395+
149396

397+
int elf_load_image(uint8_t *image, uintptr_t *entry, int ext_flash)
398+
{
399+
#ifdef MMU
150400
return elf_load_image_mmu(image, entry, NULL);
401+
#else
402+
return elf_store_image_scattered(image, entry, ext_flash);
403+
#endif
151404
}
152405

153406
#endif /* WOLFBOOT_ELF */

0 commit comments

Comments
 (0)