symbol.c (a2a99e8e12798706ec1026e5d8fc36f7c86122ce) | symbol.c (818331303bc7cb914351c992d3da00aae957eba7) |
---|---|
1#include "util.h" 2#include "../perf.h" 3#include "string.h" 4#include "symbol.h" | 1#include "util.h" 2#include "../perf.h" 3#include "string.h" 4#include "symbol.h" |
5#include "thread.h" | |
6 7#include "debug.h" 8 9#include <libelf.h> 10#include <gelf.h> 11#include <elf.h> | 5 6#include "debug.h" 7 8#include <libelf.h> 9#include <gelf.h> 10#include <elf.h> |
12#include <sys/utsname.h> | |
13 14const char *sym_hist_filter; 15 16enum dso_origin { 17 DSO__ORIG_KERNEL = 0, 18 DSO__ORIG_JAVA_JIT, 19 DSO__ORIG_FEDORA, 20 DSO__ORIG_UBUNTU, 21 DSO__ORIG_BUILDID, 22 DSO__ORIG_DSO, | 11 12const char *sym_hist_filter; 13 14enum dso_origin { 15 DSO__ORIG_KERNEL = 0, 16 DSO__ORIG_JAVA_JIT, 17 DSO__ORIG_FEDORA, 18 DSO__ORIG_UBUNTU, 19 DSO__ORIG_BUILDID, 20 DSO__ORIG_DSO, |
23 DSO__ORIG_KMODULE, | |
24 DSO__ORIG_NOT_FOUND, 25}; 26 | 21 DSO__ORIG_NOT_FOUND, 22}; 23 |
27static void dsos__add(struct dso *dso); 28static struct dso *dsos__find(const char *name); 29 30static struct rb_root kernel_maps; 31 32static void dso__set_symbols_end(struct dso *self) | 24static struct symbol *symbol__new(u64 start, u64 len, 25 const char *name, unsigned int priv_size, 26 u64 obj_start, int v) |
33{ | 27{ |
34 struct rb_node *nd, *prevnd = rb_first(&self->syms); 35 36 if (prevnd == NULL) 37 return; 38 39 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 40 struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node), 41 *curr = rb_entry(nd, struct symbol, rb_node); 42 43 if (prev->end == prev->start) 44 prev->end = curr->start - 1; 45 prevnd = nd; 46 } 47} 48 49static void kernel_maps__fixup_sym_end(void) 50{ 51 struct map *prev, *curr; 52 struct rb_node *nd, *prevnd = rb_first(&kernel_maps); 53 54 if (prevnd == NULL) 55 return; 56 57 curr = rb_entry(prevnd, struct map, rb_node); 58 dso__set_symbols_end(curr->dso); 59 60 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 61 prev = curr; 62 curr = rb_entry(nd, struct map, rb_node); 63 prev->end = curr->start - 1; 64 dso__set_symbols_end(curr->dso); 65 } 66} 67 68static struct symbol *symbol__new(u64 start, u64 len, const char *name, 69 unsigned int priv_size, int v) 70{ | |
71 size_t namelen = strlen(name) + 1; 72 struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen); 73 74 if (!self) 75 return NULL; 76 77 if (v >= 2) | 28 size_t namelen = strlen(name) + 1; 29 struct symbol *self = calloc(1, priv_size + sizeof(*self) + namelen); 30 31 if (!self) 32 return NULL; 33 34 if (v >= 2) |
78 printf("new symbol: %016Lx [%08lx]: %s, hist: %p\n", 79 start, (unsigned long)len, name, self->hist); | 35 printf("new symbol: %016Lx [%08lx]: %s, hist: %p, obj_start: %p\n", 36 (u64)start, (unsigned long)len, name, self->hist, (void *)(unsigned long)obj_start); |
80 | 37 |
38 self->obj_start= obj_start; |
|
81 self->hist = NULL; 82 self->hist_sum = 0; 83 84 if (sym_hist_filter && !strcmp(name, sym_hist_filter)) 85 self->hist = calloc(sizeof(u64), len); 86 87 if (priv_size) { 88 memset(self, 0, priv_size); --- 8 unchanged lines hidden (view full) --- 97 98static void symbol__delete(struct symbol *self, unsigned int priv_size) 99{ 100 free(((void *)self) - priv_size); 101} 102 103static size_t symbol__fprintf(struct symbol *self, FILE *fp) 104{ | 39 self->hist = NULL; 40 self->hist_sum = 0; 41 42 if (sym_hist_filter && !strcmp(name, sym_hist_filter)) 43 self->hist = calloc(sizeof(u64), len); 44 45 if (priv_size) { 46 memset(self, 0, priv_size); --- 8 unchanged lines hidden (view full) --- 55 56static void symbol__delete(struct symbol *self, unsigned int priv_size) 57{ 58 free(((void *)self) - priv_size); 59} 60 61static size_t symbol__fprintf(struct symbol *self, FILE *fp) 62{ |
105 return fprintf(fp, " %llx-%llx %s\n", | 63 if (!self->module) 64 return fprintf(fp, " %llx-%llx %s\n", |
106 self->start, self->end, self->name); | 65 self->start, self->end, self->name); |
66 else 67 return fprintf(fp, " %llx-%llx %s \t[%s]\n", 68 self->start, self->end, self->name, self->module->name); |
|
107} 108 109struct dso *dso__new(const char *name, unsigned int sym_priv_size) 110{ 111 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); 112 113 if (self != NULL) { 114 strcpy(self->name, name); | 69} 70 71struct dso *dso__new(const char *name, unsigned int sym_priv_size) 72{ 73 struct dso *self = malloc(sizeof(*self) + strlen(name) + 1); 74 75 if (self != NULL) { 76 strcpy(self->name, name); |
115 self->long_name = self->name; 116 self->short_name = self->name; | |
117 self->syms = RB_ROOT; 118 self->sym_priv_size = sym_priv_size; 119 self->find_symbol = dso__find_symbol; 120 self->slen_calculated = 0; 121 self->origin = DSO__ORIG_NOT_FOUND; 122 } 123 124 return self; --- 10 unchanged lines hidden (view full) --- 135 rb_erase(&pos->rb_node, &self->syms); 136 symbol__delete(pos, self->sym_priv_size); 137 } 138} 139 140void dso__delete(struct dso *self) 141{ 142 dso__delete_symbols(self); | 77 self->syms = RB_ROOT; 78 self->sym_priv_size = sym_priv_size; 79 self->find_symbol = dso__find_symbol; 80 self->slen_calculated = 0; 81 self->origin = DSO__ORIG_NOT_FOUND; 82 } 83 84 return self; --- 10 unchanged lines hidden (view full) --- 95 rb_erase(&pos->rb_node, &self->syms); 96 symbol__delete(pos, self->sym_priv_size); 97 } 98} 99 100void dso__delete(struct dso *self) 101{ 102 dso__delete_symbols(self); |
143 if (self->long_name != self->name) 144 free(self->long_name); | |
145 free(self); 146} 147 148static void dso__insert_symbol(struct dso *self, struct symbol *sym) 149{ 150 struct rb_node **p = &self->syms.rb_node; 151 struct rb_node *parent = NULL; 152 const u64 ip = sym->start; --- 31 unchanged lines hidden (view full) --- 184 return s; 185 } 186 187 return NULL; 188} 189 190size_t dso__fprintf(struct dso *self, FILE *fp) 191{ | 103 free(self); 104} 105 106static void dso__insert_symbol(struct dso *self, struct symbol *sym) 107{ 108 struct rb_node **p = &self->syms.rb_node; 109 struct rb_node *parent = NULL; 110 const u64 ip = sym->start; --- 31 unchanged lines hidden (view full) --- 142 return s; 143 } 144 145 return NULL; 146} 147 148size_t dso__fprintf(struct dso *self, FILE *fp) 149{ |
192 size_t ret = fprintf(fp, "dso: %s\n", self->short_name); | 150 size_t ret = fprintf(fp, "dso: %s\n", self->name); |
193 194 struct rb_node *nd; 195 for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { 196 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 197 ret += symbol__fprintf(pos, fp); 198 } 199 200 return ret; 201} 202 | 151 152 struct rb_node *nd; 153 for (nd = rb_first(&self->syms); nd; nd = rb_next(nd)) { 154 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 155 ret += symbol__fprintf(pos, fp); 156 } 157 158 return ret; 159} 160 |
203static int maps__load_kallsyms(symbol_filter_t filter, int use_modules, int v) | 161static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int v) |
204{ | 162{ |
205 struct map *map = kernel_map; | 163 struct rb_node *nd, *prevnd; |
206 char *line = NULL; 207 size_t n; 208 FILE *file = fopen("/proc/kallsyms", "r"); 209 int count = 0; 210 211 if (file == NULL) 212 goto out_failure; 213 214 while (!feof(file)) { 215 u64 start; 216 struct symbol *sym; 217 int line_len, len; 218 char symbol_type; | 164 char *line = NULL; 165 size_t n; 166 FILE *file = fopen("/proc/kallsyms", "r"); 167 int count = 0; 168 169 if (file == NULL) 170 goto out_failure; 171 172 while (!feof(file)) { 173 u64 start; 174 struct symbol *sym; 175 int line_len, len; 176 char symbol_type; |
219 char *module, *symbol_name; | |
220 221 line_len = getline(&line, &n, file); 222 if (line_len < 0) 223 break; 224 225 if (!line) 226 goto out_failure; 227 --- 6 unchanged lines hidden (view full) --- 234 continue; 235 236 symbol_type = toupper(line[len]); 237 /* 238 * We're interested only in code ('T'ext) 239 */ 240 if (symbol_type != 'T' && symbol_type != 'W') 241 continue; | 177 178 line_len = getline(&line, &n, file); 179 if (line_len < 0) 180 break; 181 182 if (!line) 183 goto out_failure; 184 --- 6 unchanged lines hidden (view full) --- 191 continue; 192 193 symbol_type = toupper(line[len]); 194 /* 195 * We're interested only in code ('T'ext) 196 */ 197 if (symbol_type != 'T' && symbol_type != 'W') 198 continue; |
242 243 symbol_name = line + len + 2; 244 module = strchr(symbol_name, '\t'); 245 if (module) { 246 char *module_name_end; 247 248 if (!use_modules) 249 continue; 250 *module = '\0'; 251 module = strchr(module + 1, '['); 252 if (!module) 253 continue; 254 module_name_end = strchr(module + 1, ']'); 255 if (!module_name_end) 256 continue; 257 *(module_name_end + 1) = '\0'; 258 if (strcmp(map->dso->name, module)) { 259 map = kernel_maps__find_by_dso_name(module); 260 if (!map) { 261 fputs("/proc/{kallsyms,modules} " 262 "inconsistency!\n", stderr); 263 return -1; 264 } 265 } 266 start = map->map_ip(map, start); 267 } else 268 map = kernel_map; | |
269 /* 270 * Well fix up the end later, when we have all sorted. 271 */ | 199 /* 200 * Well fix up the end later, when we have all sorted. 201 */ |
272 sym = symbol__new(start, 0, symbol_name, 273 map->dso->sym_priv_size, v); | 202 sym = symbol__new(start, 0xdead, line + len + 2, 203 self->sym_priv_size, 0, v); |
274 275 if (sym == NULL) 276 goto out_delete_line; 277 | 204 205 if (sym == NULL) 206 goto out_delete_line; 207 |
278 if (filter && filter(map, sym)) 279 symbol__delete(sym, map->dso->sym_priv_size); | 208 if (filter && filter(self, sym)) 209 symbol__delete(sym, self->sym_priv_size); |
280 else { | 210 else { |
281 dso__insert_symbol(map->dso, sym); | 211 dso__insert_symbol(self, sym); |
282 count++; 283 } 284 } 285 | 212 count++; 213 } 214 } 215 |
216 /* 217 * Now that we have all sorted out, just set the ->end of all 218 * symbols 219 */ 220 prevnd = rb_first(&self->syms); 221 222 if (prevnd == NULL) 223 goto out_delete_line; 224 225 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 226 struct symbol *prev = rb_entry(prevnd, struct symbol, rb_node), 227 *curr = rb_entry(nd, struct symbol, rb_node); 228 229 prev->end = curr->start - 1; 230 prevnd = nd; 231 } 232 |
|
286 free(line); 287 fclose(file); 288 289 return count; 290 291out_delete_line: 292 free(line); 293out_failure: 294 return -1; 295} 296 | 233 free(line); 234 fclose(file); 235 236 return count; 237 238out_delete_line: 239 free(line); 240out_failure: 241 return -1; 242} 243 |
297static size_t kernel_maps__fprintf(FILE *fp) | 244static int dso__load_perf_map(struct dso *self, symbol_filter_t filter, int v) |
298{ | 245{ |
299 size_t printed = fprintf(stderr, "Kernel maps:\n"); 300 struct rb_node *nd; 301 302 printed += map__fprintf(kernel_map, fp); 303 printed += dso__fprintf(kernel_map->dso, fp); 304 305 for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) { 306 struct map *pos = rb_entry(nd, struct map, rb_node); 307 308 printed += map__fprintf(pos, fp); 309 printed += dso__fprintf(pos->dso, fp); 310 } 311 312 return printed + fprintf(stderr, "END kernel maps\n"); 313} 314 315static int dso__load_perf_map(struct dso *self, struct map *map, 316 symbol_filter_t filter, int v) 317{ | |
318 char *line = NULL; 319 size_t n; 320 FILE *file; 321 int nr_syms = 0; 322 | 246 char *line = NULL; 247 size_t n; 248 FILE *file; 249 int nr_syms = 0; 250 |
323 file = fopen(self->long_name, "r"); | 251 file = fopen(self->name, "r"); |
324 if (file == NULL) 325 goto out_failure; 326 327 while (!feof(file)) { 328 u64 start, size; 329 struct symbol *sym; 330 int line_len, len; 331 --- 14 unchanged lines hidden (view full) --- 346 347 len += hex2u64(line + len, &size); 348 349 len++; 350 if (len + 2 >= line_len) 351 continue; 352 353 sym = symbol__new(start, size, line + len, | 252 if (file == NULL) 253 goto out_failure; 254 255 while (!feof(file)) { 256 u64 start, size; 257 struct symbol *sym; 258 int line_len, len; 259 --- 14 unchanged lines hidden (view full) --- 274 275 len += hex2u64(line + len, &size); 276 277 len++; 278 if (len + 2 >= line_len) 279 continue; 280 281 sym = symbol__new(start, size, line + len, |
354 self->sym_priv_size, v); | 282 self->sym_priv_size, start, v); |
355 356 if (sym == NULL) 357 goto out_delete_line; 358 | 283 284 if (sym == NULL) 285 goto out_delete_line; 286 |
359 if (filter && filter(map, sym)) | 287 if (filter && filter(self, sym)) |
360 symbol__delete(sym, self->sym_priv_size); 361 else { 362 dso__insert_symbol(self, sym); 363 nr_syms++; 364 } 365 } 366 367 free(line); --- 23 unchanged lines hidden (view full) --- 391{ 392 return GELF_ST_TYPE(sym->st_info); 393} 394 395static inline int elf_sym__is_function(const GElf_Sym *sym) 396{ 397 return elf_sym__type(sym) == STT_FUNC && 398 sym->st_name != 0 && | 288 symbol__delete(sym, self->sym_priv_size); 289 else { 290 dso__insert_symbol(self, sym); 291 nr_syms++; 292 } 293 } 294 295 free(line); --- 23 unchanged lines hidden (view full) --- 319{ 320 return GELF_ST_TYPE(sym->st_info); 321} 322 323static inline int elf_sym__is_function(const GElf_Sym *sym) 324{ 325 return elf_sym__type(sym) == STT_FUNC && 326 sym->st_name != 0 && |
399 sym->st_shndx != SHN_UNDEF && 400 sym->st_size != 0; | 327 sym->st_shndx != SHN_UNDEF; |
401} 402 403static inline int elf_sym__is_label(const GElf_Sym *sym) 404{ 405 return elf_sym__type(sym) == STT_NOTYPE && 406 sym->st_name != 0 && 407 sym->st_shndx != SHN_UNDEF && 408 sym->st_shndx != SHN_ABS; --- 68 unchanged lines hidden (view full) --- 477 Elf_Data *reldata, *syms, *symstrs; 478 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 479 size_t dynsym_idx; 480 GElf_Ehdr ehdr; 481 char sympltname[1024]; 482 Elf *elf; 483 int nr = 0, symidx, fd, err = 0; 484 | 328} 329 330static inline int elf_sym__is_label(const GElf_Sym *sym) 331{ 332 return elf_sym__type(sym) == STT_NOTYPE && 333 sym->st_name != 0 && 334 sym->st_shndx != SHN_UNDEF && 335 sym->st_shndx != SHN_ABS; --- 68 unchanged lines hidden (view full) --- 404 Elf_Data *reldata, *syms, *symstrs; 405 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 406 size_t dynsym_idx; 407 GElf_Ehdr ehdr; 408 char sympltname[1024]; 409 Elf *elf; 410 int nr = 0, symidx, fd, err = 0; 411 |
485 fd = open(self->long_name, O_RDONLY); | 412 fd = open(self->name, O_RDONLY); |
486 if (fd < 0) 487 goto out; 488 489 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 490 if (elf == NULL) 491 goto out_close; 492 493 if (gelf_getehdr(elf, &ehdr) == NULL) --- 51 unchanged lines hidden (view full) --- 545 nr_rel_entries) { 546 symidx = GELF_R_SYM(pos->r_info); 547 plt_offset += shdr_plt.sh_entsize; 548 gelf_getsym(syms, symidx, &sym); 549 snprintf(sympltname, sizeof(sympltname), 550 "%s@plt", elf_sym__name(&sym, symstrs)); 551 552 f = symbol__new(plt_offset, shdr_plt.sh_entsize, | 413 if (fd < 0) 414 goto out; 415 416 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 417 if (elf == NULL) 418 goto out_close; 419 420 if (gelf_getehdr(elf, &ehdr) == NULL) --- 51 unchanged lines hidden (view full) --- 472 nr_rel_entries) { 473 symidx = GELF_R_SYM(pos->r_info); 474 plt_offset += shdr_plt.sh_entsize; 475 gelf_getsym(syms, symidx, &sym); 476 snprintf(sympltname, sizeof(sympltname), 477 "%s@plt", elf_sym__name(&sym, symstrs)); 478 479 f = symbol__new(plt_offset, shdr_plt.sh_entsize, |
553 sympltname, self->sym_priv_size, v); | 480 sympltname, self->sym_priv_size, 0, v); |
554 if (!f) 555 goto out_elf_end; 556 557 dso__insert_symbol(self, f); 558 ++nr; 559 } 560 } else if (shdr_rel_plt.sh_type == SHT_REL) { 561 GElf_Rel pos_mem, *pos; 562 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 563 nr_rel_entries) { 564 symidx = GELF_R_SYM(pos->r_info); 565 plt_offset += shdr_plt.sh_entsize; 566 gelf_getsym(syms, symidx, &sym); 567 snprintf(sympltname, sizeof(sympltname), 568 "%s@plt", elf_sym__name(&sym, symstrs)); 569 570 f = symbol__new(plt_offset, shdr_plt.sh_entsize, | 481 if (!f) 482 goto out_elf_end; 483 484 dso__insert_symbol(self, f); 485 ++nr; 486 } 487 } else if (shdr_rel_plt.sh_type == SHT_REL) { 488 GElf_Rel pos_mem, *pos; 489 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 490 nr_rel_entries) { 491 symidx = GELF_R_SYM(pos->r_info); 492 plt_offset += shdr_plt.sh_entsize; 493 gelf_getsym(syms, symidx, &sym); 494 snprintf(sympltname, sizeof(sympltname), 495 "%s@plt", elf_sym__name(&sym, symstrs)); 496 497 f = symbol__new(plt_offset, shdr_plt.sh_entsize, |
571 sympltname, self->sym_priv_size, v); | 498 sympltname, self->sym_priv_size, 0, v); |
572 if (!f) 573 goto out_elf_end; 574 575 dso__insert_symbol(self, f); 576 ++nr; 577 } 578 } 579 580 err = 0; 581out_elf_end: 582 elf_end(elf); 583out_close: 584 close(fd); 585 586 if (err == 0) 587 return nr; 588out: 589 fprintf(stderr, "%s: problems reading %s PLT info.\n", | 499 if (!f) 500 goto out_elf_end; 501 502 dso__insert_symbol(self, f); 503 ++nr; 504 } 505 } 506 507 err = 0; 508out_elf_end: 509 elf_end(elf); 510out_close: 511 close(fd); 512 513 if (err == 0) 514 return nr; 515out: 516 fprintf(stderr, "%s: problems reading %s PLT info.\n", |
590 __func__, self->long_name); | 517 __func__, self->name); |
591 return 0; 592} 593 | 518 return 0; 519} 520 |
594static int dso__load_sym(struct dso *self, struct map *map, const char *name, 595 int fd, symbol_filter_t filter, int kernel, 596 int kmodule, int v) | 521static int dso__load_sym(struct dso *self, int fd, const char *name, 522 symbol_filter_t filter, int v, struct module *mod) |
597{ 598 Elf_Data *symstrs, *secstrs; 599 uint32_t nr_syms; 600 int err = -1; 601 uint32_t idx; 602 GElf_Ehdr ehdr; 603 GElf_Shdr shdr; 604 Elf_Data *syms; 605 GElf_Sym sym; 606 Elf_Scn *sec, *sec_strndx; 607 Elf *elf; | 523{ 524 Elf_Data *symstrs, *secstrs; 525 uint32_t nr_syms; 526 int err = -1; 527 uint32_t idx; 528 GElf_Ehdr ehdr; 529 GElf_Shdr shdr; 530 Elf_Data *syms; 531 GElf_Sym sym; 532 Elf_Scn *sec, *sec_strndx; 533 Elf *elf; |
608 int nr = 0; | 534 int nr = 0, kernel = !strcmp("[kernel]", self->name); |
609 610 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 611 if (elf == NULL) { 612 if (v) 613 fprintf(stderr, "%s: cannot read %s ELF file.\n", 614 __func__, name); 615 goto out_close; 616 } --- 40 unchanged lines hidden (view full) --- 657 ".gnu.prelink_undo", 658 NULL) != NULL); 659 } else self->adjust_symbols = 0; 660 661 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 662 struct symbol *f; 663 const char *elf_name; 664 char *demangled; | 535 536 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 537 if (elf == NULL) { 538 if (v) 539 fprintf(stderr, "%s: cannot read %s ELF file.\n", 540 __func__, name); 541 goto out_close; 542 } --- 40 unchanged lines hidden (view full) --- 583 ".gnu.prelink_undo", 584 NULL) != NULL); 585 } else self->adjust_symbols = 0; 586 587 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 588 struct symbol *f; 589 const char *elf_name; 590 char *demangled; |
591 u64 obj_start; 592 struct section *section = NULL; |
|
665 int is_label = elf_sym__is_label(&sym); 666 const char *section_name; | 593 int is_label = elf_sym__is_label(&sym); 594 const char *section_name; |
667 u64 sh_offset = 0; | |
668 669 if (!is_label && !elf_sym__is_function(&sym)) 670 continue; 671 672 sec = elf_getscn(elf, sym.st_shndx); 673 if (!sec) 674 goto out_elf_end; 675 676 gelf_getshdr(sec, &shdr); 677 678 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 679 continue; 680 681 section_name = elf_sec__name(&shdr, secstrs); | 595 596 if (!is_label && !elf_sym__is_function(&sym)) 597 continue; 598 599 sec = elf_getscn(elf, sym.st_shndx); 600 if (!sec) 601 goto out_elf_end; 602 603 gelf_getshdr(sec, &shdr); 604 605 if (is_label && !elf_sec__is_text(&shdr, secstrs)) 606 continue; 607 608 section_name = elf_sec__name(&shdr, secstrs); |
609 obj_start = sym.st_value; |
|
682 | 610 |
683 if ((kernel || kmodule)) { 684 if (strstr(section_name, ".init")) 685 sh_offset = shdr.sh_offset; 686 } 687 | |
688 if (self->adjust_symbols) { 689 if (v >= 2) 690 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 691 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 692 693 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 694 } | 611 if (self->adjust_symbols) { 612 if (v >= 2) 613 printf("adjusting symbol: st_value: %Lx sh_addr: %Lx sh_offset: %Lx\n", 614 (u64)sym.st_value, (u64)shdr.sh_addr, (u64)shdr.sh_offset); 615 616 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 617 } |
618 619 if (mod) { 620 section = mod->sections->find_section(mod->sections, section_name); 621 if (section) 622 sym.st_value += section->vma; 623 else { 624 fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n", 625 mod->name, section_name); 626 goto out_elf_end; 627 } 628 } |
|
695 /* 696 * We need to figure out if the object was created from C++ sources 697 * DWARF DW_compile_unit has this, but we don't always have access 698 * to it... 699 */ 700 elf_name = elf_sym__name(&sym, symstrs); 701 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 702 if (demangled != NULL) 703 elf_name = demangled; 704 | 629 /* 630 * We need to figure out if the object was created from C++ sources 631 * DWARF DW_compile_unit has this, but we don't always have access 632 * to it... 633 */ 634 elf_name = elf_sym__name(&sym, symstrs); 635 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 636 if (demangled != NULL) 637 elf_name = demangled; 638 |
705 f = symbol__new(sym.st_value + sh_offset, sym.st_size, elf_name, 706 self->sym_priv_size, v); | 639 f = symbol__new(sym.st_value, sym.st_size, elf_name, 640 self->sym_priv_size, obj_start, v); |
707 free(demangled); 708 if (!f) 709 goto out_elf_end; 710 | 641 free(demangled); 642 if (!f) 643 goto out_elf_end; 644 |
711 if (filter && filter(map, f)) | 645 if (filter && filter(self, f)) |
712 symbol__delete(f, self->sym_priv_size); 713 else { | 646 symbol__delete(f, self->sym_priv_size); 647 else { |
648 f->module = mod; |
|
714 dso__insert_symbol(self, f); 715 nr++; 716 } 717 } 718 719 err = nr; 720out_elf_end: 721 elf_end(elf); --- 8 unchanged lines hidden (view full) --- 730 int i; 731 GElf_Ehdr ehdr; 732 GElf_Shdr shdr; 733 Elf_Data *build_id_data; 734 Elf_Scn *sec; 735 char *build_id = NULL, *bid; 736 unsigned char *raw; 737 Elf *elf; | 649 dso__insert_symbol(self, f); 650 nr++; 651 } 652 } 653 654 err = nr; 655out_elf_end: 656 elf_end(elf); --- 8 unchanged lines hidden (view full) --- 665 int i; 666 GElf_Ehdr ehdr; 667 GElf_Shdr shdr; 668 Elf_Data *build_id_data; 669 Elf_Scn *sec; 670 char *build_id = NULL, *bid; 671 unsigned char *raw; 672 Elf *elf; |
738 int fd = open(self->long_name, O_RDONLY); | 673 int fd = open(self->name, O_RDONLY); |
739 740 if (fd < 0) 741 goto out; 742 743 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 744 if (elf == NULL) { 745 if (v) 746 fprintf(stderr, "%s: cannot read %s ELF file.\n", | 674 675 if (fd < 0) 676 goto out; 677 678 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 679 if (elf == NULL) { 680 if (v) 681 fprintf(stderr, "%s: cannot read %s ELF file.\n", |
747 __func__, self->long_name); | 682 __func__, self->name); |
748 goto out_close; 749 } 750 751 if (gelf_getehdr(elf, &ehdr) == NULL) { 752 if (v) 753 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 754 goto out_elf_end; 755 } --- 12 unchanged lines hidden (view full) --- 768 bid = build_id; 769 770 for (i = 0; i < 20; ++i) { 771 sprintf(bid, "%02x", *raw); 772 ++raw; 773 bid += 2; 774 } 775 if (v >= 2) | 683 goto out_close; 684 } 685 686 if (gelf_getehdr(elf, &ehdr) == NULL) { 687 if (v) 688 fprintf(stderr, "%s: cannot get elf header.\n", __func__); 689 goto out_elf_end; 690 } --- 12 unchanged lines hidden (view full) --- 703 bid = build_id; 704 705 for (i = 0; i < 20; ++i) { 706 sprintf(bid, "%02x", *raw); 707 ++raw; 708 bid += 2; 709 } 710 if (v >= 2) |
776 printf("%s(%s): %s\n", __func__, self->long_name, build_id); | 711 printf("%s(%s): %s\n", __func__, self->name, build_id); |
777out_elf_end: 778 elf_end(elf); 779out_close: 780 close(fd); 781out: 782 return build_id; 783} 784 785char dso__symtab_origin(const struct dso *self) 786{ 787 static const char origin[] = { 788 [DSO__ORIG_KERNEL] = 'k', 789 [DSO__ORIG_JAVA_JIT] = 'j', 790 [DSO__ORIG_FEDORA] = 'f', 791 [DSO__ORIG_UBUNTU] = 'u', 792 [DSO__ORIG_BUILDID] = 'b', 793 [DSO__ORIG_DSO] = 'd', | 712out_elf_end: 713 elf_end(elf); 714out_close: 715 close(fd); 716out: 717 return build_id; 718} 719 720char dso__symtab_origin(const struct dso *self) 721{ 722 static const char origin[] = { 723 [DSO__ORIG_KERNEL] = 'k', 724 [DSO__ORIG_JAVA_JIT] = 'j', 725 [DSO__ORIG_FEDORA] = 'f', 726 [DSO__ORIG_UBUNTU] = 'u', 727 [DSO__ORIG_BUILDID] = 'b', 728 [DSO__ORIG_DSO] = 'd', |
794 [DSO__ORIG_KMODULE] = 'K', | |
795 }; 796 797 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 798 return '!'; 799 return origin[self->origin]; 800} 801 | 729 }; 730 731 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND) 732 return '!'; 733 return origin[self->origin]; 734} 735 |
802int dso__load(struct dso *self, struct map *map, symbol_filter_t filter, int v) | 736int dso__load(struct dso *self, symbol_filter_t filter, int v) |
803{ 804 int size = PATH_MAX; 805 char *name = malloc(size), *build_id = NULL; 806 int ret = -1; 807 int fd; 808 809 if (!name) 810 return -1; 811 812 self->adjust_symbols = 0; 813 814 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { | 737{ 738 int size = PATH_MAX; 739 char *name = malloc(size), *build_id = NULL; 740 int ret = -1; 741 int fd; 742 743 if (!name) 744 return -1; 745 746 self->adjust_symbols = 0; 747 748 if (strncmp(self->name, "/tmp/perf-", 10) == 0) { |
815 ret = dso__load_perf_map(self, map, filter, v); | 749 ret = dso__load_perf_map(self, filter, v); |
816 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 817 DSO__ORIG_NOT_FOUND; 818 return ret; 819 } 820 821 self->origin = DSO__ORIG_FEDORA - 1; 822 823more: 824 do { 825 self->origin++; 826 switch (self->origin) { 827 case DSO__ORIG_FEDORA: | 750 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT : 751 DSO__ORIG_NOT_FOUND; 752 return ret; 753 } 754 755 self->origin = DSO__ORIG_FEDORA - 1; 756 757more: 758 do { 759 self->origin++; 760 switch (self->origin) { 761 case DSO__ORIG_FEDORA: |
828 snprintf(name, size, "/usr/lib/debug%s.debug", 829 self->long_name); | 762 snprintf(name, size, "/usr/lib/debug%s.debug", self->name); |
830 break; 831 case DSO__ORIG_UBUNTU: | 763 break; 764 case DSO__ORIG_UBUNTU: |
832 snprintf(name, size, "/usr/lib/debug%s", 833 self->long_name); | 765 snprintf(name, size, "/usr/lib/debug%s", self->name); |
834 break; 835 case DSO__ORIG_BUILDID: 836 build_id = dso__read_build_id(self, v); 837 if (build_id != NULL) { 838 snprintf(name, size, 839 "/usr/lib/debug/.build-id/%.2s/%s.debug", 840 build_id, build_id + 2); 841 free(build_id); 842 break; 843 } 844 self->origin++; 845 /* Fall thru */ 846 case DSO__ORIG_DSO: | 766 break; 767 case DSO__ORIG_BUILDID: 768 build_id = dso__read_build_id(self, v); 769 if (build_id != NULL) { 770 snprintf(name, size, 771 "/usr/lib/debug/.build-id/%.2s/%s.debug", 772 build_id, build_id + 2); 773 free(build_id); 774 break; 775 } 776 self->origin++; 777 /* Fall thru */ 778 case DSO__ORIG_DSO: |
847 snprintf(name, size, "%s", self->long_name); | 779 snprintf(name, size, "%s", self->name); |
848 break; 849 850 default: 851 goto out; 852 } 853 854 fd = open(name, O_RDONLY); 855 } while (fd < 0); 856 | 780 break; 781 782 default: 783 goto out; 784 } 785 786 fd = open(name, O_RDONLY); 787 } while (fd < 0); 788 |
857 ret = dso__load_sym(self, map, name, fd, filter, 0, 0, v); | 789 ret = dso__load_sym(self, fd, name, filter, v, NULL); |
858 close(fd); 859 860 /* 861 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 862 */ 863 if (!ret) 864 goto more; 865 --- 4 unchanged lines hidden (view full) --- 870 } 871out: 872 free(name); 873 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 874 return 0; 875 return ret; 876} 877 | 790 close(fd); 791 792 /* 793 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!? 794 */ 795 if (!ret) 796 goto more; 797 --- 4 unchanged lines hidden (view full) --- 802 } 803out: 804 free(name); 805 if (ret < 0 && strstr(self->name, " (deleted)") != NULL) 806 return 0; 807 return ret; 808} 809 |
878struct map *kernel_map; 879 880static void kernel_maps__insert(struct map *map) | 810static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, 811 symbol_filter_t filter, int v) |
881{ | 812{ |
882 maps__insert(&kernel_maps, map); 883} | 813 struct module *mod = mod_dso__find_module(mods, name); 814 int err = 0, fd; |
884 | 815 |
885struct symbol *kernel_maps__find_symbol(u64 ip, struct map **mapp) 886{ 887 /* 888 * We can't have kernel_map in kernel_maps because it spans an address 889 * space that includes the modules. The right way to fix this is to 890 * create several maps, so that we don't have overlapping ranges with 891 * modules. For now lets look first on the kernel dso. 892 */ 893 struct map *map = maps__find(&kernel_maps, ip); 894 struct symbol *sym; | 816 if (mod == NULL || !mod->active) 817 return err; |
895 | 818 |
896 if (map) { 897 ip = map->map_ip(map, ip); 898 sym = map->dso->find_symbol(map->dso, ip); 899 } else { 900 map = kernel_map; 901 sym = map->dso->find_symbol(map->dso, ip); 902 } | 819 fd = open(mod->path, O_RDONLY); |
903 | 820 |
904 if (mapp) 905 *mapp = map; 906 907 return sym; 908} 909 910struct map *kernel_maps__find_by_dso_name(const char *name) 911{ 912 struct rb_node *nd; 913 914 for (nd = rb_first(&kernel_maps); nd; nd = rb_next(nd)) { 915 struct map *map = rb_entry(nd, struct map, rb_node); 916 917 if (map->dso && strcmp(map->dso->name, name) == 0) 918 return map; 919 } 920 921 return NULL; 922} 923 924static int dso__load_module_sym(struct dso *self, struct map *map, 925 symbol_filter_t filter, int v) 926{ 927 int err = 0, fd = open(self->long_name, O_RDONLY); 928 929 if (fd < 0) { 930 if (v) 931 fprintf(stderr, "%s: cannot open %s\n", 932 __func__, self->long_name); | 821 if (fd < 0) |
933 return err; | 822 return err; |
934 } | |
935 | 823 |
936 err = dso__load_sym(self, map, self->long_name, fd, filter, 0, 1, v); | 824 err = dso__load_sym(self, fd, name, filter, v, mod); |
937 close(fd); 938 939 return err; 940} 941 | 825 close(fd); 826 827 return err; 828} 829 |
942static int dsos__load_modules_sym_dir(char *dirname, 943 symbol_filter_t filter, int v) | 830int dso__load_modules(struct dso *self, symbol_filter_t filter, int v) |
944{ | 831{ |
945 struct dirent *dent; 946 int nr_symbols = 0, err; 947 DIR *dir = opendir(dirname); | 832 struct mod_dso *mods = mod_dso__new_dso("modules"); 833 struct module *pos; 834 struct rb_node *next; 835 int err, count = 0; |
948 | 836 |
949 if (!dir) { 950 if (v) 951 fprintf(stderr, "%s: cannot open %s dir\n", __func__, 952 dirname); 953 return -1; 954 } | 837 err = mod_dso__load_modules(mods); |
955 | 838 |
956 while ((dent = readdir(dir)) != NULL) { 957 char path[PATH_MAX]; | 839 if (err <= 0) 840 return err; |
958 | 841 |
959 if (dent->d_type == DT_DIR) { 960 if (!strcmp(dent->d_name, ".") || 961 !strcmp(dent->d_name, "..")) 962 continue; | 842 /* 843 * Iterate over modules, and load active symbols. 844 */ 845 next = rb_first(&mods->mods); 846 while (next) { 847 pos = rb_entry(next, struct module, rb_node); 848 err = dso__load_module(self, mods, pos->name, filter, v); |
963 | 849 |
964 snprintf(path, sizeof(path), "%s/%s", 965 dirname, dent->d_name); 966 err = dsos__load_modules_sym_dir(path, filter, v); 967 if (err < 0) 968 goto failure; 969 } else { 970 char *dot = strrchr(dent->d_name, '.'), 971 dso_name[PATH_MAX]; 972 struct map *map; 973 struct rb_node *last; | 850 if (err < 0) 851 break; |
974 | 852 |
975 if (dot == NULL || strcmp(dot, ".ko")) 976 continue; 977 snprintf(dso_name, sizeof(dso_name), "[%.*s]", 978 (int)(dot - dent->d_name), dent->d_name); | 853 next = rb_next(&pos->rb_node); 854 count += err; 855 } |
979 | 856 |
980 strxfrchar(dso_name, '-', '_'); 981 map = kernel_maps__find_by_dso_name(dso_name); 982 if (map == NULL) 983 continue; 984 985 snprintf(path, sizeof(path), "%s/%s", 986 dirname, dent->d_name); 987 988 map->dso->long_name = strdup(path); 989 if (map->dso->long_name == NULL) 990 goto failure; 991 992 err = dso__load_module_sym(map->dso, map, filter, v); 993 if (err < 0) 994 goto failure; 995 last = rb_last(&map->dso->syms); 996 if (last) { 997 struct symbol *sym; 998 sym = rb_entry(last, struct symbol, rb_node); 999 map->end = map->start + sym->end; 1000 } 1001 } 1002 nr_symbols += err; | 857 if (err < 0) { 858 mod_dso__delete_modules(mods); 859 mod_dso__delete_self(mods); 860 return err; |
1003 } 1004 | 861 } 862 |
1005 return nr_symbols; 1006failure: 1007 closedir(dir); 1008 return -1; | 863 return count; |
1009} 1010 | 864} 865 |
1011static int dsos__load_modules_sym(symbol_filter_t filter, int v) | 866static inline void dso__fill_symbol_holes(struct dso *self) |
1012{ | 867{ |
1013 struct utsname uts; 1014 char modules_path[PATH_MAX]; | 868 struct symbol *prev = NULL; 869 struct rb_node *nd; |
1015 | 870 |
1016 if (uname(&uts) < 0) 1017 return -1; | 871 for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { 872 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
1018 | 873 |
1019 snprintf(modules_path, sizeof(modules_path), "/lib/modules/%s/kernel", 1020 uts.release); | 874 if (prev) { 875 u64 hole = 0; 876 int alias = pos->start == prev->start; |
1021 | 877 |
1022 return dsos__load_modules_sym_dir(modules_path, filter, v); 1023} | 878 if (!alias) 879 hole = prev->start - pos->end - 1; |
1024 | 880 |
1025/* 1026 * Constructor variant for modules (where we know from /proc/modules where 1027 * they are loaded) and for vmlinux, where only after we load all the 1028 * symbols we'll know where it starts and ends. 1029 */ 1030static struct map *map__new2(u64 start, struct dso *dso) 1031{ 1032 struct map *self = malloc(sizeof(*self)); 1033 1034 if (self != NULL) { 1035 self->start = start; 1036 /* 1037 * Will be filled after we load all the symbols 1038 */ 1039 self->end = 0; 1040 1041 self->pgoff = 0; 1042 self->dso = dso; 1043 self->map_ip = map__map_ip; 1044 RB_CLEAR_NODE(&self->rb_node); 1045 } 1046 return self; 1047} 1048 1049static int dsos__load_modules(unsigned int sym_priv_size) 1050{ 1051 char *line = NULL; 1052 size_t n; 1053 FILE *file = fopen("/proc/modules", "r"); 1054 struct map *map; 1055 1056 if (file == NULL) 1057 return -1; 1058 1059 while (!feof(file)) { 1060 char name[PATH_MAX]; 1061 u64 start; 1062 struct dso *dso; 1063 char *sep; 1064 int line_len; 1065 1066 line_len = getline(&line, &n, file); 1067 if (line_len < 0) 1068 break; 1069 1070 if (!line) 1071 goto out_failure; 1072 1073 line[--line_len] = '\0'; /* \n */ 1074 1075 sep = strrchr(line, 'x'); 1076 if (sep == NULL) 1077 continue; 1078 1079 hex2u64(sep + 1, &start); 1080 1081 sep = strchr(line, ' '); 1082 if (sep == NULL) 1083 continue; 1084 1085 *sep = '\0'; 1086 1087 snprintf(name, sizeof(name), "[%s]", line); 1088 dso = dso__new(name, sym_priv_size); 1089 1090 if (dso == NULL) 1091 goto out_delete_line; 1092 1093 map = map__new2(start, dso); 1094 if (map == NULL) { 1095 dso__delete(dso); 1096 goto out_delete_line; | 881 if (hole || alias) { 882 if (alias) 883 pos->end = prev->end; 884 else if (hole) 885 pos->end = prev->start - 1; 886 } |
1097 } | 887 } |
1098 1099 dso->origin = DSO__ORIG_KMODULE; 1100 kernel_maps__insert(map); 1101 dsos__add(dso); | 888 prev = pos; |
1102 } | 889 } |
1103 1104 free(line); 1105 fclose(file); 1106 1107 return 0; 1108 1109out_delete_line: 1110 free(line); 1111out_failure: 1112 return -1; | |
1113} 1114 | 890} 891 |
1115static int dso__load_vmlinux(struct dso *self, struct map *map, 1116 const char *vmlinux, | 892static int dso__load_vmlinux(struct dso *self, const char *vmlinux, |
1117 symbol_filter_t filter, int v) 1118{ 1119 int err, fd = open(vmlinux, O_RDONLY); 1120 1121 if (fd < 0) 1122 return -1; 1123 | 893 symbol_filter_t filter, int v) 894{ 895 int err, fd = open(vmlinux, O_RDONLY); 896 897 if (fd < 0) 898 return -1; 899 |
1124 err = dso__load_sym(self, map, self->long_name, fd, filter, 1, 0, v); | 900 err = dso__load_sym(self, fd, vmlinux, filter, v, NULL); |
1125 | 901 |
902 if (err > 0) 903 dso__fill_symbol_holes(self); 904 |
|
1126 close(fd); 1127 1128 return err; 1129} 1130 | 905 close(fd); 906 907 return err; 908} 909 |
1131int dsos__load_kernel(const char *vmlinux, unsigned int sym_priv_size, 1132 symbol_filter_t filter, int v, int use_modules) | 910int dso__load_kernel(struct dso *self, const char *vmlinux, 911 symbol_filter_t filter, int v, int use_modules) |
1133{ 1134 int err = -1; | 912{ 913 int err = -1; |
1135 struct dso *dso = dso__new(vmlinux, sym_priv_size); | |
1136 | 914 |
1137 if (dso == NULL) 1138 return -1; 1139 1140 dso->short_name = "[kernel]"; 1141 kernel_map = map__new2(0, dso); 1142 if (kernel_map == NULL) 1143 goto out_delete_dso; 1144 1145 kernel_map->map_ip = vdso__map_ip; 1146 1147 if (use_modules && dsos__load_modules(sym_priv_size) < 0) { 1148 fprintf(stderr, "Failed to load list of modules in use! " 1149 "Continuing...\n"); 1150 use_modules = 0; 1151 } 1152 | |
1153 if (vmlinux) { | 915 if (vmlinux) { |
1154 err = dso__load_vmlinux(dso, kernel_map, vmlinux, filter, v); | 916 err = dso__load_vmlinux(self, vmlinux, filter, v); |
1155 if (err > 0 && use_modules) { | 917 if (err > 0 && use_modules) { |
1156 int syms = dsos__load_modules_sym(filter, v); | 918 int syms = dso__load_modules(self, filter, v); |
1157 | 919 |
1158 if (syms < 0) 1159 fprintf(stderr, "Failed to read module symbols!" 1160 " Continuing...\n"); 1161 else 1162 err += syms; | 920 if (syms < 0) { 921 fprintf(stderr, "dso__load_modules failed!\n"); 922 return syms; 923 } 924 err += syms; |
1163 } 1164 } 1165 1166 if (err <= 0) | 925 } 926 } 927 928 if (err <= 0) |
1167 err = maps__load_kallsyms(filter, use_modules, v); | 929 err = dso__load_kallsyms(self, filter, v); |
1168 | 930 |
1169 if (err > 0) { 1170 struct rb_node *node = rb_first(&dso->syms); 1171 struct symbol *sym = rb_entry(node, struct symbol, rb_node); 1172 /* 1173 * Now that we have all sorted out, just set the ->end of all 1174 * symbols that still don't have it. 1175 */ 1176 dso__set_symbols_end(dso); 1177 kernel_maps__fixup_sym_end(); | 931 if (err > 0) 932 self->origin = DSO__ORIG_KERNEL; |
1178 | 933 |
1179 kernel_map->start = sym->start; 1180 node = rb_last(&dso->syms); 1181 sym = rb_entry(node, struct symbol, rb_node); 1182 kernel_map->end = sym->end; 1183 1184 dso->origin = DSO__ORIG_KERNEL; 1185 /* 1186 * XXX See kernel_maps__find_symbol comment 1187 * kernel_maps__insert(kernel_map) 1188 */ 1189 dsos__add(dso); 1190 1191 if (v > 0) 1192 kernel_maps__fprintf(stderr); 1193 } 1194 | |
1195 return err; | 934 return err; |
1196 1197out_delete_dso: 1198 dso__delete(dso); 1199 return -1; | |
1200} 1201 1202LIST_HEAD(dsos); | 935} 936 937LIST_HEAD(dsos); |
938struct dso *kernel_dso; |
|
1203struct dso *vdso; | 939struct dso *vdso; |
940struct dso *hypervisor_dso; |
|
1204 1205const char *vmlinux_name = "vmlinux"; 1206int modules; 1207 1208static void dsos__add(struct dso *dso) 1209{ 1210 list_add_tail(&dso->node, &dsos); 1211} --- 15 unchanged lines hidden (view full) --- 1227 1228 if (dso) 1229 return dso; 1230 1231 dso = dso__new(name, 0); 1232 if (!dso) 1233 goto out_delete_dso; 1234 | 941 942const char *vmlinux_name = "vmlinux"; 943int modules; 944 945static void dsos__add(struct dso *dso) 946{ 947 list_add_tail(&dso->node, &dsos); 948} --- 15 unchanged lines hidden (view full) --- 964 965 if (dso) 966 return dso; 967 968 dso = dso__new(name, 0); 969 if (!dso) 970 goto out_delete_dso; 971 |
1235 nr = dso__load(dso, NULL, NULL, verbose); | 972 nr = dso__load(dso, NULL, verbose); |
1236 if (nr < 0) { 1237 eprintf("Failed to open: %s\n", name); 1238 goto out_delete_dso; 1239 } 1240 if (!nr) 1241 eprintf("No symbols found in: %s, maybe install a debug package?\n", name); 1242 1243 dsos__add(dso); --- 8 unchanged lines hidden (view full) --- 1252void dsos__fprintf(FILE *fp) 1253{ 1254 struct dso *pos; 1255 1256 list_for_each_entry(pos, &dsos, node) 1257 dso__fprintf(pos, fp); 1258} 1259 | 973 if (nr < 0) { 974 eprintf("Failed to open: %s\n", name); 975 goto out_delete_dso; 976 } 977 if (!nr) 978 eprintf("No symbols found in: %s, maybe install a debug package?\n", name); 979 980 dsos__add(dso); --- 8 unchanged lines hidden (view full) --- 989void dsos__fprintf(FILE *fp) 990{ 991 struct dso *pos; 992 993 list_for_each_entry(pos, &dsos, node) 994 dso__fprintf(pos, fp); 995} 996 |
997static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) 998{ 999 return dso__find_symbol(dso, ip); 1000} 1001 |
|
1260int load_kernel(void) 1261{ | 1002int load_kernel(void) 1003{ |
1262 if (dsos__load_kernel(vmlinux_name, 0, NULL, verbose, modules) <= 0) | 1004 int err; 1005 1006 kernel_dso = dso__new("[kernel]", 0); 1007 if (!kernel_dso) |
1263 return -1; 1264 | 1008 return -1; 1009 |
1010 err = dso__load_kernel(kernel_dso, vmlinux_name, NULL, verbose, modules); 1011 if (err <= 0) { 1012 dso__delete(kernel_dso); 1013 kernel_dso = NULL; 1014 } else 1015 dsos__add(kernel_dso); 1016 |
|
1265 vdso = dso__new("[vdso]", 0); 1266 if (!vdso) 1267 return -1; 1268 | 1017 vdso = dso__new("[vdso]", 0); 1018 if (!vdso) 1019 return -1; 1020 |
1021 vdso->find_symbol = vdso__find_symbol; 1022 |
|
1269 dsos__add(vdso); 1270 | 1023 dsos__add(vdso); 1024 |
1271 return 0; | 1025 hypervisor_dso = dso__new("[hypervisor]", 0); 1026 if (!hypervisor_dso) 1027 return -1; 1028 dsos__add(hypervisor_dso); 1029 1030 return err; |
1272} 1273 | 1031} 1032 |
1033 |
|
1274void symbol__init(void) 1275{ 1276 elf_version(EV_CURRENT); 1277} | 1034void symbol__init(void) 1035{ 1036 elf_version(EV_CURRENT); 1037} |