| .. | .. |
|---|
| 4 | 4 | #include <stdlib.h> |
|---|
| 5 | 5 | #include <stdio.h> |
|---|
| 6 | 6 | #include <string.h> |
|---|
| 7 | +#include <linux/capability.h> |
|---|
| 7 | 8 | #include <linux/kernel.h> |
|---|
| 8 | 9 | #include <linux/mman.h> |
|---|
| 10 | +#include <linux/string.h> |
|---|
| 11 | +#include <linux/time64.h> |
|---|
| 9 | 12 | #include <sys/types.h> |
|---|
| 10 | 13 | #include <sys/stat.h> |
|---|
| 11 | 14 | #include <sys/param.h> |
|---|
| .. | .. |
|---|
| 14 | 17 | #include <inttypes.h> |
|---|
| 15 | 18 | #include "annotate.h" |
|---|
| 16 | 19 | #include "build-id.h" |
|---|
| 17 | | -#include "util.h" |
|---|
| 20 | +#include "cap.h" |
|---|
| 21 | +#include "dso.h" |
|---|
| 22 | +#include "util.h" // lsdir() |
|---|
| 18 | 23 | #include "debug.h" |
|---|
| 24 | +#include "event.h" |
|---|
| 19 | 25 | #include "machine.h" |
|---|
| 26 | +#include "map.h" |
|---|
| 20 | 27 | #include "symbol.h" |
|---|
| 28 | +#include "map_symbol.h" |
|---|
| 29 | +#include "mem-events.h" |
|---|
| 30 | +#include "symsrc.h" |
|---|
| 21 | 31 | #include "strlist.h" |
|---|
| 22 | 32 | #include "intlist.h" |
|---|
| 23 | 33 | #include "namespaces.h" |
|---|
| 24 | 34 | #include "header.h" |
|---|
| 25 | 35 | #include "path.h" |
|---|
| 26 | | -#include "sane_ctype.h" |
|---|
| 36 | +#include <linux/ctype.h> |
|---|
| 37 | +#include <linux/zalloc.h> |
|---|
| 27 | 38 | |
|---|
| 28 | 39 | #include <elf.h> |
|---|
| 29 | 40 | #include <limits.h> |
|---|
| .. | .. |
|---|
| 38 | 49 | char **vmlinux_path; |
|---|
| 39 | 50 | |
|---|
| 40 | 51 | struct symbol_conf symbol_conf = { |
|---|
| 52 | + .nanosecs = false, |
|---|
| 41 | 53 | .use_modules = true, |
|---|
| 42 | 54 | .try_vmlinux_path = true, |
|---|
| 43 | 55 | .demangle = true, |
|---|
| 44 | 56 | .demangle_kernel = false, |
|---|
| 45 | 57 | .cumulate_callchain = true, |
|---|
| 58 | + .time_quantum = 100 * NSEC_PER_MSEC, /* 100ms */ |
|---|
| 46 | 59 | .show_hist_headers = true, |
|---|
| 47 | 60 | .symfs = "", |
|---|
| 48 | 61 | .event_group = true, |
|---|
| 49 | 62 | .inline_name = true, |
|---|
| 63 | + .res_sample = 0, |
|---|
| 50 | 64 | }; |
|---|
| 51 | 65 | |
|---|
| 52 | 66 | static enum dso_binary_type binary_type_symtab[] = { |
|---|
| .. | .. |
|---|
| 85 | 99 | tail++; |
|---|
| 86 | 100 | |
|---|
| 87 | 101 | return tail - str; |
|---|
| 88 | | -} |
|---|
| 89 | | - |
|---|
| 90 | | -void __weak arch__symbols__fixup_end(struct symbol *p, struct symbol *c) |
|---|
| 91 | | -{ |
|---|
| 92 | | - p->end = c->start; |
|---|
| 93 | 102 | } |
|---|
| 94 | 103 | |
|---|
| 95 | 104 | const char * __weak arch__normalize_symbol_name(const char *name) |
|---|
| .. | .. |
|---|
| 169 | 178 | return arch__choose_best_symbol(syma, symb); |
|---|
| 170 | 179 | } |
|---|
| 171 | 180 | |
|---|
| 172 | | -void symbols__fixup_duplicate(struct rb_root *symbols) |
|---|
| 181 | +void symbols__fixup_duplicate(struct rb_root_cached *symbols) |
|---|
| 173 | 182 | { |
|---|
| 174 | 183 | struct rb_node *nd; |
|---|
| 175 | 184 | struct symbol *curr, *next; |
|---|
| .. | .. |
|---|
| 177 | 186 | if (symbol_conf.allow_aliases) |
|---|
| 178 | 187 | return; |
|---|
| 179 | 188 | |
|---|
| 180 | | - nd = rb_first(symbols); |
|---|
| 189 | + nd = rb_first_cached(symbols); |
|---|
| 181 | 190 | |
|---|
| 182 | 191 | while (nd) { |
|---|
| 183 | 192 | curr = rb_entry(nd, struct symbol, rb_node); |
|---|
| .. | .. |
|---|
| 192 | 201 | continue; |
|---|
| 193 | 202 | |
|---|
| 194 | 203 | if (choose_best_symbol(curr, next) == SYMBOL_A) { |
|---|
| 195 | | - rb_erase(&next->rb_node, symbols); |
|---|
| 204 | + rb_erase_cached(&next->rb_node, symbols); |
|---|
| 196 | 205 | symbol__delete(next); |
|---|
| 197 | 206 | goto again; |
|---|
| 198 | 207 | } else { |
|---|
| 199 | 208 | nd = rb_next(&curr->rb_node); |
|---|
| 200 | | - rb_erase(&curr->rb_node, symbols); |
|---|
| 209 | + rb_erase_cached(&curr->rb_node, symbols); |
|---|
| 201 | 210 | symbol__delete(curr); |
|---|
| 202 | 211 | } |
|---|
| 203 | 212 | } |
|---|
| 204 | 213 | } |
|---|
| 205 | 214 | |
|---|
| 206 | | -void symbols__fixup_end(struct rb_root *symbols) |
|---|
| 215 | +/* Update zero-sized symbols using the address of the next symbol */ |
|---|
| 216 | +void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms) |
|---|
| 207 | 217 | { |
|---|
| 208 | | - struct rb_node *nd, *prevnd = rb_first(symbols); |
|---|
| 218 | + struct rb_node *nd, *prevnd = rb_first_cached(symbols); |
|---|
| 209 | 219 | struct symbol *curr, *prev; |
|---|
| 210 | 220 | |
|---|
| 211 | 221 | if (prevnd == NULL) |
|---|
| .. | .. |
|---|
| 217 | 227 | prev = curr; |
|---|
| 218 | 228 | curr = rb_entry(nd, struct symbol, rb_node); |
|---|
| 219 | 229 | |
|---|
| 220 | | - if (prev->end == prev->start && prev->end != curr->start) |
|---|
| 221 | | - arch__symbols__fixup_end(prev, curr); |
|---|
| 230 | + /* |
|---|
| 231 | + * On some architecture kernel text segment start is located at |
|---|
| 232 | + * some low memory address, while modules are located at high |
|---|
| 233 | + * memory addresses (or vice versa). The gap between end of |
|---|
| 234 | + * kernel text segment and beginning of first module's text |
|---|
| 235 | + * segment is very big. Therefore do not fill this gap and do |
|---|
| 236 | + * not assign it to the kernel dso map (kallsyms). |
|---|
| 237 | + * |
|---|
| 238 | + * In kallsyms, it determines module symbols using '[' character |
|---|
| 239 | + * like in: |
|---|
| 240 | + * ffffffffc1937000 T hdmi_driver_init [snd_hda_codec_hdmi] |
|---|
| 241 | + */ |
|---|
| 242 | + if (prev->end == prev->start) { |
|---|
| 243 | + /* Last kernel/module symbol mapped to end of page */ |
|---|
| 244 | + if (is_kallsyms && (!strchr(prev->name, '[') != |
|---|
| 245 | + !strchr(curr->name, '['))) |
|---|
| 246 | + prev->end = roundup(prev->end + 4096, 4096); |
|---|
| 247 | + else |
|---|
| 248 | + prev->end = curr->start; |
|---|
| 249 | + |
|---|
| 250 | + pr_debug4("%s sym:%s end:%#" PRIx64 "\n", |
|---|
| 251 | + __func__, prev->name, prev->end); |
|---|
| 252 | + } |
|---|
| 222 | 253 | } |
|---|
| 223 | 254 | |
|---|
| 224 | 255 | /* Last entry */ |
|---|
| .. | .. |
|---|
| 226 | 257 | curr->end = roundup(curr->start, 4096) + 4096; |
|---|
| 227 | 258 | } |
|---|
| 228 | 259 | |
|---|
| 229 | | -void map_groups__fixup_end(struct map_groups *mg) |
|---|
| 260 | +void maps__fixup_end(struct maps *maps) |
|---|
| 230 | 261 | { |
|---|
| 231 | | - struct maps *maps = &mg->maps; |
|---|
| 232 | | - struct map *next, *curr; |
|---|
| 262 | + struct map *prev = NULL, *curr; |
|---|
| 233 | 263 | |
|---|
| 234 | 264 | down_write(&maps->lock); |
|---|
| 235 | 265 | |
|---|
| 236 | | - curr = maps__first(maps); |
|---|
| 237 | | - if (curr == NULL) |
|---|
| 238 | | - goto out_unlock; |
|---|
| 266 | + maps__for_each_entry(maps, curr) { |
|---|
| 267 | + if (prev != NULL && !prev->end) |
|---|
| 268 | + prev->end = curr->start; |
|---|
| 239 | 269 | |
|---|
| 240 | | - for (next = map__next(curr); next; next = map__next(curr)) { |
|---|
| 241 | | - if (!curr->end) |
|---|
| 242 | | - curr->end = next->start; |
|---|
| 243 | | - curr = next; |
|---|
| 270 | + prev = curr; |
|---|
| 244 | 271 | } |
|---|
| 245 | 272 | |
|---|
| 246 | 273 | /* |
|---|
| 247 | 274 | * We still haven't the actual symbols, so guess the |
|---|
| 248 | 275 | * last map final address. |
|---|
| 249 | 276 | */ |
|---|
| 250 | | - if (!curr->end) |
|---|
| 277 | + if (curr && !curr->end) |
|---|
| 251 | 278 | curr->end = ~0ULL; |
|---|
| 252 | 279 | |
|---|
| 253 | | -out_unlock: |
|---|
| 254 | 280 | up_write(&maps->lock); |
|---|
| 255 | 281 | } |
|---|
| 256 | 282 | |
|---|
| .. | .. |
|---|
| 288 | 314 | free(((void *)sym) - symbol_conf.priv_size); |
|---|
| 289 | 315 | } |
|---|
| 290 | 316 | |
|---|
| 291 | | -void symbols__delete(struct rb_root *symbols) |
|---|
| 317 | +void symbols__delete(struct rb_root_cached *symbols) |
|---|
| 292 | 318 | { |
|---|
| 293 | 319 | struct symbol *pos; |
|---|
| 294 | | - struct rb_node *next = rb_first(symbols); |
|---|
| 320 | + struct rb_node *next = rb_first_cached(symbols); |
|---|
| 295 | 321 | |
|---|
| 296 | 322 | while (next) { |
|---|
| 297 | 323 | pos = rb_entry(next, struct symbol, rb_node); |
|---|
| 298 | 324 | next = rb_next(&pos->rb_node); |
|---|
| 299 | | - rb_erase(&pos->rb_node, symbols); |
|---|
| 325 | + rb_erase_cached(&pos->rb_node, symbols); |
|---|
| 300 | 326 | symbol__delete(pos); |
|---|
| 301 | 327 | } |
|---|
| 302 | 328 | } |
|---|
| 303 | 329 | |
|---|
| 304 | | -void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel) |
|---|
| 330 | +void __symbols__insert(struct rb_root_cached *symbols, |
|---|
| 331 | + struct symbol *sym, bool kernel) |
|---|
| 305 | 332 | { |
|---|
| 306 | | - struct rb_node **p = &symbols->rb_node; |
|---|
| 333 | + struct rb_node **p = &symbols->rb_root.rb_node; |
|---|
| 307 | 334 | struct rb_node *parent = NULL; |
|---|
| 308 | 335 | const u64 ip = sym->start; |
|---|
| 309 | 336 | struct symbol *s; |
|---|
| 337 | + bool leftmost = true; |
|---|
| 310 | 338 | |
|---|
| 311 | 339 | if (kernel) { |
|---|
| 312 | 340 | const char *name = sym->name; |
|---|
| .. | .. |
|---|
| 324 | 352 | s = rb_entry(parent, struct symbol, rb_node); |
|---|
| 325 | 353 | if (ip < s->start) |
|---|
| 326 | 354 | p = &(*p)->rb_left; |
|---|
| 327 | | - else |
|---|
| 355 | + else { |
|---|
| 328 | 356 | p = &(*p)->rb_right; |
|---|
| 357 | + leftmost = false; |
|---|
| 358 | + } |
|---|
| 329 | 359 | } |
|---|
| 330 | 360 | rb_link_node(&sym->rb_node, parent, p); |
|---|
| 331 | | - rb_insert_color(&sym->rb_node, symbols); |
|---|
| 361 | + rb_insert_color_cached(&sym->rb_node, symbols, leftmost); |
|---|
| 332 | 362 | } |
|---|
| 333 | 363 | |
|---|
| 334 | | -void symbols__insert(struct rb_root *symbols, struct symbol *sym) |
|---|
| 364 | +void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym) |
|---|
| 335 | 365 | { |
|---|
| 336 | 366 | __symbols__insert(symbols, sym, false); |
|---|
| 337 | 367 | } |
|---|
| 338 | 368 | |
|---|
| 339 | | -static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) |
|---|
| 369 | +static struct symbol *symbols__find(struct rb_root_cached *symbols, u64 ip) |
|---|
| 340 | 370 | { |
|---|
| 341 | 371 | struct rb_node *n; |
|---|
| 342 | 372 | |
|---|
| 343 | 373 | if (symbols == NULL) |
|---|
| 344 | 374 | return NULL; |
|---|
| 345 | 375 | |
|---|
| 346 | | - n = symbols->rb_node; |
|---|
| 376 | + n = symbols->rb_root.rb_node; |
|---|
| 347 | 377 | |
|---|
| 348 | 378 | while (n) { |
|---|
| 349 | 379 | struct symbol *s = rb_entry(n, struct symbol, rb_node); |
|---|
| .. | .. |
|---|
| 359 | 389 | return NULL; |
|---|
| 360 | 390 | } |
|---|
| 361 | 391 | |
|---|
| 362 | | -static struct symbol *symbols__first(struct rb_root *symbols) |
|---|
| 392 | +static struct symbol *symbols__first(struct rb_root_cached *symbols) |
|---|
| 363 | 393 | { |
|---|
| 364 | | - struct rb_node *n = rb_first(symbols); |
|---|
| 394 | + struct rb_node *n = rb_first_cached(symbols); |
|---|
| 365 | 395 | |
|---|
| 366 | 396 | if (n) |
|---|
| 367 | 397 | return rb_entry(n, struct symbol, rb_node); |
|---|
| .. | .. |
|---|
| 369 | 399 | return NULL; |
|---|
| 370 | 400 | } |
|---|
| 371 | 401 | |
|---|
| 372 | | -static struct symbol *symbols__last(struct rb_root *symbols) |
|---|
| 402 | +static struct symbol *symbols__last(struct rb_root_cached *symbols) |
|---|
| 373 | 403 | { |
|---|
| 374 | | - struct rb_node *n = rb_last(symbols); |
|---|
| 404 | + struct rb_node *n = rb_last(&symbols->rb_root); |
|---|
| 375 | 405 | |
|---|
| 376 | 406 | if (n) |
|---|
| 377 | 407 | return rb_entry(n, struct symbol, rb_node); |
|---|
| .. | .. |
|---|
| 389 | 419 | return NULL; |
|---|
| 390 | 420 | } |
|---|
| 391 | 421 | |
|---|
| 392 | | -static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym) |
|---|
| 422 | +static void symbols__insert_by_name(struct rb_root_cached *symbols, struct symbol *sym) |
|---|
| 393 | 423 | { |
|---|
| 394 | | - struct rb_node **p = &symbols->rb_node; |
|---|
| 424 | + struct rb_node **p = &symbols->rb_root.rb_node; |
|---|
| 395 | 425 | struct rb_node *parent = NULL; |
|---|
| 396 | 426 | struct symbol_name_rb_node *symn, *s; |
|---|
| 427 | + bool leftmost = true; |
|---|
| 397 | 428 | |
|---|
| 398 | 429 | symn = container_of(sym, struct symbol_name_rb_node, sym); |
|---|
| 399 | 430 | |
|---|
| .. | .. |
|---|
| 402 | 433 | s = rb_entry(parent, struct symbol_name_rb_node, rb_node); |
|---|
| 403 | 434 | if (strcmp(sym->name, s->sym.name) < 0) |
|---|
| 404 | 435 | p = &(*p)->rb_left; |
|---|
| 405 | | - else |
|---|
| 436 | + else { |
|---|
| 406 | 437 | p = &(*p)->rb_right; |
|---|
| 438 | + leftmost = false; |
|---|
| 439 | + } |
|---|
| 407 | 440 | } |
|---|
| 408 | 441 | rb_link_node(&symn->rb_node, parent, p); |
|---|
| 409 | | - rb_insert_color(&symn->rb_node, symbols); |
|---|
| 442 | + rb_insert_color_cached(&symn->rb_node, symbols, leftmost); |
|---|
| 410 | 443 | } |
|---|
| 411 | 444 | |
|---|
| 412 | | -static void symbols__sort_by_name(struct rb_root *symbols, |
|---|
| 413 | | - struct rb_root *source) |
|---|
| 445 | +static void symbols__sort_by_name(struct rb_root_cached *symbols, |
|---|
| 446 | + struct rb_root_cached *source) |
|---|
| 414 | 447 | { |
|---|
| 415 | 448 | struct rb_node *nd; |
|---|
| 416 | 449 | |
|---|
| 417 | | - for (nd = rb_first(source); nd; nd = rb_next(nd)) { |
|---|
| 450 | + for (nd = rb_first_cached(source); nd; nd = rb_next(nd)) { |
|---|
| 418 | 451 | struct symbol *pos = rb_entry(nd, struct symbol, rb_node); |
|---|
| 419 | 452 | symbols__insert_by_name(symbols, pos); |
|---|
| 420 | 453 | } |
|---|
| .. | .. |
|---|
| 437 | 470 | return arch__compare_symbol_names(name, str); |
|---|
| 438 | 471 | } |
|---|
| 439 | 472 | |
|---|
| 440 | | -static struct symbol *symbols__find_by_name(struct rb_root *symbols, |
|---|
| 473 | +static struct symbol *symbols__find_by_name(struct rb_root_cached *symbols, |
|---|
| 441 | 474 | const char *name, |
|---|
| 442 | 475 | enum symbol_tag_include includes) |
|---|
| 443 | 476 | { |
|---|
| .. | .. |
|---|
| 447 | 480 | if (symbols == NULL) |
|---|
| 448 | 481 | return NULL; |
|---|
| 449 | 482 | |
|---|
| 450 | | - n = symbols->rb_node; |
|---|
| 483 | + n = symbols->rb_root.rb_node; |
|---|
| 451 | 484 | |
|---|
| 452 | 485 | while (n) { |
|---|
| 453 | 486 | int cmp; |
|---|
| .. | .. |
|---|
| 497 | 530 | sym->start == sym->end)) { |
|---|
| 498 | 531 | dso->last_find_result.symbol = sym; |
|---|
| 499 | 532 | } |
|---|
| 533 | +} |
|---|
| 534 | + |
|---|
| 535 | +void dso__delete_symbol(struct dso *dso, struct symbol *sym) |
|---|
| 536 | +{ |
|---|
| 537 | + rb_erase_cached(&sym->rb_node, &dso->symbols); |
|---|
| 538 | + symbol__delete(sym); |
|---|
| 539 | + dso__reset_find_symbol_cache(dso); |
|---|
| 500 | 540 | } |
|---|
| 501 | 541 | |
|---|
| 502 | 542 | struct symbol *dso__find_symbol(struct dso *dso, u64 addr) |
|---|
| .. | .. |
|---|
| 550 | 590 | dso__set_sorted_by_name(dso); |
|---|
| 551 | 591 | return symbols__sort_by_name(&dso->symbol_names, &dso->symbols); |
|---|
| 552 | 592 | } |
|---|
| 593 | + |
|---|
| 594 | +/* |
|---|
| 595 | + * While we find nice hex chars, build a long_val. |
|---|
| 596 | + * Return number of chars processed. |
|---|
| 597 | + */ |
|---|
| 598 | +static int hex2u64(const char *ptr, u64 *long_val) |
|---|
| 599 | +{ |
|---|
| 600 | + char *p; |
|---|
| 601 | + |
|---|
| 602 | + *long_val = strtoull(ptr, &p, 16); |
|---|
| 603 | + |
|---|
| 604 | + return p - ptr; |
|---|
| 605 | +} |
|---|
| 606 | + |
|---|
| 553 | 607 | |
|---|
| 554 | 608 | int modules__parse(const char *filename, void *arg, |
|---|
| 555 | 609 | int (*process_module)(void *arg, const char *name, |
|---|
| .. | .. |
|---|
| 620 | 674 | static bool symbol__is_idle(const char *name) |
|---|
| 621 | 675 | { |
|---|
| 622 | 676 | const char * const idle_symbols[] = { |
|---|
| 677 | + "acpi_idle_do_entry", |
|---|
| 678 | + "acpi_processor_ffh_cstate_enter", |
|---|
| 679 | + "arch_cpu_idle", |
|---|
| 623 | 680 | "cpu_idle", |
|---|
| 624 | 681 | "cpu_startup_entry", |
|---|
| 682 | + "idle_cpu", |
|---|
| 625 | 683 | "intel_idle", |
|---|
| 626 | 684 | "default_idle", |
|---|
| 627 | 685 | "native_safe_halt", |
|---|
| .. | .. |
|---|
| 629 | 687 | "exit_idle", |
|---|
| 630 | 688 | "mwait_idle", |
|---|
| 631 | 689 | "mwait_idle_with_hints", |
|---|
| 690 | + "mwait_idle_with_hints.constprop.0", |
|---|
| 632 | 691 | "poll_idle", |
|---|
| 633 | 692 | "ppc64_runlatch_off", |
|---|
| 634 | 693 | "pseries_dedicated_idle_sleep", |
|---|
| 694 | + "psw_idle", |
|---|
| 695 | + "psw_idle_exit", |
|---|
| 635 | 696 | NULL |
|---|
| 636 | 697 | }; |
|---|
| 637 | 698 | int i; |
|---|
| 699 | + static struct strlist *idle_symbols_list; |
|---|
| 638 | 700 | |
|---|
| 639 | | - for (i = 0; idle_symbols[i]; i++) { |
|---|
| 640 | | - if (!strcmp(idle_symbols[i], name)) |
|---|
| 641 | | - return true; |
|---|
| 642 | | - } |
|---|
| 701 | + if (idle_symbols_list) |
|---|
| 702 | + return strlist__has_entry(idle_symbols_list, name); |
|---|
| 643 | 703 | |
|---|
| 644 | | - return false; |
|---|
| 704 | + idle_symbols_list = strlist__new(NULL, NULL); |
|---|
| 705 | + |
|---|
| 706 | + for (i = 0; idle_symbols[i]; i++) |
|---|
| 707 | + strlist__add(idle_symbols_list, idle_symbols[i]); |
|---|
| 708 | + |
|---|
| 709 | + return strlist__has_entry(idle_symbols_list, name); |
|---|
| 645 | 710 | } |
|---|
| 646 | 711 | |
|---|
| 647 | 712 | static int map__process_kallsym_symbol(void *arg, const char *name, |
|---|
| .. | .. |
|---|
| 649 | 714 | { |
|---|
| 650 | 715 | struct symbol *sym; |
|---|
| 651 | 716 | struct dso *dso = arg; |
|---|
| 652 | | - struct rb_root *root = &dso->symbols; |
|---|
| 717 | + struct rb_root_cached *root = &dso->symbols; |
|---|
| 653 | 718 | |
|---|
| 654 | 719 | if (!symbol_type__filter(type)) |
|---|
| 655 | 720 | return 0; |
|---|
| .. | .. |
|---|
| 681 | 746 | return kallsyms__parse(filename, dso, map__process_kallsym_symbol); |
|---|
| 682 | 747 | } |
|---|
| 683 | 748 | |
|---|
| 684 | | -static int map_groups__split_kallsyms_for_kcore(struct map_groups *kmaps, struct dso *dso) |
|---|
| 749 | +static int maps__split_kallsyms_for_kcore(struct maps *kmaps, struct dso *dso) |
|---|
| 685 | 750 | { |
|---|
| 686 | 751 | struct map *curr_map; |
|---|
| 687 | 752 | struct symbol *pos; |
|---|
| 688 | 753 | int count = 0; |
|---|
| 689 | | - struct rb_root old_root = dso->symbols; |
|---|
| 690 | | - struct rb_root *root = &dso->symbols; |
|---|
| 691 | | - struct rb_node *next = rb_first(root); |
|---|
| 754 | + struct rb_root_cached old_root = dso->symbols; |
|---|
| 755 | + struct rb_root_cached *root = &dso->symbols; |
|---|
| 756 | + struct rb_node *next = rb_first_cached(root); |
|---|
| 692 | 757 | |
|---|
| 693 | 758 | if (!kmaps) |
|---|
| 694 | 759 | return -1; |
|---|
| 695 | 760 | |
|---|
| 696 | | - *root = RB_ROOT; |
|---|
| 761 | + *root = RB_ROOT_CACHED; |
|---|
| 697 | 762 | |
|---|
| 698 | 763 | while (next) { |
|---|
| 699 | 764 | char *module; |
|---|
| .. | .. |
|---|
| 701 | 766 | pos = rb_entry(next, struct symbol, rb_node); |
|---|
| 702 | 767 | next = rb_next(&pos->rb_node); |
|---|
| 703 | 768 | |
|---|
| 704 | | - rb_erase_init(&pos->rb_node, &old_root); |
|---|
| 705 | | - |
|---|
| 769 | + rb_erase_cached(&pos->rb_node, &old_root); |
|---|
| 770 | + RB_CLEAR_NODE(&pos->rb_node); |
|---|
| 706 | 771 | module = strchr(pos->name, '\t'); |
|---|
| 707 | 772 | if (module) |
|---|
| 708 | 773 | *module = '\0'; |
|---|
| 709 | 774 | |
|---|
| 710 | | - curr_map = map_groups__find(kmaps, pos->start); |
|---|
| 775 | + curr_map = maps__find(kmaps, pos->start); |
|---|
| 711 | 776 | |
|---|
| 712 | 777 | if (!curr_map) { |
|---|
| 713 | 778 | symbol__delete(pos); |
|---|
| .. | .. |
|---|
| 734 | 799 | * kernel range is broken in several maps, named [kernel].N, as we don't have |
|---|
| 735 | 800 | * the original ELF section names vmlinux have. |
|---|
| 736 | 801 | */ |
|---|
| 737 | | -static int map_groups__split_kallsyms(struct map_groups *kmaps, struct dso *dso, u64 delta, |
|---|
| 738 | | - struct map *initial_map) |
|---|
| 802 | +static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, |
|---|
| 803 | + struct map *initial_map) |
|---|
| 739 | 804 | { |
|---|
| 740 | 805 | struct machine *machine; |
|---|
| 741 | 806 | struct map *curr_map = initial_map; |
|---|
| 742 | 807 | struct symbol *pos; |
|---|
| 743 | 808 | int count = 0, moved = 0; |
|---|
| 744 | | - struct rb_root *root = &dso->symbols; |
|---|
| 745 | | - struct rb_node *next = rb_first(root); |
|---|
| 809 | + struct rb_root_cached *root = &dso->symbols; |
|---|
| 810 | + struct rb_node *next = rb_first_cached(root); |
|---|
| 746 | 811 | int kernel_range = 0; |
|---|
| 747 | 812 | bool x86_64; |
|---|
| 748 | 813 | |
|---|
| .. | .. |
|---|
| 768 | 833 | |
|---|
| 769 | 834 | if (strcmp(curr_map->dso->short_name, module)) { |
|---|
| 770 | 835 | if (curr_map != initial_map && |
|---|
| 771 | | - dso->kernel == DSO_TYPE_GUEST_KERNEL && |
|---|
| 836 | + dso->kernel == DSO_SPACE__KERNEL_GUEST && |
|---|
| 772 | 837 | machine__is_default_guest(machine)) { |
|---|
| 773 | 838 | /* |
|---|
| 774 | 839 | * We assume all symbols of a module are |
|---|
| .. | .. |
|---|
| 780 | 845 | dso__set_loaded(curr_map->dso); |
|---|
| 781 | 846 | } |
|---|
| 782 | 847 | |
|---|
| 783 | | - curr_map = map_groups__find_by_name(kmaps, module); |
|---|
| 848 | + curr_map = maps__find_by_name(kmaps, module); |
|---|
| 784 | 849 | if (curr_map == NULL) { |
|---|
| 785 | 850 | pr_debug("%s/proc/{kallsyms,modules} " |
|---|
| 786 | 851 | "inconsistency while looking " |
|---|
| .. | .. |
|---|
| 825 | 890 | goto add_symbol; |
|---|
| 826 | 891 | } |
|---|
| 827 | 892 | |
|---|
| 828 | | - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 893 | + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 829 | 894 | snprintf(dso_name, sizeof(dso_name), |
|---|
| 830 | 895 | "[guest.kernel].%d", |
|---|
| 831 | 896 | kernel_range++); |
|---|
| .. | .. |
|---|
| 847 | 912 | } |
|---|
| 848 | 913 | |
|---|
| 849 | 914 | curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; |
|---|
| 850 | | - map_groups__insert(kmaps, curr_map); |
|---|
| 915 | + maps__insert(kmaps, curr_map); |
|---|
| 851 | 916 | ++kernel_range; |
|---|
| 852 | 917 | } else if (delta) { |
|---|
| 853 | 918 | /* Kernel was relocated at boot time */ |
|---|
| .. | .. |
|---|
| 856 | 921 | } |
|---|
| 857 | 922 | add_symbol: |
|---|
| 858 | 923 | if (curr_map != initial_map) { |
|---|
| 859 | | - rb_erase(&pos->rb_node, root); |
|---|
| 924 | + rb_erase_cached(&pos->rb_node, root); |
|---|
| 860 | 925 | symbols__insert(&curr_map->dso->symbols, pos); |
|---|
| 861 | 926 | ++moved; |
|---|
| 862 | 927 | } else |
|---|
| .. | .. |
|---|
| 864 | 929 | |
|---|
| 865 | 930 | continue; |
|---|
| 866 | 931 | discard_symbol: |
|---|
| 867 | | - rb_erase(&pos->rb_node, root); |
|---|
| 932 | + rb_erase_cached(&pos->rb_node, root); |
|---|
| 868 | 933 | symbol__delete(pos); |
|---|
| 869 | 934 | } |
|---|
| 870 | 935 | |
|---|
| 871 | 936 | if (curr_map != initial_map && |
|---|
| 872 | | - dso->kernel == DSO_TYPE_GUEST_KERNEL && |
|---|
| 937 | + dso->kernel == DSO_SPACE__KERNEL_GUEST && |
|---|
| 873 | 938 | machine__is_default_guest(kmaps->machine)) { |
|---|
| 874 | 939 | dso__set_loaded(curr_map->dso); |
|---|
| 875 | 940 | } |
|---|
| .. | .. |
|---|
| 1032 | 1097 | return ret; |
|---|
| 1033 | 1098 | } |
|---|
| 1034 | 1099 | |
|---|
| 1035 | | -struct map *map_groups__first(struct map_groups *mg) |
|---|
| 1036 | | -{ |
|---|
| 1037 | | - return maps__first(&mg->maps); |
|---|
| 1038 | | -} |
|---|
| 1039 | | - |
|---|
| 1040 | | -static int do_validate_kcore_modules(const char *filename, |
|---|
| 1041 | | - struct map_groups *kmaps) |
|---|
| 1100 | +static int do_validate_kcore_modules(const char *filename, struct maps *kmaps) |
|---|
| 1042 | 1101 | { |
|---|
| 1043 | 1102 | struct rb_root modules = RB_ROOT; |
|---|
| 1044 | 1103 | struct map *old_map; |
|---|
| .. | .. |
|---|
| 1048 | 1107 | if (err) |
|---|
| 1049 | 1108 | return err; |
|---|
| 1050 | 1109 | |
|---|
| 1051 | | - old_map = map_groups__first(kmaps); |
|---|
| 1052 | | - while (old_map) { |
|---|
| 1053 | | - struct map *next = map_groups__next(old_map); |
|---|
| 1110 | + maps__for_each_entry(kmaps, old_map) { |
|---|
| 1054 | 1111 | struct module_info *mi; |
|---|
| 1055 | 1112 | |
|---|
| 1056 | 1113 | if (!__map__is_kmodule(old_map)) { |
|---|
| 1057 | | - old_map = next; |
|---|
| 1058 | 1114 | continue; |
|---|
| 1059 | 1115 | } |
|---|
| 1060 | 1116 | |
|---|
| .. | .. |
|---|
| 1064 | 1120 | err = -EINVAL; |
|---|
| 1065 | 1121 | goto out; |
|---|
| 1066 | 1122 | } |
|---|
| 1067 | | - |
|---|
| 1068 | | - old_map = next; |
|---|
| 1069 | 1123 | } |
|---|
| 1070 | 1124 | out: |
|---|
| 1071 | 1125 | delete_modules(&modules); |
|---|
| .. | .. |
|---|
| 1100 | 1154 | static int validate_kcore_modules(const char *kallsyms_filename, |
|---|
| 1101 | 1155 | struct map *map) |
|---|
| 1102 | 1156 | { |
|---|
| 1103 | | - struct map_groups *kmaps = map__kmaps(map); |
|---|
| 1157 | + struct maps *kmaps = map__kmaps(map); |
|---|
| 1104 | 1158 | char modules_filename[PATH_MAX]; |
|---|
| 1105 | 1159 | |
|---|
| 1106 | 1160 | if (!kmaps) |
|---|
| .. | .. |
|---|
| 1159 | 1213 | return 0; |
|---|
| 1160 | 1214 | } |
|---|
| 1161 | 1215 | |
|---|
| 1216 | +/* |
|---|
| 1217 | + * Merges map into maps by splitting the new map within the existing map |
|---|
| 1218 | + * regions. |
|---|
| 1219 | + */ |
|---|
| 1220 | +int maps__merge_in(struct maps *kmaps, struct map *new_map) |
|---|
| 1221 | +{ |
|---|
| 1222 | + struct map *old_map; |
|---|
| 1223 | + LIST_HEAD(merged); |
|---|
| 1224 | + |
|---|
| 1225 | + maps__for_each_entry(kmaps, old_map) { |
|---|
| 1226 | + /* no overload with this one */ |
|---|
| 1227 | + if (new_map->end < old_map->start || |
|---|
| 1228 | + new_map->start >= old_map->end) |
|---|
| 1229 | + continue; |
|---|
| 1230 | + |
|---|
| 1231 | + if (new_map->start < old_map->start) { |
|---|
| 1232 | + /* |
|---|
| 1233 | + * |new...... |
|---|
| 1234 | + * |old.... |
|---|
| 1235 | + */ |
|---|
| 1236 | + if (new_map->end < old_map->end) { |
|---|
| 1237 | + /* |
|---|
| 1238 | + * |new......| -> |new..| |
|---|
| 1239 | + * |old....| -> |old....| |
|---|
| 1240 | + */ |
|---|
| 1241 | + new_map->end = old_map->start; |
|---|
| 1242 | + } else { |
|---|
| 1243 | + /* |
|---|
| 1244 | + * |new.............| -> |new..| |new..| |
|---|
| 1245 | + * |old....| -> |old....| |
|---|
| 1246 | + */ |
|---|
| 1247 | + struct map *m = map__clone(new_map); |
|---|
| 1248 | + |
|---|
| 1249 | + if (!m) |
|---|
| 1250 | + return -ENOMEM; |
|---|
| 1251 | + |
|---|
| 1252 | + m->end = old_map->start; |
|---|
| 1253 | + list_add_tail(&m->node, &merged); |
|---|
| 1254 | + new_map->pgoff += old_map->end - new_map->start; |
|---|
| 1255 | + new_map->start = old_map->end; |
|---|
| 1256 | + } |
|---|
| 1257 | + } else { |
|---|
| 1258 | + /* |
|---|
| 1259 | + * |new...... |
|---|
| 1260 | + * |old.... |
|---|
| 1261 | + */ |
|---|
| 1262 | + if (new_map->end < old_map->end) { |
|---|
| 1263 | + /* |
|---|
| 1264 | + * |new..| -> x |
|---|
| 1265 | + * |old.........| -> |old.........| |
|---|
| 1266 | + */ |
|---|
| 1267 | + map__put(new_map); |
|---|
| 1268 | + new_map = NULL; |
|---|
| 1269 | + break; |
|---|
| 1270 | + } else { |
|---|
| 1271 | + /* |
|---|
| 1272 | + * |new......| -> |new...| |
|---|
| 1273 | + * |old....| -> |old....| |
|---|
| 1274 | + */ |
|---|
| 1275 | + new_map->pgoff += old_map->end - new_map->start; |
|---|
| 1276 | + new_map->start = old_map->end; |
|---|
| 1277 | + } |
|---|
| 1278 | + } |
|---|
| 1279 | + } |
|---|
| 1280 | + |
|---|
| 1281 | + while (!list_empty(&merged)) { |
|---|
| 1282 | + old_map = list_entry(merged.next, struct map, node); |
|---|
| 1283 | + list_del_init(&old_map->node); |
|---|
| 1284 | + maps__insert(kmaps, old_map); |
|---|
| 1285 | + map__put(old_map); |
|---|
| 1286 | + } |
|---|
| 1287 | + |
|---|
| 1288 | + if (new_map) { |
|---|
| 1289 | + maps__insert(kmaps, new_map); |
|---|
| 1290 | + map__put(new_map); |
|---|
| 1291 | + } |
|---|
| 1292 | + return 0; |
|---|
| 1293 | +} |
|---|
| 1294 | + |
|---|
| 1162 | 1295 | static int dso__load_kcore(struct dso *dso, struct map *map, |
|---|
| 1163 | 1296 | const char *kallsyms_filename) |
|---|
| 1164 | 1297 | { |
|---|
| 1165 | | - struct map_groups *kmaps = map__kmaps(map); |
|---|
| 1298 | + struct maps *kmaps = map__kmaps(map); |
|---|
| 1166 | 1299 | struct kcore_mapfn_data md; |
|---|
| 1167 | | - struct map *old_map, *new_map, *replacement_map = NULL; |
|---|
| 1300 | + struct map *old_map, *new_map, *replacement_map = NULL, *next; |
|---|
| 1168 | 1301 | struct machine *machine; |
|---|
| 1169 | 1302 | bool is_64_bit; |
|---|
| 1170 | 1303 | int err, fd; |
|---|
| .. | .. |
|---|
| 1211 | 1344 | } |
|---|
| 1212 | 1345 | |
|---|
| 1213 | 1346 | /* Remove old maps */ |
|---|
| 1214 | | - old_map = map_groups__first(kmaps); |
|---|
| 1215 | | - while (old_map) { |
|---|
| 1216 | | - struct map *next = map_groups__next(old_map); |
|---|
| 1217 | | - |
|---|
| 1218 | | - if (old_map != map) |
|---|
| 1219 | | - map_groups__remove(kmaps, old_map); |
|---|
| 1220 | | - old_map = next; |
|---|
| 1347 | + maps__for_each_entry_safe(kmaps, old_map, next) { |
|---|
| 1348 | + /* |
|---|
| 1349 | + * We need to preserve eBPF maps even if they are |
|---|
| 1350 | + * covered by kcore, because we need to access |
|---|
| 1351 | + * eBPF dso for source data. |
|---|
| 1352 | + */ |
|---|
| 1353 | + if (old_map != map && !__map__is_bpf_prog(old_map)) |
|---|
| 1354 | + maps__remove(kmaps, old_map); |
|---|
| 1221 | 1355 | } |
|---|
| 1222 | 1356 | machine->trampolines_mapped = false; |
|---|
| 1223 | 1357 | |
|---|
| .. | .. |
|---|
| 1246 | 1380 | map->unmap_ip = new_map->unmap_ip; |
|---|
| 1247 | 1381 | /* Ensure maps are correctly ordered */ |
|---|
| 1248 | 1382 | map__get(map); |
|---|
| 1249 | | - map_groups__remove(kmaps, map); |
|---|
| 1250 | | - map_groups__insert(kmaps, map); |
|---|
| 1383 | + maps__remove(kmaps, map); |
|---|
| 1384 | + maps__insert(kmaps, map); |
|---|
| 1251 | 1385 | map__put(map); |
|---|
| 1386 | + map__put(new_map); |
|---|
| 1252 | 1387 | } else { |
|---|
| 1253 | | - map_groups__insert(kmaps, new_map); |
|---|
| 1388 | + /* |
|---|
| 1389 | + * Merge kcore map into existing maps, |
|---|
| 1390 | + * and ensure that current maps (eBPF) |
|---|
| 1391 | + * stay intact. |
|---|
| 1392 | + */ |
|---|
| 1393 | + if (maps__merge_in(kmaps, new_map)) |
|---|
| 1394 | + goto out_err; |
|---|
| 1254 | 1395 | } |
|---|
| 1255 | | - |
|---|
| 1256 | | - map__put(new_map); |
|---|
| 1257 | 1396 | } |
|---|
| 1258 | 1397 | |
|---|
| 1259 | 1398 | if (machine__is(machine, "x86_64")) { |
|---|
| .. | .. |
|---|
| 1273 | 1412 | * Set the data type and long name so that kcore can be read via |
|---|
| 1274 | 1413 | * dso__data_read_addr(). |
|---|
| 1275 | 1414 | */ |
|---|
| 1276 | | - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 1415 | + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 1277 | 1416 | dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE; |
|---|
| 1278 | 1417 | else |
|---|
| 1279 | 1418 | dso->binary_type = DSO_BINARY_TYPE__KCORE; |
|---|
| .. | .. |
|---|
| 1334 | 1473 | if (kallsyms__delta(kmap, filename, &delta)) |
|---|
| 1335 | 1474 | return -1; |
|---|
| 1336 | 1475 | |
|---|
| 1337 | | - symbols__fixup_end(&dso->symbols); |
|---|
| 1476 | + symbols__fixup_end(&dso->symbols, true); |
|---|
| 1338 | 1477 | symbols__fixup_duplicate(&dso->symbols); |
|---|
| 1339 | 1478 | |
|---|
| 1340 | | - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 1479 | + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 1341 | 1480 | dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS; |
|---|
| 1342 | 1481 | else |
|---|
| 1343 | 1482 | dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS; |
|---|
| 1344 | 1483 | |
|---|
| 1345 | 1484 | if (!no_kcore && !dso__load_kcore(dso, map, filename)) |
|---|
| 1346 | | - return map_groups__split_kallsyms_for_kcore(kmap->kmaps, dso); |
|---|
| 1485 | + return maps__split_kallsyms_for_kcore(kmap->kmaps, dso); |
|---|
| 1347 | 1486 | else |
|---|
| 1348 | | - return map_groups__split_kallsyms(kmap->kmaps, dso, delta, map); |
|---|
| 1487 | + return maps__split_kallsyms(kmap->kmaps, dso, delta, map); |
|---|
| 1349 | 1488 | } |
|---|
| 1350 | 1489 | |
|---|
| 1351 | 1490 | int dso__load_kallsyms(struct dso *dso, const char *filename, |
|---|
| .. | .. |
|---|
| 1411 | 1550 | return -1; |
|---|
| 1412 | 1551 | } |
|---|
| 1413 | 1552 | |
|---|
| 1553 | +#ifdef HAVE_LIBBFD_SUPPORT |
|---|
| 1554 | +#define PACKAGE 'perf' |
|---|
| 1555 | +#include <bfd.h> |
|---|
| 1556 | + |
|---|
| 1557 | +static int bfd_symbols__cmpvalue(const void *a, const void *b) |
|---|
| 1558 | +{ |
|---|
| 1559 | + const asymbol *as = *(const asymbol **)a, *bs = *(const asymbol **)b; |
|---|
| 1560 | + |
|---|
| 1561 | + if (bfd_asymbol_value(as) != bfd_asymbol_value(bs)) |
|---|
| 1562 | + return bfd_asymbol_value(as) - bfd_asymbol_value(bs); |
|---|
| 1563 | + |
|---|
| 1564 | + return bfd_asymbol_name(as)[0] - bfd_asymbol_name(bs)[0]; |
|---|
| 1565 | +} |
|---|
| 1566 | + |
|---|
| 1567 | +static int bfd2elf_binding(asymbol *symbol) |
|---|
| 1568 | +{ |
|---|
| 1569 | + if (symbol->flags & BSF_WEAK) |
|---|
| 1570 | + return STB_WEAK; |
|---|
| 1571 | + if (symbol->flags & BSF_GLOBAL) |
|---|
| 1572 | + return STB_GLOBAL; |
|---|
| 1573 | + if (symbol->flags & BSF_LOCAL) |
|---|
| 1574 | + return STB_LOCAL; |
|---|
| 1575 | + return -1; |
|---|
| 1576 | +} |
|---|
| 1577 | + |
|---|
| 1578 | +int dso__load_bfd_symbols(struct dso *dso, const char *debugfile) |
|---|
| 1579 | +{ |
|---|
| 1580 | + int err = -1; |
|---|
| 1581 | + long symbols_size, symbols_count, i; |
|---|
| 1582 | + asection *section; |
|---|
| 1583 | + asymbol **symbols, *sym; |
|---|
| 1584 | + struct symbol *symbol; |
|---|
| 1585 | + bfd *abfd; |
|---|
| 1586 | + u64 start, len; |
|---|
| 1587 | + |
|---|
| 1588 | + abfd = bfd_openr(dso->long_name, NULL); |
|---|
| 1589 | + if (!abfd) |
|---|
| 1590 | + return -1; |
|---|
| 1591 | + |
|---|
| 1592 | + if (!bfd_check_format(abfd, bfd_object)) { |
|---|
| 1593 | + pr_debug2("%s: cannot read %s bfd file.\n", __func__, |
|---|
| 1594 | + dso->long_name); |
|---|
| 1595 | + goto out_close; |
|---|
| 1596 | + } |
|---|
| 1597 | + |
|---|
| 1598 | + if (bfd_get_flavour(abfd) == bfd_target_elf_flavour) |
|---|
| 1599 | + goto out_close; |
|---|
| 1600 | + |
|---|
| 1601 | + section = bfd_get_section_by_name(abfd, ".text"); |
|---|
| 1602 | + if (section) |
|---|
| 1603 | + dso->text_offset = section->vma - section->filepos; |
|---|
| 1604 | + |
|---|
| 1605 | + bfd_close(abfd); |
|---|
| 1606 | + |
|---|
| 1607 | + abfd = bfd_openr(debugfile, NULL); |
|---|
| 1608 | + if (!abfd) |
|---|
| 1609 | + return -1; |
|---|
| 1610 | + |
|---|
| 1611 | + if (!bfd_check_format(abfd, bfd_object)) { |
|---|
| 1612 | + pr_debug2("%s: cannot read %s bfd file.\n", __func__, |
|---|
| 1613 | + debugfile); |
|---|
| 1614 | + goto out_close; |
|---|
| 1615 | + } |
|---|
| 1616 | + |
|---|
| 1617 | + if (bfd_get_flavour(abfd) == bfd_target_elf_flavour) |
|---|
| 1618 | + goto out_close; |
|---|
| 1619 | + |
|---|
| 1620 | + symbols_size = bfd_get_symtab_upper_bound(abfd); |
|---|
| 1621 | + if (symbols_size == 0) { |
|---|
| 1622 | + bfd_close(abfd); |
|---|
| 1623 | + return 0; |
|---|
| 1624 | + } |
|---|
| 1625 | + |
|---|
| 1626 | + if (symbols_size < 0) |
|---|
| 1627 | + goto out_close; |
|---|
| 1628 | + |
|---|
| 1629 | + symbols = malloc(symbols_size); |
|---|
| 1630 | + if (!symbols) |
|---|
| 1631 | + goto out_close; |
|---|
| 1632 | + |
|---|
| 1633 | + symbols_count = bfd_canonicalize_symtab(abfd, symbols); |
|---|
| 1634 | + if (symbols_count < 0) |
|---|
| 1635 | + goto out_free; |
|---|
| 1636 | + |
|---|
| 1637 | + qsort(symbols, symbols_count, sizeof(asymbol *), bfd_symbols__cmpvalue); |
|---|
| 1638 | + |
|---|
| 1639 | +#ifdef bfd_get_section |
|---|
| 1640 | +#define bfd_asymbol_section bfd_get_section |
|---|
| 1641 | +#endif |
|---|
| 1642 | + for (i = 0; i < symbols_count; ++i) { |
|---|
| 1643 | + sym = symbols[i]; |
|---|
| 1644 | + section = bfd_asymbol_section(sym); |
|---|
| 1645 | + if (bfd2elf_binding(sym) < 0) |
|---|
| 1646 | + continue; |
|---|
| 1647 | + |
|---|
| 1648 | + while (i + 1 < symbols_count && |
|---|
| 1649 | + bfd_asymbol_section(symbols[i + 1]) == section && |
|---|
| 1650 | + bfd2elf_binding(symbols[i + 1]) < 0) |
|---|
| 1651 | + i++; |
|---|
| 1652 | + |
|---|
| 1653 | + if (i + 1 < symbols_count && |
|---|
| 1654 | + bfd_asymbol_section(symbols[i + 1]) == section) |
|---|
| 1655 | + len = symbols[i + 1]->value - sym->value; |
|---|
| 1656 | + else |
|---|
| 1657 | + len = section->size - sym->value; |
|---|
| 1658 | + |
|---|
| 1659 | + start = bfd_asymbol_value(sym) - dso->text_offset; |
|---|
| 1660 | + symbol = symbol__new(start, len, bfd2elf_binding(sym), STT_FUNC, |
|---|
| 1661 | + bfd_asymbol_name(sym)); |
|---|
| 1662 | + if (!symbol) |
|---|
| 1663 | + goto out_free; |
|---|
| 1664 | + |
|---|
| 1665 | + symbols__insert(&dso->symbols, symbol); |
|---|
| 1666 | + } |
|---|
| 1667 | +#ifdef bfd_get_section |
|---|
| 1668 | +#undef bfd_asymbol_section |
|---|
| 1669 | +#endif |
|---|
| 1670 | + |
|---|
| 1671 | + symbols__fixup_end(&dso->symbols, false); |
|---|
| 1672 | + symbols__fixup_duplicate(&dso->symbols); |
|---|
| 1673 | + dso->adjust_symbols = 1; |
|---|
| 1674 | + |
|---|
| 1675 | + err = 0; |
|---|
| 1676 | +out_free: |
|---|
| 1677 | + free(symbols); |
|---|
| 1678 | +out_close: |
|---|
| 1679 | + bfd_close(abfd); |
|---|
| 1680 | + return err; |
|---|
| 1681 | +} |
|---|
| 1682 | +#endif |
|---|
| 1683 | + |
|---|
| 1414 | 1684 | static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, |
|---|
| 1415 | 1685 | enum dso_binary_type type) |
|---|
| 1416 | 1686 | { |
|---|
| .. | .. |
|---|
| 1423 | 1693 | case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO: |
|---|
| 1424 | 1694 | case DSO_BINARY_TYPE__BUILDID_DEBUGINFO: |
|---|
| 1425 | 1695 | case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: |
|---|
| 1426 | | - return !kmod && dso->kernel == DSO_TYPE_USER; |
|---|
| 1696 | + return !kmod && dso->kernel == DSO_SPACE__USER; |
|---|
| 1427 | 1697 | |
|---|
| 1428 | 1698 | case DSO_BINARY_TYPE__KALLSYMS: |
|---|
| 1429 | 1699 | case DSO_BINARY_TYPE__VMLINUX: |
|---|
| 1430 | 1700 | case DSO_BINARY_TYPE__KCORE: |
|---|
| 1431 | | - return dso->kernel == DSO_TYPE_KERNEL; |
|---|
| 1701 | + return dso->kernel == DSO_SPACE__KERNEL; |
|---|
| 1432 | 1702 | |
|---|
| 1433 | 1703 | case DSO_BINARY_TYPE__GUEST_KALLSYMS: |
|---|
| 1434 | 1704 | case DSO_BINARY_TYPE__GUEST_VMLINUX: |
|---|
| 1435 | 1705 | case DSO_BINARY_TYPE__GUEST_KCORE: |
|---|
| 1436 | | - return dso->kernel == DSO_TYPE_GUEST_KERNEL; |
|---|
| 1706 | + return dso->kernel == DSO_SPACE__KERNEL_GUEST; |
|---|
| 1437 | 1707 | |
|---|
| 1438 | 1708 | case DSO_BINARY_TYPE__GUEST_KMODULE: |
|---|
| 1439 | 1709 | case DSO_BINARY_TYPE__GUEST_KMODULE_COMP: |
|---|
| .. | .. |
|---|
| 1441 | 1711 | case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP: |
|---|
| 1442 | 1712 | /* |
|---|
| 1443 | 1713 | * kernel modules know their symtab type - it's set when |
|---|
| 1444 | | - * creating a module dso in machine__findnew_module_map(). |
|---|
| 1714 | + * creating a module dso in machine__addnew_module_map(). |
|---|
| 1445 | 1715 | */ |
|---|
| 1446 | 1716 | return kmod && dso->symtab_type == type; |
|---|
| 1447 | 1717 | |
|---|
| .. | .. |
|---|
| 1449 | 1719 | case DSO_BINARY_TYPE__BUILD_ID_CACHE_DEBUGINFO: |
|---|
| 1450 | 1720 | return true; |
|---|
| 1451 | 1721 | |
|---|
| 1722 | + case DSO_BINARY_TYPE__BPF_PROG_INFO: |
|---|
| 1723 | + case DSO_BINARY_TYPE__BPF_IMAGE: |
|---|
| 1724 | + case DSO_BINARY_TYPE__OOL: |
|---|
| 1452 | 1725 | case DSO_BINARY_TYPE__NOT_FOUND: |
|---|
| 1453 | 1726 | default: |
|---|
| 1454 | 1727 | return false; |
|---|
| .. | .. |
|---|
| 1498 | 1771 | char *name; |
|---|
| 1499 | 1772 | int ret = -1; |
|---|
| 1500 | 1773 | u_int i; |
|---|
| 1501 | | - struct machine *machine; |
|---|
| 1774 | + struct machine *machine = NULL; |
|---|
| 1502 | 1775 | char *root_dir = (char *) ""; |
|---|
| 1503 | 1776 | int ss_pos = 0; |
|---|
| 1504 | 1777 | struct symsrc ss_[2]; |
|---|
| 1505 | 1778 | struct symsrc *syms_ss = NULL, *runtime_ss = NULL; |
|---|
| 1506 | 1779 | bool kmod; |
|---|
| 1507 | 1780 | bool perfmap; |
|---|
| 1508 | | - unsigned char build_id[BUILD_ID_SIZE]; |
|---|
| 1781 | + struct build_id bid; |
|---|
| 1509 | 1782 | struct nscookie nsc; |
|---|
| 1510 | 1783 | char newmapname[PATH_MAX]; |
|---|
| 1511 | 1784 | const char *map_path = dso->long_name; |
|---|
| .. | .. |
|---|
| 1527 | 1800 | goto out; |
|---|
| 1528 | 1801 | } |
|---|
| 1529 | 1802 | |
|---|
| 1530 | | - if (map->groups && map->groups->machine) |
|---|
| 1531 | | - machine = map->groups->machine; |
|---|
| 1532 | | - else |
|---|
| 1533 | | - machine = NULL; |
|---|
| 1803 | + kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || |
|---|
| 1804 | + dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || |
|---|
| 1805 | + dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || |
|---|
| 1806 | + dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; |
|---|
| 1534 | 1807 | |
|---|
| 1535 | | - if (dso->kernel) { |
|---|
| 1536 | | - if (dso->kernel == DSO_TYPE_KERNEL) |
|---|
| 1808 | + if (dso->kernel && !kmod) { |
|---|
| 1809 | + if (dso->kernel == DSO_SPACE__KERNEL) |
|---|
| 1537 | 1810 | ret = dso__load_kernel_sym(dso, map); |
|---|
| 1538 | | - else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 1811 | + else if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 1539 | 1812 | ret = dso__load_guest_kernel_sym(dso, map); |
|---|
| 1540 | 1813 | |
|---|
| 1814 | + machine = map__kmaps(map)->machine; |
|---|
| 1541 | 1815 | if (machine__is(machine, "x86_64")) |
|---|
| 1542 | 1816 | machine__map_x86_64_entry_trampolines(machine, dso); |
|---|
| 1543 | 1817 | goto out; |
|---|
| .. | .. |
|---|
| 1546 | 1820 | dso->adjust_symbols = 0; |
|---|
| 1547 | 1821 | |
|---|
| 1548 | 1822 | if (perfmap) { |
|---|
| 1549 | | - struct stat st; |
|---|
| 1550 | | - |
|---|
| 1551 | | - if (lstat(map_path, &st) < 0) |
|---|
| 1552 | | - goto out; |
|---|
| 1553 | | - |
|---|
| 1554 | | - if (!symbol_conf.force && st.st_uid && (st.st_uid != geteuid())) { |
|---|
| 1555 | | - pr_warning("File %s not owned by current user or root, " |
|---|
| 1556 | | - "ignoring it (use -f to override).\n", map_path); |
|---|
| 1557 | | - goto out; |
|---|
| 1558 | | - } |
|---|
| 1559 | | - |
|---|
| 1560 | 1823 | ret = dso__load_perf_map(map_path, dso); |
|---|
| 1561 | 1824 | dso->symtab_type = ret > 0 ? DSO_BINARY_TYPE__JAVA_JIT : |
|---|
| 1562 | 1825 | DSO_BINARY_TYPE__NOT_FOUND; |
|---|
| .. | .. |
|---|
| 1570 | 1833 | if (!name) |
|---|
| 1571 | 1834 | goto out; |
|---|
| 1572 | 1835 | |
|---|
| 1573 | | - kmod = dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE || |
|---|
| 1574 | | - dso->symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP || |
|---|
| 1575 | | - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE || |
|---|
| 1576 | | - dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP; |
|---|
| 1577 | | - |
|---|
| 1578 | | - |
|---|
| 1579 | 1836 | /* |
|---|
| 1580 | 1837 | * Read the build id if possible. This is required for |
|---|
| 1581 | 1838 | * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work |
|---|
| .. | .. |
|---|
| 1583 | 1840 | if (!dso->has_build_id && |
|---|
| 1584 | 1841 | is_regular_file(dso->long_name)) { |
|---|
| 1585 | 1842 | __symbol__join_symfs(name, PATH_MAX, dso->long_name); |
|---|
| 1586 | | - if (filename__read_build_id(name, build_id, BUILD_ID_SIZE) > 0) |
|---|
| 1587 | | - dso__set_build_id(dso, build_id); |
|---|
| 1843 | + if (filename__read_build_id(name, &bid) > 0) |
|---|
| 1844 | + dso__set_build_id(dso, &bid); |
|---|
| 1588 | 1845 | } |
|---|
| 1589 | 1846 | |
|---|
| 1590 | 1847 | /* |
|---|
| .. | .. |
|---|
| 1597 | 1854 | bool next_slot = false; |
|---|
| 1598 | 1855 | bool is_reg; |
|---|
| 1599 | 1856 | bool nsexit; |
|---|
| 1857 | + int bfdrc = -1; |
|---|
| 1600 | 1858 | int sirc = -1; |
|---|
| 1601 | 1859 | |
|---|
| 1602 | 1860 | enum dso_binary_type symtab_type = binary_type_symtab[i]; |
|---|
| .. | .. |
|---|
| 1615 | 1873 | nsinfo__mountns_exit(&nsc); |
|---|
| 1616 | 1874 | |
|---|
| 1617 | 1875 | is_reg = is_regular_file(name); |
|---|
| 1876 | +#ifdef HAVE_LIBBFD_SUPPORT |
|---|
| 1618 | 1877 | if (is_reg) |
|---|
| 1878 | + bfdrc = dso__load_bfd_symbols(dso, name); |
|---|
| 1879 | +#endif |
|---|
| 1880 | + if (is_reg && bfdrc < 0) |
|---|
| 1619 | 1881 | sirc = symsrc__init(ss, dso, name, symtab_type); |
|---|
| 1620 | 1882 | |
|---|
| 1621 | 1883 | if (nsexit) |
|---|
| 1622 | 1884 | nsinfo__mountns_enter(dso->nsinfo, &nsc); |
|---|
| 1885 | + |
|---|
| 1886 | + if (bfdrc == 0) { |
|---|
| 1887 | + ret = 0; |
|---|
| 1888 | + break; |
|---|
| 1889 | + } |
|---|
| 1623 | 1890 | |
|---|
| 1624 | 1891 | if (!is_reg || sirc < 0) |
|---|
| 1625 | 1892 | continue; |
|---|
| .. | .. |
|---|
| 1685 | 1952 | return ret; |
|---|
| 1686 | 1953 | } |
|---|
| 1687 | 1954 | |
|---|
| 1688 | | -struct map *map_groups__find_by_name(struct map_groups *mg, const char *name) |
|---|
| 1955 | +static int map__strcmp(const void *a, const void *b) |
|---|
| 1689 | 1956 | { |
|---|
| 1690 | | - struct maps *maps = &mg->maps; |
|---|
| 1957 | + const struct map *ma = *(const struct map **)a, *mb = *(const struct map **)b; |
|---|
| 1958 | + return strcmp(ma->dso->short_name, mb->dso->short_name); |
|---|
| 1959 | +} |
|---|
| 1960 | + |
|---|
| 1961 | +static int map__strcmp_name(const void *name, const void *b) |
|---|
| 1962 | +{ |
|---|
| 1963 | + const struct map *map = *(const struct map **)b; |
|---|
| 1964 | + return strcmp(name, map->dso->short_name); |
|---|
| 1965 | +} |
|---|
| 1966 | + |
|---|
| 1967 | +void __maps__sort_by_name(struct maps *maps) |
|---|
| 1968 | +{ |
|---|
| 1969 | + qsort(maps->maps_by_name, maps->nr_maps, sizeof(struct map *), map__strcmp); |
|---|
| 1970 | +} |
|---|
| 1971 | + |
|---|
| 1972 | +static int map__groups__sort_by_name_from_rbtree(struct maps *maps) |
|---|
| 1973 | +{ |
|---|
| 1974 | + struct map *map; |
|---|
| 1975 | + struct map **maps_by_name = realloc(maps->maps_by_name, maps->nr_maps * sizeof(map)); |
|---|
| 1976 | + int i = 0; |
|---|
| 1977 | + |
|---|
| 1978 | + if (maps_by_name == NULL) |
|---|
| 1979 | + return -1; |
|---|
| 1980 | + |
|---|
| 1981 | + maps->maps_by_name = maps_by_name; |
|---|
| 1982 | + maps->nr_maps_allocated = maps->nr_maps; |
|---|
| 1983 | + |
|---|
| 1984 | + maps__for_each_entry(maps, map) |
|---|
| 1985 | + maps_by_name[i++] = map; |
|---|
| 1986 | + |
|---|
| 1987 | + __maps__sort_by_name(maps); |
|---|
| 1988 | + return 0; |
|---|
| 1989 | +} |
|---|
| 1990 | + |
|---|
| 1991 | +static struct map *__maps__find_by_name(struct maps *maps, const char *name) |
|---|
| 1992 | +{ |
|---|
| 1993 | + struct map **mapp; |
|---|
| 1994 | + |
|---|
| 1995 | + if (maps->maps_by_name == NULL && |
|---|
| 1996 | + map__groups__sort_by_name_from_rbtree(maps)) |
|---|
| 1997 | + return NULL; |
|---|
| 1998 | + |
|---|
| 1999 | + mapp = bsearch(name, maps->maps_by_name, maps->nr_maps, sizeof(*mapp), map__strcmp_name); |
|---|
| 2000 | + if (mapp) |
|---|
| 2001 | + return *mapp; |
|---|
| 2002 | + return NULL; |
|---|
| 2003 | +} |
|---|
| 2004 | + |
|---|
| 2005 | +struct map *maps__find_by_name(struct maps *maps, const char *name) |
|---|
| 2006 | +{ |
|---|
| 1691 | 2007 | struct map *map; |
|---|
| 1692 | 2008 | |
|---|
| 1693 | 2009 | down_read(&maps->lock); |
|---|
| 1694 | 2010 | |
|---|
| 1695 | | - for (map = maps__first(maps); map; map = map__next(map)) { |
|---|
| 1696 | | - if (map->dso && strcmp(map->dso->short_name, name) == 0) |
|---|
| 1697 | | - goto out_unlock; |
|---|
| 2011 | + if (maps->last_search_by_name && strcmp(maps->last_search_by_name->dso->short_name, name) == 0) { |
|---|
| 2012 | + map = maps->last_search_by_name; |
|---|
| 2013 | + goto out_unlock; |
|---|
| 1698 | 2014 | } |
|---|
| 2015 | + /* |
|---|
| 2016 | + * If we have maps->maps_by_name, then the name isn't in the rbtree, |
|---|
| 2017 | + * as maps->maps_by_name mirrors the rbtree when lookups by name are |
|---|
| 2018 | + * made. |
|---|
| 2019 | + */ |
|---|
| 2020 | + map = __maps__find_by_name(maps, name); |
|---|
| 2021 | + if (map || maps->maps_by_name != NULL) |
|---|
| 2022 | + goto out_unlock; |
|---|
| 2023 | + |
|---|
| 2024 | + /* Fallback to traversing the rbtree... */ |
|---|
| 2025 | + maps__for_each_entry(maps, map) |
|---|
| 2026 | + if (strcmp(map->dso->short_name, name) == 0) { |
|---|
| 2027 | + maps->last_search_by_name = map; |
|---|
| 2028 | + goto out_unlock; |
|---|
| 2029 | + } |
|---|
| 1699 | 2030 | |
|---|
| 1700 | 2031 | map = NULL; |
|---|
| 1701 | 2032 | |
|---|
| .. | .. |
|---|
| 1717 | 2048 | else |
|---|
| 1718 | 2049 | symbol__join_symfs(symfs_vmlinux, vmlinux); |
|---|
| 1719 | 2050 | |
|---|
| 1720 | | - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 2051 | + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 1721 | 2052 | symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; |
|---|
| 1722 | 2053 | else |
|---|
| 1723 | 2054 | symtab_type = DSO_BINARY_TYPE__VMLINUX; |
|---|
| .. | .. |
|---|
| 1729 | 2060 | symsrc__destroy(&ss); |
|---|
| 1730 | 2061 | |
|---|
| 1731 | 2062 | if (err > 0) { |
|---|
| 1732 | | - if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
|---|
| 2063 | + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) |
|---|
| 1733 | 2064 | dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX; |
|---|
| 1734 | 2065 | else |
|---|
| 1735 | 2066 | dso->binary_type = DSO_BINARY_TYPE__VMLINUX; |
|---|
| .. | .. |
|---|
| 1816 | 2147 | |
|---|
| 1817 | 2148 | static char *dso__find_kallsyms(struct dso *dso, struct map *map) |
|---|
| 1818 | 2149 | { |
|---|
| 1819 | | - u8 host_build_id[BUILD_ID_SIZE]; |
|---|
| 2150 | + struct build_id bid; |
|---|
| 1820 | 2151 | char sbuild_id[SBUILD_ID_SIZE]; |
|---|
| 1821 | 2152 | bool is_host = false; |
|---|
| 1822 | 2153 | char path[PATH_MAX]; |
|---|
| .. | .. |
|---|
| 1829 | 2160 | goto proc_kallsyms; |
|---|
| 1830 | 2161 | } |
|---|
| 1831 | 2162 | |
|---|
| 1832 | | - if (sysfs__read_build_id("/sys/kernel/notes", host_build_id, |
|---|
| 1833 | | - sizeof(host_build_id)) == 0) |
|---|
| 1834 | | - is_host = dso__build_id_equal(dso, host_build_id); |
|---|
| 2163 | + if (sysfs__read_build_id("/sys/kernel/notes", &bid) == 0) |
|---|
| 2164 | + is_host = dso__build_id_equal(dso, &bid); |
|---|
| 1835 | 2165 | |
|---|
| 1836 | 2166 | /* Try a fast path for /proc/kallsyms if possible */ |
|---|
| 1837 | 2167 | if (is_host) { |
|---|
| .. | .. |
|---|
| 1847 | 2177 | goto proc_kallsyms; |
|---|
| 1848 | 2178 | } |
|---|
| 1849 | 2179 | |
|---|
| 1850 | | - build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); |
|---|
| 2180 | + build_id__sprintf(&dso->bid, sbuild_id); |
|---|
| 1851 | 2181 | |
|---|
| 1852 | 2182 | /* Find kallsyms in build-id cache with kcore */ |
|---|
| 1853 | 2183 | scnprintf(path, sizeof(path), "%s/%s/%s", |
|---|
| .. | .. |
|---|
| 1937 | 2267 | { |
|---|
| 1938 | 2268 | int err; |
|---|
| 1939 | 2269 | const char *kallsyms_filename = NULL; |
|---|
| 1940 | | - struct machine *machine; |
|---|
| 2270 | + struct machine *machine = map__kmaps(map)->machine; |
|---|
| 1941 | 2271 | char path[PATH_MAX]; |
|---|
| 1942 | | - |
|---|
| 1943 | | - if (!map->groups) { |
|---|
| 1944 | | - pr_debug("Guest kernel map hasn't the point to groups\n"); |
|---|
| 1945 | | - return -1; |
|---|
| 1946 | | - } |
|---|
| 1947 | | - machine = map->groups->machine; |
|---|
| 1948 | 2272 | |
|---|
| 1949 | 2273 | if (machine__is_default_guest(machine)) { |
|---|
| 1950 | 2274 | /* |
|---|
| .. | .. |
|---|
| 2093 | 2417 | char line[8]; |
|---|
| 2094 | 2418 | |
|---|
| 2095 | 2419 | if (fgets(line, sizeof(line), fp) != NULL) |
|---|
| 2096 | | - value = ((geteuid() != 0) || (getuid() != 0)) ? |
|---|
| 2097 | | - (atoi(line) != 0) : |
|---|
| 2098 | | - (atoi(line) == 2); |
|---|
| 2420 | + value = perf_cap__capable(CAP_SYSLOG) ? |
|---|
| 2421 | + (atoi(line) >= 2) : |
|---|
| 2422 | + (atoi(line) != 0); |
|---|
| 2099 | 2423 | |
|---|
| 2100 | 2424 | fclose(fp); |
|---|
| 2101 | 2425 | } |
|---|
| 2102 | 2426 | |
|---|
| 2427 | + /* Per kernel/kallsyms.c: |
|---|
| 2428 | + * we also restrict when perf_event_paranoid > 1 w/o CAP_SYSLOG |
|---|
| 2429 | + */ |
|---|
| 2430 | + if (perf_event_paranoid() > 1 && !perf_cap__capable(CAP_SYSLOG)) |
|---|
| 2431 | + value = true; |
|---|
| 2432 | + |
|---|
| 2103 | 2433 | return value; |
|---|
| 2104 | 2434 | } |
|---|
| 2105 | 2435 | |
|---|