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 Load ELF symbol table for DDB.



details:   https://anonhg.NetBSD.org/src/rev/46a6fe4584bd
branches:  trunk
changeset: 507394:46a6fe4584bd
user:      toshii <toshii%NetBSD.org@localhost>
date:      Wed Mar 21 14:06:25 2001 +0000

description:
Load ELF symbol table for DDB.

diffstat:

 sys/arch/hpc/stand/hpcboot/load.cpp     |  33 +++++++++++++++-
 sys/arch/hpc/stand/hpcboot/load.h       |   3 +-
 sys/arch/hpc/stand/hpcboot/load_elf.cpp |  68 +++++++++++++++++++++++++++++++-
 sys/arch/hpc/stand/hpcboot/load_elf.h   |   3 +-
 4 files changed, 101 insertions(+), 6 deletions(-)

diffs (196 lines):

diff -r a61054bda58b -r 46a6fe4584bd sys/arch/hpc/stand/hpcboot/load.cpp
--- a/sys/arch/hpc/stand/hpcboot/load.cpp       Wed Mar 21 14:05:10 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load.cpp       Wed Mar 21 14:06:25 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: load.cpp,v 1.1 2001/02/09 18:34:44 uch Exp $   */
+/*     $NetBSD: load.cpp,v 1.2 2001/03/21 14:06:25 toshii Exp $        */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -201,6 +201,37 @@
        _kernend = kv + memsz;
 }
 
+void
+Loader::_load_memory(vaddr_t kv, vsize_t memsz, void *data)
+{
+       struct PageTag *pvec;
+       vaddr_t kv_start = kv, v;
+       paddr_t p, pvec_paddr;
+
+       DPRINTF((TEXT("\t->load 0x%08x+0x%08x=0x%08x\n"),
+                kv, memsz, kv + memsz));
+       if (memsz > _tpsz) {
+               /* XXX failure */
+               return;
+       }
+
+       _opvec_prev = _pvec_prev;
+       _mem->getTaggedPage(v, p, &pvec, pvec_paddr);      
+       memcpy((void *)v, data, memsz);
+       _pvec_prev->src = ptokv(p);
+       _pvec_prev->dst = kv;
+       _pvec_prev->sz = memsz;
+#ifdef PAGE_LINK_DUMP
+       _pvec_prev->next =(u_int32_t)pvec;
+#else
+       _pvec_prev->next = ptokv(pvec_paddr);
+#endif
+       _pvec_prev = pvec;
+
+       _kernend = kv + memsz;
+       ++_nload_link;
+}
+
 struct PageTag *
 Loader::_load_page(vaddr_t kv, off_t ofs, size_t sz, struct PageTag *prev)
 {
diff -r a61054bda58b -r 46a6fe4584bd sys/arch/hpc/stand/hpcboot/load.h
--- a/sys/arch/hpc/stand/hpcboot/load.h Wed Mar 21 14:05:10 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load.h Wed Mar 21 14:06:25 2001 +0000
@@ -1,4 +1,4 @@
-/* -*-C++-*-   $NetBSD: load.h,v 1.1 2001/02/09 18:34:44 uch Exp $     */
+/* -*-C++-*-   $NetBSD: load.h,v 1.2 2001/03/21 14:06:25 toshii Exp $  */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -68,6 +68,7 @@
 
        void _load_segment_start(void);
        void _load_segment(vaddr_t, vsize_t, off_t, size_t);
+       void _load_memory(vaddr_t, vsize_t, void *);
        void _load_segment_end(void);
 
 public:
diff -r a61054bda58b -r 46a6fe4584bd sys/arch/hpc/stand/hpcboot/load_elf.cpp
--- a/sys/arch/hpc/stand/hpcboot/load_elf.cpp   Wed Mar 21 14:05:10 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load_elf.cpp   Wed Mar 21 14:06:25 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: load_elf.cpp,v 1.1 2001/02/09 18:34:46 uch Exp $       */
+/*     $NetBSD: load_elf.cpp,v 1.2 2001/03/21 14:06:25 toshii Exp $    */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -55,13 +55,18 @@
 BOOL
 ElfLoader::setFile(File *&file)
 {
+       size_t sz;
        Loader::setFile(file);
 
        /* read ELF header and check it */
        if (!read_header())
                return FALSE;
+       /* 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 */
-       size_t sz = _eh.e_phnum * _eh.e_phentsize;
+       sz = _eh.e_phnum * _eh.e_phentsize;
 
        return _file->read(_ph, sz, _eh.e_phoff) == sz;
 }
@@ -81,6 +86,9 @@
                        sz += _mem->roundPage(filesz);
                }
        }
+       /* XXX reserve 192kB for symbols */
+       sz += 0x30000;
+
        DPRINTF((TEXT(" = 0x%x byte\n"), sz));
        return sz;
 }
@@ -96,6 +104,11 @@
 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();
@@ -104,13 +117,62 @@
                if (ph->p_type == PT_LOAD) {
                        size_t filesz = ph->p_filesz;
                        size_t memsz = ph->p_memsz;
-                       vaddr_t kv = ph->p_vaddr;
+                       kv = ph->p_vaddr;
                        off_t fileofs = ph->p_offset;
                        DPRINTF((TEXT("[%d] vaddr 0x%08x file size 0x%x mem size 0x%x\n"),
                                 i, kv, filesz, memsz));
                        _load_segment(kv, memsz, fileofs, filesz);
+                       kv += memsz;
                }
        }
+
+       /*
+        * 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 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 */
 
        return TRUE;
diff -r a61054bda58b -r 46a6fe4584bd sys/arch/hpc/stand/hpcboot/load_elf.h
--- a/sys/arch/hpc/stand/hpcboot/load_elf.h     Wed Mar 21 14:05:10 2001 +0000
+++ b/sys/arch/hpc/stand/hpcboot/load_elf.h     Wed Mar 21 14:06:25 2001 +0000
@@ -1,4 +1,4 @@
-/* -*-C++-*-   $NetBSD: load_elf.h,v 1.1 2001/02/09 18:34:47 uch Exp $ */
+/* -*-C++-*-   $NetBSD: load_elf.h,v 1.2 2001/03/21 14:06:25 toshii Exp $      */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -45,6 +45,7 @@
 private:
        Elf_Ehdr _eh;
        Elf_Phdr _ph[16];
+       Elf_Shdr _sh[16];
 
        BOOL is_elf_file(void) {
                return



Home | Main Index | Thread Index | Old Index