Re: More hpcboot memory/ELF loading errors?
Rafal Boni <[email protected]> Thu, 06 Mar 2008 08:52:02 -0500
| Newsgroups | gmane.os.netbsd.ports.hpcarm |
|---|---|
| Message-ID | <[email protected]> |
Valeriy E. Ushakov wrote:
> On Wed, Mar 05, 2008 at 21:33:19 -0500, Rafal Boni wrote:
>
>> The issue appears to be that while the symbol header, symbol table and
>> string table are all loaded in 3 separate passes, the size-estimation
>> code returned the size of all 3 items as a single datum, ignoring the
>> fact that each of those 3 components would need at least one page (and
>> maybe more) to store the contents in the 'load chain'.
>>
>> Diff attached... comments welcome,
>> --rafal
>
>> Index: hpcboot/load_elf.cpp
>> ===================================================================
>> RCS file: /cvsroot/src/sys/arch/hpc/stand/hpcboot/load_elf.cpp,v
>> retrieving revision 1.17
>> diff -u -p -u -p -r1.17 load_elf.cpp
>> --- hpcboot/load_elf.cpp 5 Mar 2006 04:04:13 -0000 1.17
>> +++ hpcboot/load_elf.cpp 6 Mar 2008 02:01:36 -0000
>> @@ -123,10 +123,6 @@ ElfLoader::memorySize()
>> sz += _mem->roundPage(filesz);
>> // compensate for partial last tag
>> extra += _mem->getTaggedPageSize();
>> - if (filesz < ph->p_memsz)
>> - // compensate for zero clear
>> - extra += _mem->getTaggedPageSize();
>> -
>> }
>> }
>
> Why have you removed this? Zero-clear chunk occupies an extra tagged
> page in the chain.
I thought this was the case too, but if you follow the code / chain,
you'll note that they steal from the initial 'pvec' page allocated at
the beginning (they just kidnap sizeof(PageTag) since there's no data to
store). So I adjusted for reality.
>> @@ -135,8 +131,9 @@ ElfLoader::memorySize()
>> if (symblk_sz) {
>> sz += symblk_sz;
>> DPRINTF((TEXT(" = 0x%x]"), symblk_sz));
>> - // XXX: compensate for partial tags after ELF header and symtab
>> - extra += 2 * _mem->getTaggedPageSize();
>> + // XXX: compensate for partial tags after ELF header, symtab
>> + // and strtab
>> + extra += 3 * _mem->getTaggedPageSize();
>> }
>
> Does it work for you with this hunk alone?
I haven't tried just that one -- though even if it works, it seems a
little like a rubber-chickens and voodoo-sticks change ;). But I'll
give it a try and report back in any case..
>> sz += extra;
>> @@ -263,13 +260,17 @@ ElfLoader::symbol_block_size()
>> ROUND4(_sym_blk.shsym->sh_size);
>> _sym_blk.enable = TRUE;
>>
>> - DPRINTF((TEXT("+[ksyms: header 0x%x, symtab 0x%x, strtab 0x%x"),
>> + DPRINTF((TEXT("+[ksyms: header 0x%x, symtab 0x%x, strtab 0x%x = 0x%x]"),
>> _sym_blk.header_size, _sym_blk.shsym->sh_size,
>> - _sym_blk.shstr->sh_size));
>> + _sym_blk.shstr->sh_size, _sym_blk.header_size +
>> + ROUND4(_sym_blk.shsym->sh_size) + _sym_blk.shstr->sh_size));
>
> The sum is printed in the caller. If you print it here, you need to
> remove the printf in the caller.
Oops, I thought I had done that; will update, thanks.
>> - // return total amount of symbol block
>> - return (_sym_blk.header_size + ROUND4(_sym_blk.shsym->sh_size) +
>> - _sym_blk.shstr->sh_size);
>> + // Round each of the three components to page_size since they're
>> + // loaded as 3 different segments.
>> + return (_mem->roundPage(_sym_blk.header_size) +
>> + _mem->roundPage(ROUND4(_sym_blk.shsym->sh_size)) +
>> + _mem->roundPage(_sym_blk.shstr->sh_size));
>> +
>> }
>
> Is these roundPage necessary? I really don't want to inflict on
> myself the pain of reading and understanding this code again, but IIRC
> extra pages added in the caller are supposed to take care of this.
> Moreover, IIRC, doing roundPage doesn't actually help the "partial
> tag" problem.
I think this is the crux of the problem, and yeah, I think it's
necessary. If you look at what ElfLoader::load_symbol_block() does, it
loads (a) header, (b) symbol table, and (c) string table as individual
segments, which means each will start on a new page in the tag chain.
So if you have e.g. 1320 + 1290 + 1350 bytes in those 3, before we'd
return 1320 + ROUND4(1290) = 1292 + 1350 = 3962, which would look like
it would fit in a single page (even in a single tagged page), but would
actually require *3* tagged pages since each component would get it's
own link (== tagged page) in the tag chain.
AAs for the 'partial tag' issue, I'm also not sure off the top of my
head, but given the gyrations Architecture::allocateMemory goes through
to convert bytes-needed-in-memory to tagged-pages-needed, I'd think as
long as we rounded up all segments to the next unit of tagged-page-size
(since after all that's what matters, not actual HW page size), there
should be *no* page unaccounted for. Rounding up to HW page size is
maybe a little sloppy, but should give more *conservative* estimates,
which from our POV is OK (after all, it's going to get rounded up to the
next chunk of 64k anyway when we allocate pages from WinCE).
> I'd prefer we really understand were the overflow occurs before we
> commit anything to this code that is already quite hairy.
I'm all for that, which is why I'm sending this to the list rather than
checking in... but I also want to minimize the amount of damage my
forehead takes from beating it against this too much, and in the end I
want something which works at least semi-reliably -- and this hasn't
been the case with the hpcboot built from unmodified sources.
Thanks,
--rafal