This is the mail archive of the ecos-devel@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]