Skip to content

Commit

Permalink
elf loader: The rproc elf loading problem
Browse files Browse the repository at this point in the history
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: Muhammad Umair Khan <[email protected]>
  • Loading branch information
UmairKhanUET committed Feb 7, 2024
1 parent b32187e commit f2f9364
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
2 changes: 2 additions & 0 deletions lib/include/openamp/elf_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ struct elf32_info {
Elf32_Phdr *phdrs;
Elf32_Shdr *shdrs;
void *shstrtab;
int max_load_phnum;
};

struct elf64_info {
Expand All @@ -298,6 +299,7 @@ struct elf64_info {
Elf64_Phdr *phdrs;
Elf64_Shdr *shdrs;
void *shstrtab;
int max_load_phnum;
};

#define ELF_STATE_INIT 0x0L
Expand Down
43 changes: 38 additions & 5 deletions lib/remoteproc/elf_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ static void **elf_shstrtab_ptr(void *elf_info)
}
}

static int *elf_max_load_phnum(void *elf_info)
{
if (elf_is_64(elf_info) == 0) {
struct elf32_info *einfo = elf_info;

return &einfo->max_load_phnum;
} else {

Check warning on line 170 in lib/remoteproc/elf_loader.c

View workflow job for this annotation

GitHub Actions / checkpatch review

UNNECESSARY_ELSE

lib/remoteproc/elf_loader.c:170 else is not generally useful after a break or return
struct elf64_info *einfo = elf_info;

return &einfo->max_load_phnum;
}
}

static int *elf_load_state(void *elf_info)
{
if (elf_is_64(elf_info) == 0) {
Expand Down Expand Up @@ -374,6 +387,25 @@ static const void *elf_next_load_segment(void *elf_info, int *nseg,
return phdr;
}

static void elf_find_max_load_phnum(void *elf_info)
{
const void *phdr = PT_NULL;
unsigned int p_type = PT_NULL;
int nseg = 0;
int *max_load_seg;

max_load_seg = elf_max_load_phnum(elf_info);
phdr = elf_get_segment_from_index(elf_info, nseg);
while (phdr != PT_NULL) {
elf_parse_segment(elf_info, phdr, &p_type, NULL,
NULL, NULL, NULL, NULL);
if (p_type == PT_LOAD)
*max_load_seg = nseg;
nseg++;
phdr = elf_get_segment_from_index(elf_info, nseg);
}
}

static size_t elf_info_size(const void *img_data)
{
if (elf_is_64(img_data) == 0)
Expand Down Expand Up @@ -453,6 +485,7 @@ int elf_load_header(const void *img_data, size_t offset, size_t len,
if (!*phdrs)
return -RPROC_ENOMEM;
memcpy(*phdrs, img_phdrs, phdrs_size);
elf_find_max_load_phnum(*img_info);
*load_state = ELF_STATE_WAIT_FOR_SHDRS |
RPROC_LOADER_READY_TO_LOAD;
}
Expand Down Expand Up @@ -566,7 +599,7 @@ int elf_load(struct remoteproc *rproc,
int nsegment;
size_t nsegmsize = 0;
size_t nsize = 0;
int phnums = 0;
int *max_load_phnum = 0;

nsegment = *load_state & ELF_NEXT_SEGMENT_MASK;
phdr = elf_next_load_segment(*img_info, &nsegment, da,
Expand All @@ -579,10 +612,10 @@ int elf_load(struct remoteproc *rproc,
}
*nlen = nsize;
*nmemsize = nsegmsize;
phnums = elf_phnum(*img_info);
metal_log(METAL_LOG_DEBUG, "segment: %d, total segs %d\r\n",
nsegment, phnums);
if (nsegment == phnums) {
max_load_phnum = elf_max_load_phnum(*img_info);
metal_log(METAL_LOG_DEBUG, "segment: %d, last load seg %d\r\n",
nsegment, *max_load_phnum);
if (nsegment == *max_load_phnum) {
*load_state = (*load_state & (~RPROC_LOADER_MASK)) |
RPROC_LOADER_POST_DATA_LOAD;
}
Expand Down

0 comments on commit f2f9364

Please sign in to comment.