This is the mail archive of the
ecos-devel@sourceware.org
mailing list for the eCos project.
bug in RedBoot ELF loader?
- From: Bert Thomas <bert at brothom dot nl>
- To: ecos-devel at ecos dot sourceware dot org
- Date: Tue, 06 Jun 2006 14:13:38 +0100
- Subject: bug in RedBoot ELF loader?
Hi all,
I think I may have found a bug in the RedBoot ELF loader, but it may be
just as well that I don't understand the code well enough. Here's the part:
*************
for (phx = 0; phx < ehdr.e_phnum; phx++) {
if (phdr[phx].p_type == PT_LOAD) {
// Loadable segment
addr = (unsigned char *)phdr[phx].p_vaddr;
len = phdr[phx].p_filesz;
if ((unsigned long)addr < lowest_address) {
lowest_address = (unsigned long)addr;
}
addr += addr_offset;
if (offset > phdr[phx].p_offset) {
if ((phdr[phx].p_offset + len) < offset) {
diag_printf("Can't load ELF file - program headers
out of order\n");
return 0;
}
addr += offset - phdr[phx].p_offset;
} else {
while (offset < phdr[phx].p_offset) {
if ((*getc)() < 0) {
diag_printf(SHORT_DATA);
return 0;
}
offset++;
}
}
*************
It appears that normally the first program segment header contains a
file offset of 0. This is on purpose, to tell the loader to load the ELF
header and the program segment headers as well I am told. However, this
is where the redboot loader fails. It can't seek back to the beginning
of the file. The destination address in memory is compensated for that
by this line:
addr += offset - phdr[phx].p_offset;
(At least, that's what I think).
However, I know for sure that it is incorrect to read 'len' bytes from
the current offset instead of the real offset. This results in trouble
when the next segment to be loaded is smaller then the "offset error".
In some of my experiments the next segment was a "comment" segment that
I didn't really need to have in memory. However, the loader failed
loading my segment, saying "Can't load ELF file - program headers out of
order". They weren't out of order, but I can see why it comes to that
conclusion.
Example:
An ELF file with 2 segments:
segment 0: offset in file = 0, length = 0xac
segment 1: offset in file = 0xac, length = 15
First iteration, to load segment 0, offset=84
len = 0xac (172 bytes), so start reading 172 bytes from offset 84
Second iteration,to load segment 1, offset=256 (84+172)
len = 15, expected offset in file=172 (0xac), expected end in file =
172+15=187
The current offset is 256 and thus larger then 187 -> error!
My suggested fix would be to adjust 'len' to the remaining bytes, say:
len -= offset;
Regards,
Bert