Load ELF symbol table for DDB.

This commit is contained in:
toshii 2001-03-21 14:06:25 +00:00
parent 5b519fb0f9
commit 358a8ee71a
4 changed files with 101 additions and 6 deletions

View File

@ -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 @@ Loader::_load_segment(vaddr_t kv, vsize_t memsz, off_t fileofs, size_t filesz)
_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)
{

View File

@ -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 @@ protected:
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:

View File

@ -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 @@ ElfLoader::~ElfLoader(void)
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 @@ ElfLoader::memorySize()
sz += _mem->roundPage(filesz);
}
}
/* XXX reserve 192kB for symbols */
sz += 0x30000;
DPRINTF((TEXT(" = 0x%x byte\n"), sz));
return sz;
}
@ -96,6 +104,11 @@ BOOL
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 @@ ElfLoader::load()
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;

View File

@ -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 @@ class ElfLoader : public Loader {
private:
Elf_Ehdr _eh;
Elf_Phdr _ph[16];
Elf_Shdr _sh[16];
BOOL is_elf_file(void) {
return