Add linux-next specific files for 20110831
[linux-2.6/next.git] / tools / kvm / symbol.c
blob56dd346c4af813d329a624bc16a1e67e186abf49
1 #include "kvm/symbol.h"
3 #include "kvm/kvm.h"
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <bfd.h>
10 static bfd *abfd;
12 void symbol__init(const char *vmlinux)
14 if (!vmlinux)
15 return;
17 bfd_init();
19 abfd = bfd_openr(vmlinux, NULL);
22 static asymbol *lookup(asymbol **symbols, int nr_symbols, const char *symbol_name)
24 int i;
26 for (i = 0; i < nr_symbols; i++) {
27 asymbol *symbol = symbols[i];
29 if (!strcmp(bfd_asymbol_name(symbol), symbol_name))
30 return symbol;
33 return NULL;
36 char *symbol__lookup(struct kvm *kvm, unsigned long addr, char *sym, size_t size)
38 const char *filename;
39 bfd_vma sym_offset;
40 bfd_vma sym_start;
41 asection *section;
42 unsigned int line;
43 const char *func;
44 long symtab_size;
45 asymbol *symbol;
46 asymbol **syms;
47 int nr_syms;
48 char *s;
50 if (!abfd)
51 goto not_found;
53 if (!bfd_check_format(abfd, bfd_object))
54 goto not_found;
56 symtab_size = bfd_get_symtab_upper_bound(abfd);
57 if (!symtab_size)
58 goto not_found;
60 syms = malloc(symtab_size);
61 if (!syms)
62 goto not_found;
64 nr_syms = bfd_canonicalize_symtab(abfd, syms);
66 section = bfd_get_section_by_name(abfd, ".debug_aranges");
67 if (!section)
68 goto not_found;
70 if (!bfd_find_nearest_line(abfd, section, NULL, addr, &filename, &func, &line))
71 goto not_found;
73 if (!func)
74 goto not_found;
76 symbol = lookup(syms, nr_syms, func);
77 if (!symbol)
78 goto not_found;
80 sym_start = bfd_asymbol_value(symbol);
82 sym_offset = addr - sym_start;
84 snprintf(sym, size, "%s+%llx (%s:%i)", func, (long long) sym_offset, filename, line);
86 sym[size - 1] = '\0';
88 free(syms);
90 return sym;
92 not_found:
93 s = strncpy(sym, "<unknown>", size);
95 sym[size - 1] = '\0';
97 return s;