Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/hpc/stand/hpcboot reserve correct size of kernel sy...
details: https://anonhg.NetBSD.org/src/rev/54765d7eb027
branches: trunk
changeset: 512036:54765d7eb027
user: uch <uch%NetBSD.org@localhost>
date: Tue Jul 03 20:38:03 2001 +0000
description:
reserve correct size of kernel symbol table.
diffstat:
sys/arch/hpc/stand/hpcboot/load_elf.cpp | 191 +++++++++++++++++++++----------
sys/arch/hpc/stand/hpcboot/load_elf.h | 14 ++-
2 files changed, 144 insertions(+), 61 deletions(-)
diffs (truncated from 301 to 300 lines):
diff -r b3f01cad999a -r 54765d7eb027 sys/arch/hpc/stand/hpcboot/load_elf.cpp
--- a/sys/arch/hpc/stand/hpcboot/load_elf.cpp Tue Jul 03 20:26:23 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load_elf.cpp Tue Jul 03 20:38:03 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: load_elf.cpp,v 1.3 2001/05/08 18:51:23 uch Exp $ */
+/* $NetBSD: load_elf.cpp,v 1.4 2001/07/03 20:38:03 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -36,20 +36,30 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include <hpcmenu.h>
+#include <menu/window.h>
+#include <menu/rootwindow.h>
+
#include <load.h>
#include <load_elf.h>
#include <console.h>
#include <memory.h>
#include <file.h>
+#define ROUND4(x) (((x) + 3) & ~3)
+
ElfLoader::ElfLoader(Console *&cons, MemoryManager *&mem)
: Loader(cons, mem)
{
+ _sym_blk.enable = FALSE;
+
DPRINTF((TEXT("Loader: ELF\n")));
}
ElfLoader::~ElfLoader(void)
{
+ if (_sym_blk.header != NULL)
+ free (_sym_blk.header);
}
BOOL
@@ -58,14 +68,14 @@
size_t sz;
Loader::setFile(file);
- /* read ELF header and check it */
+ // read ELF header and check it
if (!read_header())
return FALSE;
- /* read section header */
+ // read section header
sz = _eh.e_shnum * _eh.e_shentsize;
_file->read(_sh, _eh.e_shentsize * _eh.e_shnum, _eh.e_shoff);
- /* read program header */
+ // read program header
sz = _eh.e_phnum * _eh.e_phentsize;
return _file->read(_ph, sz, _eh.e_phoff) == sz;
@@ -86,8 +96,13 @@
sz += _mem->roundPage(filesz);
}
}
- /* XXX reserve 192kB for symbols */
- sz += 0x30000;
+
+ // reserve for symbols
+ size_t symblk_sz = symbol_block_size();
+ if (symblk_sz) {
+ sz += symblk_sz;
+ DPRINTF((TEXT(" = 0x%x]"), symblk_sz));
+ }
DPRINTF((TEXT(" = 0x%x byte\n"), sz));
return sz;
@@ -104,12 +119,7 @@
ElfLoader::load()
{
Elf_Phdr *ph;
- Elf_Shdr *sh, *shstr, *shsym;
- off_t stroff = 0, symoff = 0, off;
vaddr_t kv;
-
- size_t shstrsize;
- char buf[1024];
int i;
_load_segment_start();
@@ -127,60 +137,121 @@
}
}
- /*
- * Prepare ELF headers for symbol table.
- *
- * ELF header
- * section header
- * shstrtab
- * strtab
- * symtab
- */
- memcpy(buf, &_eh, sizeof(_eh));
- ((Elf_Ehdr *)buf)->e_phoff = 0;
- ((Elf_Ehdr *)buf)->e_phnum = 0;
- ((Elf_Ehdr *)buf)->e_entry = 0;
- ((Elf_Ehdr *)buf)->e_shoff = sizeof(_eh);
- off = ((Elf_Ehdr *)buf)->e_shoff;
- memcpy(buf + off, _sh, _eh.e_shentsize * _eh.e_shnum);
- sh = (Elf_Shdr *)(buf + off);
- off += _eh.e_shentsize * _eh.e_shnum;
+ load_symbol_block(kv);
- /* load shstrtab and find desired sections */
- shstrsize = (sh[_eh.e_shstrndx].sh_size + 3) & ~0x3;
- _file->read(buf + off, shstrsize, sh[_eh.e_shstrndx].sh_offset);
- for(i = 0; i < _eh.e_shnum; i++, sh++) {
- if (strcmp(".strtab", buf + off + sh->sh_name) == 0) {
- stroff = sh->sh_offset;
- shstr = sh;
- } else if (strcmp(".symtab", buf + off + sh->sh_name) == 0) {
- symoff = sh->sh_offset;
- shsym = sh;
- }
- if (i == _eh.e_shstrndx)
- sh->sh_offset = off;
- else
- sh->sh_offset = 0;
- }
- /* silently return if strtab or symtab can't be found */
- if (! stroff || ! symoff)
- return TRUE;
-
- shstr->sh_offset = off + shstrsize;
- shsym->sh_offset = off + shstrsize + ((shstr->sh_size + 3) & ~0x3);
- _load_memory(kv, off + shstrsize, buf);
- kv += off + shstrsize;
- _load_segment(kv, shstr->sh_size, stroff, shstr->sh_size);
- kv += (shstr->sh_size + 3) & ~0x3;
- _load_segment(kv, shsym->sh_size, symoff, shsym->sh_size);
-
- /* tag chain still opening */
+ // tag chain still opening
return TRUE;
}
+//
+// Prepare ELF headers for symbol table.
+//
+// ELF header
+// section header
+// shstrtab
+// strtab
+// symtab
+//
+size_t
+ElfLoader::symbol_block_size()
+{
+ size_t shstrsize = ROUND4(_sh[_eh.e_shstrndx].sh_size);
+ size_t shtab_sz = _eh.e_shentsize * _eh.e_shnum;
+ off_t shstrtab_offset = sizeof(Elf_Ehdr) + shtab_sz;
+ int i;
+
+ memset(&_sym_blk, 0, sizeof(_sym_blk));
+ _sym_blk.enable = FALSE;
+ _sym_blk.header_size = sizeof(Elf_Ehdr) + shtab_sz + shstrsize;
+
+ // inquire string and symbol table size
+ _sym_blk.header = static_cast<char *>(malloc(_sym_blk.header_size));
+ if (_sym_blk.header == NULL) {
+ MessageBox(HPC_MENU._root->_window,
+ TEXT("couldn't determine symbol block size"),
+ TEXT("WARNING"), 0);
+ return (0);
+ }
+
+ // set pointer for symbol block
+ Elf_Ehdr *eh = reinterpret_cast<Elf_Ehdr *>(_sym_blk.header);
+ Elf_Shdr *sh = reinterpret_cast<Elf_Shdr *>
+ (_sym_blk.header + sizeof(Elf_Ehdr));
+ char *shstrtab = _sym_blk.header + shstrtab_offset;
+
+ // initialize headers
+ memset(_sym_blk.header, 0, _sym_blk.header_size);
+ memcpy(eh, &_eh, sizeof(Elf_Ehdr));
+ eh->e_phoff = 0;
+ eh->e_phnum = 0;
+ eh->e_entry = 0; // XXX NetBSD kernel check this member. see machdep.c
+ eh->e_shoff = sizeof(Elf_Ehdr);
+ memcpy(sh, _sh, shtab_sz);
+
+ // inquire symbol/string table information
+ _file->read(shstrtab, shstrsize, _sh[_eh.e_shstrndx].sh_offset);
+ for (i = 0; i < _eh.e_shnum; i++, sh++) {
+ if (strcmp(".strtab", shstrtab + sh->sh_name) == 0) {
+ _sym_blk.shstr = sh;
+ _sym_blk.stroff = sh->sh_offset;
+ } else if (strcmp(".symtab", shstrtab + sh->sh_name) == 0) {
+ _sym_blk.shsym = sh;
+ _sym_blk.symoff = sh->sh_offset;
+ }
+
+ sh->sh_offset = (i == _eh.e_shstrndx) ? shstrtab_offset : 0;
+ }
+
+ if (_sym_blk.shstr == NULL || _sym_blk.shsym == NULL) {
+ MessageBox(HPC_MENU._root->_window,
+ TEXT("no symbol and/or strint table in binary"),
+ TEXT("Information"), 0);
+ free(_sym_blk.header);
+ _sym_blk.header = NULL;
+
+ return (0);
+ }
+
+ // set Section Headers for symbol/string table
+ _sym_blk.shstr->sh_offset = shstrtab_offset + shstrsize;
+ _sym_blk.shsym->sh_offset = shstrtab_offset + shstrsize +
+ ROUND4(_sym_blk.shstr->sh_size);
+ _sym_blk.enable = TRUE;
+
+ DPRINTF((TEXT("+[(symbol block: header %d string %d symbol %d byte)"),
+ _sym_blk.header_size,_sym_blk.shstr->sh_size,
+ _sym_blk.shsym->sh_size));
+
+ // return total amount of symbol block
+ return (_sym_blk.header_size + ROUND4(_sym_blk.shstr->sh_size) +
+ _sym_blk.shsym->sh_size);
+}
+
+void
+ElfLoader::load_symbol_block(vaddr_t kv)
+{
+ size_t sz;
+
+ if (!_sym_blk.enable)
+ return;
+
+ // load header
+ _load_memory(kv, _sym_blk.header_size, _sym_blk.header);
+ kv += _sym_blk.header_size;
+
+ // load string table
+ sz = _sym_blk.shstr->sh_size;
+ _load_segment(kv, sz, _sym_blk.stroff, sz);
+ kv += ROUND4(sz);
+
+ // load symbol table
+ sz = _sym_blk.shsym->sh_size;
+ _load_segment(kv, sz, _sym_blk.symoff, sz);
+}
+
BOOL
-ElfLoader::read_header(void)
+ElfLoader::read_header()
{
// read ELF header
_file->read(&_eh, sizeof(Elf_Ehdr), 0);
@@ -208,7 +279,7 @@
return FALSE;
}
- /* Check object type */
+ // Check object type
if (_eh.e_type != ET_EXEC) {
DPRINTF((TEXT("not a executable file. type = %d\n"),
_eh.e_type));
diff -r b3f01cad999a -r 54765d7eb027 sys/arch/hpc/stand/hpcboot/load_elf.h
--- a/sys/arch/hpc/stand/hpcboot/load_elf.h Tue Jul 03 20:26:23 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load_elf.h Tue Jul 03 20:38:03 2001 +0000
@@ -1,4 +1,4 @@
-/* -*-C++-*- $NetBSD: load_elf.h,v 1.3 2001/05/08 18:51:23 uch Exp $ */
+/* -*-C++-*- $NetBSD: load_elf.h,v 1.4 2001/07/03 20:38:03 uch Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -47,6 +47,16 @@
Elf_Phdr _ph[16];
Elf_Shdr _sh[16];
+ struct _symbol_block {
+ BOOL enable;
+ char *header;
+ size_t header_size;
+ Elf_Shdr *shstr;
+ off_t stroff;
+ Elf_Shdr *shsym;
+ off_t symoff;
+ } _sym_blk;
+
BOOL is_elf_file(void) {
return
_eh.e_ident[EI_MAG0] == ELFMAG0 &&
@@ -56,6 +66,8 @@
}
BOOL read_header(void);
struct PageTag *load_page(vaddr_t, off_t, size_t, struct PageTag *);
+ size_t symbol_block_size(void);
+ void load_symbol_block(vaddr_t);
public:
Home |
Main Index |
Thread Index |
Old Index