Load ELF symbol table for DDB.
This commit is contained in:
parent
5b519fb0f9
commit
358a8ee71a
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user