this adds address to symbol lookups to the kernel debugger. try the "ls <someaddr>" command.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@371 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2002-07-21 17:50:56 +00:00
parent a0ea8d5fd3
commit 3ff18ff146
1 changed files with 92 additions and 0 deletions

View File

@ -15,6 +15,7 @@
#include <debug.h>
#include <memheap.h>
#include <atomic.h>
#include <stdlib.h>
#include <arch/cpu.h>
@ -39,6 +40,7 @@ struct elf_region {
struct elf_image_info {
struct elf_image_info *next;
char *name;
image_id id;
int ref_count;
void *vnode;
@ -82,6 +84,90 @@ static image_id next_image_id = 0;
#define HASHCHAINS(image) ((unsigned int *)&(image)->symhash[2+HASHTABSIZE(image)])
/* static */ int
get_address_symbol_info(addr address, char *text, int maxtextlen)
{
struct elf_image_info **ptr;
struct elf_image_info *image;
struct Elf32_Sym *sym;
struct elf_image_info *found_image;
struct Elf32_Sym *found_sym;
long found_delta;
int i,j,rv;
PRINT(("looking up %#x\n",address));
mutex_lock(&image_lock);
found_sym = 0;
found_image = 0;
found_delta = 0x7fffffff;
for(ptr = &kernel_images; *ptr; ptr = &(*ptr)->next) {
image = *ptr;
PRINT((" image %p, base = %#x, size = %#x\n", image, image->regions[0].start, image->regions[0].size));
if ((address < image->regions[0].start) || (address >= (image->regions[0].start + image->regions[0].size)))
continue;
PRINT((" searching...\n"));
found_image = image;
for (i = 0; i < HASHTABSIZE(image); i++) {
for(j = HASHBUCKETS(image)[i]; j != STN_UNDEF; j = HASHCHAINS(image)[j]) {
long d;
sym = &image->syms[j];
PRINT((" %p looking at %s, type = %d, bind = %d, addr = %p\n",sym,SYMNAME(image, sym),ELF32_ST_TYPE(sym->st_info),ELF32_ST_BIND(sym->st_info),sym->st_value));
PRINT((" symbol: %x (%x + %x)\n", sym->st_value + image->regions[0].delta, sym->st_value, image->regions[0].delta));
if ((ELF32_ST_TYPE(sym->st_info) != STT_FUNC) || (ELF32_ST_BIND(sym->st_info) != STB_GLOBAL))
continue;
d = (long)address - (long)(sym->st_value + image->regions[0].delta);
if ((d >= 0) && (d < found_delta)) {
found_delta = d;
found_sym = sym;
}
}
}
break;
}
if (found_sym == 0) {
PRINT(("symbol not found!\n"));
strlcpy(text, "symbol not found", maxtextlen);
rv = -1;
} else {
PRINT(("symbol at %p, in image %p, name = %s\n", found_sym, found_image, found_image->name));
PRINT(("name index %d, '%s'\n", found_sym->st_name, SYMNAME(found_image, found_sym)));
PRINT(("addr = %#x, offset = %#x\n",(found_sym->st_value + found_image->regions[0].delta),found_delta));
// XXX should honor maxtextlen here
sprintf(text, "<%#lx:%s + %#lx> %s", (found_sym->st_value + found_image->regions[0].delta), SYMNAME(found_image, found_sym), found_delta, found_image->name);
rv = 0;
}
mutex_unlock(&image_lock);
return rv;
}
static int
print_address_info(int argc, char **argv)
{
char text[128];
long address;
if(argc < 2) {
dprintf("not enough arguments\n");
return 0;
}
address = atoul(argv[1]);
get_address_symbol_info(address, text, sizeof(text));
dprintf("%#lx = %s\n",address,text);
return 0;
}
static void
insert_image_in_list(struct elf_image_info *image)
{
@ -759,6 +845,7 @@ elf_load_kspace(const char *path, const char *sym_prepend)
}
image->vnode = vnode;
image->eheader = eheader;
image->name = kstrdup(path);
pheaders = (struct Elf32_Phdr *)kmalloc(eheader->e_phnum * eheader->e_phentsize);
if (pheaders == NULL) {
@ -931,6 +1018,7 @@ elf_unload_image_final(struct elf_image_info *image)
remove_image_from_list(image);
kfree(image->eheader);
kfree(image->name);
kfree(image);
}
@ -996,6 +1084,8 @@ elf_init(kernel_args *ka)
// build a image structure for the kernel, which has already been loaded
kernel_image = create_image_struct();
kernel_image->name = kstrdup("kernel");
// text segment
kernel_image->regions[0].id = vm_find_region_by_name(vm_get_kernel_aspace_id(), "kernel_ro");
@ -1024,6 +1114,8 @@ elf_init(kernel_args *ka)
kernel_images = NULL;
insert_image_in_list(kernel_image);
add_debugger_command("ls", &print_address_info, "lookup symbol for a particular address");
return 0;
}