Re: More hpcboot memory/ELF loading errors?

Rafal Boni <[email protected]> Wed, 05 Mar 2008 21:33:19 -0500
Newsgroups gmane.os.netbsd.ports.hpcarm
Message-ID <[email protected]>
Rafal Boni wrote:
> Folks:
> 	I've been having a lot of trouble getting hpcboot to correctly
> 	load/boot much of anything on my iPAQ, and the symptoms look very
> 	much like the bug Uwe fixed about 2 years ago... looks like I'm
> 	running out of memory in the currently allocated region(s) and
> 	some page is either leaked into or overwritten because it's been
> 	handed out more than once.

My latest attempt has tossed the guard pages out the window and made the 
ELF symbol-loading machinery return better (read: more conservative) 
estimates of amount of memory required to load the symbols.

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
elf-load.diff (text/plain, 1.8 KB)
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();
-
 		}
 	}
 
@@ -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();
 	}
 
 	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));
 
-	// 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));
+	    
 }
 
 void