* Add 0001-remoteproc-Fix-management-of-non-loadable-program-se.patch to fix elf loader bug Signed-off-by: hanzongcheng <hanzongcheng@huawei.com>
64 lines
2.4 KiB
Diff
64 lines
2.4 KiB
Diff
From 79b795e954e15d0d7c37d49fd32ac9cc0315bc3c Mon Sep 17 00:00:00 2001
|
|
From: Umair Khan <umair_khan@mentor.com>
|
|
Date: Wed, 7 Feb 2024 19:43:04 +0500
|
|
Subject: [PATCH] remoteproc: Fix management of non loadable program segments
|
|
|
|
The elf loader assumes that the last ELF program segment will always
|
|
be a LOAD type segment. I deduce this from the fact that the elf_load()
|
|
function, when loading the remote ELF sections during the
|
|
RPROC_LOADER_READY_TO_LOAD stage, compares the last load segment num
|
|
to the total ELF sections to determine if the loading is complete and
|
|
it can move to the next stage RPROC_LOADER_POST_DATA_LOAD. If the last
|
|
program segment in the ELF is not of type LOAD, the last loaded LOAD
|
|
segment never equals total ELF sections. This creates an error
|
|
condition and the firmware loading fails. This patch fixes this issue
|
|
by comparing the last loaded LOAD segment number with the max LOAD
|
|
segment number in the ELF.
|
|
|
|
Signed-off-by: Umair Khan <umair_khan@mentor.com>
|
|
|
|
diff --git a/lib/remoteproc/elf_loader.c b/lib/remoteproc/elf_loader.c
|
|
index 4d50183..c0eb116 100644
|
|
--- a/lib/remoteproc/elf_loader.c
|
|
+++ b/lib/remoteproc/elf_loader.c
|
|
@@ -571,20 +571,25 @@ int elf_load(struct remoteproc *rproc,
|
|
nsegment = *load_state & ELF_NEXT_SEGMENT_MASK;
|
|
phdr = elf_next_load_segment(*img_info, &nsegment, da,
|
|
noffset, &nsize, &nsegmsize);
|
|
- if (!phdr) {
|
|
- metal_log(METAL_LOG_DEBUG, "cannot find more segment\r\n");
|
|
- *load_state = (*load_state & (~ELF_NEXT_SEGMENT_MASK)) |
|
|
- (nsegment & ELF_NEXT_SEGMENT_MASK);
|
|
- return *load_state;
|
|
- }
|
|
- *nlen = nsize;
|
|
- *nmemsize = nsegmsize;
|
|
+
|
|
phnums = elf_phnum(*img_info);
|
|
- metal_log(METAL_LOG_DEBUG, "segment: %d, total segs %d\r\n",
|
|
- nsegment, phnums);
|
|
+ if (phdr) {
|
|
+ *nlen = nsize;
|
|
+ *nmemsize = nsegmsize;
|
|
+ metal_log(METAL_LOG_DEBUG, "segment: %d, total segs %d\r\n",
|
|
+ nsegment, phnums);
|
|
+ }
|
|
+
|
|
if (nsegment == phnums) {
|
|
- *load_state = (*load_state & (~RPROC_LOADER_MASK)) |
|
|
+ if (phdr) {
|
|
+ *load_state = (*load_state & (~RPROC_LOADER_MASK)) |
|
|
RPROC_LOADER_POST_DATA_LOAD;
|
|
+ } else {
|
|
+ metal_log(METAL_LOG_DEBUG, "no more segment to load\r\n");
|
|
+ *load_state = (*load_state & (~RPROC_LOADER_MASK)) |
|
|
+ RPROC_LOADER_LOAD_COMPLETE;
|
|
+ *da = RPROC_LOAD_ANYADDR;
|
|
+ }
|
|
}
|
|
*load_state = (*load_state & (~ELF_NEXT_SEGMENT_MASK)) |
|
|
(nsegment & ELF_NEXT_SEGMENT_MASK);
|
|
--
|
|
2.34.1
|
|
|