lib: elf: Fix bootelf -p crash issue
Do not load and flush segments whose program header type is not
PT_LOAD to avoid crash happen.
bootelf will load all program headers and then flush cache.
Since PT_GNU_STACK start address is 0x0, crash happens when
it flushes PT_GNU_STACK area for target that memory cannot be
accessed from address 0x0.
crash call stack:
====================================================================
bootelf -p
|-> do_bootelf (cmd/elf.c)
|-> load_elf_image_phdr (lib/elf.c) /* Load each program header */
|-> for (i = 0; i < ehdr->e_phnum; ++i) { /* e_phnum is 2 */
|-> flush_cache(start=0, size=0) (arch/arm/lib/cache.c) (*1)
|-> flush_dcache_range(start=0, 0); (arch/arm/cpu/armv8/cache_v8.c)
|-> __asm_flush_dcache_range(start=0, 0) (arch/arm/cpu/armv8/cache.S)
|-> /* clean & invalidate data or unified cache */
|-> dc civac, x0 <<== crash happen x0:start=0
====================================================================
*1 Here the p_paddr and p_filesz of the GNU_STACK program are 0.
hello_world elf image program headers
====================================================================
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000080ff0000 0x0000000080ff0000
0x0000000000010390 0x0000000000010390 R E 0x10000
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
Section to Segment mapping:
Segment Sections...
00 .text .rodata .eh_frame
01
====================================================================
bootelf -p crash error log
====================================================================
bootelf -p 0x80f00000
"Synchronous Abort" handler, esr 0x96000147, far 0x0
elr: 000000008f6035bc lr : 000000008f66ff54 (reloc)
elr: 00000000bd9475bc lr : 00000000bd9b3f54
x0 : 0000000000000000 x1 : 0000000000000000
x2 : 0000000000000040 x3 : 000000000000003f
x4 : 0000000081000390 x5 : 00000000bd12da98
x6 : 0000000000000010 x7 : 0000000000000010
x8 : 000000000000000a x9 : 00000000bd156b30
x10: 00000000bd1526e0 x11: 0000000000000000
x12: 0000000000000004 x13: 00000000bda00000
x14: 00000000ffffffff x15: 00000000bd12dab7
x16: 00000000bd957b14 x17: 0000000000000000
x18: 00000000bd13fd90 x19: 0000000080f000b0
x20: 0000000080f00000 x21: 0000000000000002
x22: 0000000000000000 x23: 0000000000000003
x24: 00000000bd9eacc0 x25: 0000000000000000
x26: 0000000000000000 x27: 0000000000000000
x28: 00000000bd154c80 x29: 00000000bd12da70
Code: d2800082 9ac32042 d1000443 8a230000 (d50b7e20)
====================================================================
Signed-off-by: Jianfeng Zhu <JianfengA.Zhu@sony.com>
Reviewed-by: Jacky Cao <Jacky.Cao@sony.com>
Reviewed-by: Toyama, Yoshihiro <Yoshihiro.Toyama@sony.com>
diff --git a/lib/elf.c b/lib/elf.c
index dc13935..28ec87b 100644
--- a/lib/elf.c
+++ b/lib/elf.c
@@ -90,6 +90,10 @@
void *dst = (void *)(ulong)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
+ /* Only load PT_LOAD program header */
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
debug("Loading phdr %i to 0x%p (%lu bytes)\n",
i, dst, (ulong)phdr->p_filesz);
if (phdr->p_filesz)
@@ -205,6 +209,10 @@
void *dst = (void *)(uintptr_t)phdr->p_paddr;
void *src = (void *)addr + phdr->p_offset;
+ /* Only load PT_LOAD program header */
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
debug("Loading phdr %i to 0x%p (%i bytes)\n",
i, dst, phdr->p_filesz);
if (phdr->p_filesz)