1 // SPDX-License-Identifier: GPL-2.0 2 #include <errno.h> 3 #include <linux/kernel.h> 4 #include <linux/types.h> 5 #include <inttypes.h> 6 #include <stdlib.h> 7 #include <unistd.h> 8 #include <stdio.h> 9 #include <string.h> 10 #include <sys/param.h> 11 #include <perf/cpumap.h> 12 #include <perf/evlist.h> 13 14 #include "parse-events.h" 15 #include "evlist.h" 16 #include "evsel.h" 17 #include "thread_map.h" 18 #include "cpumap.h" 19 #include "machine.h" 20 #include "map.h" 21 #include "symbol.h" 22 #include "event.h" 23 #include "thread.h" 24 25 #include "tests.h" 26 27 #include <linux/ctype.h> 28 29 #define BUFSZ 1024 30 #define READLEN 128 31 32 struct state { 33 u64 done[1024]; 34 size_t done_cnt; 35 }; 36 37 static unsigned int hex(char c) 38 { 39 if (c >= '0' && c <= '9') 40 return c - '0'; 41 if (c >= 'a' && c <= 'f') 42 return c - 'a' + 10; 43 return c - 'A' + 10; 44 } 45 46 static size_t read_objdump_chunk(const char **line, unsigned char **buf, 47 size_t *buf_len) 48 { 49 size_t bytes_read = 0; 50 unsigned char *chunk_start = *buf; 51 52 /* Read bytes */ 53 while (*buf_len > 0) { 54 char c1, c2; 55 56 /* Get 2 hex digits */ 57 c1 = *(*line)++; 58 if (!isxdigit(c1)) 59 break; 60 c2 = *(*line)++; 61 if (!isxdigit(c2)) 62 break; 63 64 /* Store byte and advance buf */ 65 **buf = (hex(c1) << 4) | hex(c2); 66 (*buf)++; 67 (*buf_len)--; 68 bytes_read++; 69 70 /* End of chunk? */ 71 if (isspace(**line)) 72 break; 73 } 74 75 /* 76 * objdump will display raw insn as LE if code endian 77 * is LE and bytes_per_chunk > 1. In that case reverse 78 * the chunk we just read. 79 * 80 * see disassemble_bytes() at binutils/objdump.c for details 81 * how objdump chooses display endian) 82 */ 83 if (bytes_read > 1 && !bigendian()) { 84 unsigned char *chunk_end = chunk_start + bytes_read - 1; 85 unsigned char tmp; 86 87 while (chunk_start < chunk_end) { 88 tmp = *chunk_start; 89 *chunk_start = *chunk_end; 90 *chunk_end = tmp; 91 chunk_start++; 92 chunk_end--; 93 } 94 } 95 96 return bytes_read; 97 } 98 99 static size_t read_objdump_line(const char *line, unsigned char *buf, 100 size_t buf_len) 101 { 102 const char *p; 103 size_t ret, bytes_read = 0; 104 105 /* Skip to a colon */ 106 p = strchr(line, ':'); 107 if (!p) 108 return 0; 109 p++; 110 111 /* Skip initial spaces */ 112 while (*p) { 113 if (!isspace(*p)) 114 break; 115 p++; 116 } 117 118 do { 119 ret = read_objdump_chunk(&p, &buf, &buf_len); 120 bytes_read += ret; 121 p++; 122 } while (ret > 0); 123 124 /* return number of successfully read bytes */ 125 return bytes_read; 126 } 127 128 static int read_objdump_output(FILE *f, void *buf, size_t *len, u64 start_addr) 129 { 130 char *line = NULL; 131 size_t line_len, off_last = 0; 132 ssize_t ret; 133 int err = 0; 134 u64 addr, last_addr = start_addr; 135 136 while (off_last < *len) { 137 size_t off, read_bytes, written_bytes; 138 unsigned char tmp[BUFSZ]; 139 140 ret = getline(&line, &line_len, f); 141 if (feof(f)) 142 break; 143 if (ret < 0) { 144 pr_debug("getline failed\n"); 145 err = -1; 146 break; 147 } 148 149 /* read objdump data into temporary buffer */ 150 read_bytes = read_objdump_line(line, tmp, sizeof(tmp)); 151 if (!read_bytes) 152 continue; 153 154 if (sscanf(line, "%"PRIx64, &addr) != 1) 155 continue; 156 if (addr < last_addr) { 157 pr_debug("addr going backwards, read beyond section?\n"); 158 break; 159 } 160 last_addr = addr; 161 162 /* copy it from temporary buffer to 'buf' according 163 * to address on current objdump line */ 164 off = addr - start_addr; 165 if (off >= *len) 166 break; 167 written_bytes = MIN(read_bytes, *len - off); 168 memcpy(buf + off, tmp, written_bytes); 169 off_last = off + written_bytes; 170 } 171 172 /* len returns number of bytes that could not be read */ 173 *len -= off_last; 174 175 free(line); 176 177 return err; 178 } 179 180 static int read_via_objdump(const char *filename, u64 addr, void *buf, 181 size_t len) 182 { 183 char cmd[PATH_MAX * 2]; 184 const char *fmt; 185 FILE *f; 186 int ret; 187 188 fmt = "%s -z -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s"; 189 ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len, 190 filename); 191 if (ret <= 0 || (size_t)ret >= sizeof(cmd)) 192 return -1; 193 194 pr_debug("Objdump command is: %s\n", cmd); 195 196 /* Ignore objdump errors */ 197 strcat(cmd, " 2>/dev/null"); 198 199 f = popen(cmd, "r"); 200 if (!f) { 201 pr_debug("popen failed\n"); 202 return -1; 203 } 204 205 ret = read_objdump_output(f, buf, &len, addr); 206 if (len) { 207 pr_debug("objdump read too few bytes: %zd\n", len); 208 if (!ret) 209 ret = len; 210 } 211 212 pclose(f); 213 214 return ret; 215 } 216 217 static void dump_buf(unsigned char *buf, size_t len) 218 { 219 size_t i; 220 221 for (i = 0; i < len; i++) { 222 pr_debug("0x%02x ", buf[i]); 223 if (i % 16 == 15) 224 pr_debug("\n"); 225 } 226 pr_debug("\n"); 227 } 228 229 static int read_object_code(u64 addr, size_t len, u8 cpumode, 230 struct thread *thread, struct state *state) 231 { 232 struct addr_location al; 233 unsigned char buf1[BUFSZ]; 234 unsigned char buf2[BUFSZ]; 235 size_t ret_len; 236 u64 objdump_addr; 237 const char *objdump_name; 238 char decomp_name[KMOD_DECOMP_LEN]; 239 bool decomp = false; 240 int ret; 241 242 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); 243 244 if (!thread__find_map(thread, cpumode, addr, &al) || !al.map->dso) { 245 if (cpumode == PERF_RECORD_MISC_HYPERVISOR) { 246 pr_debug("Hypervisor address can not be resolved - skipping\n"); 247 return 0; 248 } 249 250 pr_debug("thread__find_map failed\n"); 251 return -1; 252 } 253 254 pr_debug("File is: %s\n", al.map->dso->long_name); 255 256 if (al.map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 257 !dso__is_kcore(al.map->dso)) { 258 pr_debug("Unexpected kernel address - skipping\n"); 259 return 0; 260 } 261 262 pr_debug("On file address is: %#"PRIx64"\n", al.addr); 263 264 if (len > BUFSZ) 265 len = BUFSZ; 266 267 /* Do not go off the map */ 268 if (addr + len > al.map->end) 269 len = al.map->end - addr; 270 271 /* Read the object code using perf */ 272 ret_len = dso__data_read_offset(al.map->dso, thread->mg->machine, 273 al.addr, buf1, len); 274 if (ret_len != len) { 275 pr_debug("dso__data_read_offset failed\n"); 276 return -1; 277 } 278 279 /* 280 * Converting addresses for use by objdump requires more information. 281 * map__load() does that. See map__rip_2objdump() for details. 282 */ 283 if (map__load(al.map)) 284 return -1; 285 286 /* objdump struggles with kcore - try each map only once */ 287 if (dso__is_kcore(al.map->dso)) { 288 size_t d; 289 290 for (d = 0; d < state->done_cnt; d++) { 291 if (state->done[d] == al.map->start) { 292 pr_debug("kcore map tested already"); 293 pr_debug(" - skipping\n"); 294 return 0; 295 } 296 } 297 if (state->done_cnt >= ARRAY_SIZE(state->done)) { 298 pr_debug("Too many kcore maps - skipping\n"); 299 return 0; 300 } 301 state->done[state->done_cnt++] = al.map->start; 302 } 303 304 objdump_name = al.map->dso->long_name; 305 if (dso__needs_decompress(al.map->dso)) { 306 if (dso__decompress_kmodule_path(al.map->dso, objdump_name, 307 decomp_name, 308 sizeof(decomp_name)) < 0) { 309 pr_debug("decompression failed\n"); 310 return -1; 311 } 312 313 decomp = true; 314 objdump_name = decomp_name; 315 } 316 317 /* Read the object code using objdump */ 318 objdump_addr = map__rip_2objdump(al.map, al.addr); 319 ret = read_via_objdump(objdump_name, objdump_addr, buf2, len); 320 321 if (decomp) 322 unlink(objdump_name); 323 324 if (ret > 0) { 325 /* 326 * The kernel maps are inaccurate - assume objdump is right in 327 * that case. 328 */ 329 if (cpumode == PERF_RECORD_MISC_KERNEL || 330 cpumode == PERF_RECORD_MISC_GUEST_KERNEL) { 331 len -= ret; 332 if (len) { 333 pr_debug("Reducing len to %zu\n", len); 334 } else if (dso__is_kcore(al.map->dso)) { 335 /* 336 * objdump cannot handle very large segments 337 * that may be found in kcore. 338 */ 339 pr_debug("objdump failed for kcore"); 340 pr_debug(" - skipping\n"); 341 return 0; 342 } else { 343 return -1; 344 } 345 } 346 } 347 if (ret < 0) { 348 pr_debug("read_via_objdump failed\n"); 349 return -1; 350 } 351 352 /* The results should be identical */ 353 if (memcmp(buf1, buf2, len)) { 354 pr_debug("Bytes read differ from those read by objdump\n"); 355 pr_debug("buf1 (dso):\n"); 356 dump_buf(buf1, len); 357 pr_debug("buf2 (objdump):\n"); 358 dump_buf(buf2, len); 359 return -1; 360 } 361 pr_debug("Bytes read match those read by objdump\n"); 362 363 return 0; 364 } 365 366 static int process_sample_event(struct machine *machine, 367 struct evlist *evlist, 368 union perf_event *event, struct state *state) 369 { 370 struct perf_sample sample; 371 struct thread *thread; 372 int ret; 373 374 if (perf_evlist__parse_sample(evlist, event, &sample)) { 375 pr_debug("perf_evlist__parse_sample failed\n"); 376 return -1; 377 } 378 379 thread = machine__findnew_thread(machine, sample.pid, sample.tid); 380 if (!thread) { 381 pr_debug("machine__findnew_thread failed\n"); 382 return -1; 383 } 384 385 ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread, state); 386 thread__put(thread); 387 return ret; 388 } 389 390 static int process_event(struct machine *machine, struct evlist *evlist, 391 union perf_event *event, struct state *state) 392 { 393 if (event->header.type == PERF_RECORD_SAMPLE) 394 return process_sample_event(machine, evlist, event, state); 395 396 if (event->header.type == PERF_RECORD_THROTTLE || 397 event->header.type == PERF_RECORD_UNTHROTTLE) 398 return 0; 399 400 if (event->header.type < PERF_RECORD_MAX) { 401 int ret; 402 403 ret = machine__process_event(machine, event, NULL); 404 if (ret < 0) 405 pr_debug("machine__process_event failed, event type %u\n", 406 event->header.type); 407 return ret; 408 } 409 410 return 0; 411 } 412 413 static int process_events(struct machine *machine, struct evlist *evlist, 414 struct state *state) 415 { 416 union perf_event *event; 417 struct perf_mmap *md; 418 int i, ret; 419 420 for (i = 0; i < evlist->nr_mmaps; i++) { 421 md = &evlist->mmap[i]; 422 if (perf_mmap__read_init(md) < 0) 423 continue; 424 425 while ((event = perf_mmap__read_event(md)) != NULL) { 426 ret = process_event(machine, evlist, event, state); 427 perf_mmap__consume(md); 428 if (ret < 0) 429 return ret; 430 } 431 perf_mmap__read_done(md); 432 } 433 return 0; 434 } 435 436 static int comp(const void *a, const void *b) 437 { 438 return *(int *)a - *(int *)b; 439 } 440 441 static void do_sort_something(void) 442 { 443 int buf[40960], i; 444 445 for (i = 0; i < (int)ARRAY_SIZE(buf); i++) 446 buf[i] = ARRAY_SIZE(buf) - i - 1; 447 448 qsort(buf, ARRAY_SIZE(buf), sizeof(int), comp); 449 450 for (i = 0; i < (int)ARRAY_SIZE(buf); i++) { 451 if (buf[i] != i) { 452 pr_debug("qsort failed\n"); 453 break; 454 } 455 } 456 } 457 458 static void sort_something(void) 459 { 460 int i; 461 462 for (i = 0; i < 10; i++) 463 do_sort_something(); 464 } 465 466 static void syscall_something(void) 467 { 468 int pipefd[2]; 469 int i; 470 471 for (i = 0; i < 1000; i++) { 472 if (pipe(pipefd) < 0) { 473 pr_debug("pipe failed\n"); 474 break; 475 } 476 close(pipefd[1]); 477 close(pipefd[0]); 478 } 479 } 480 481 static void fs_something(void) 482 { 483 const char *test_file_name = "temp-perf-code-reading-test-file--"; 484 FILE *f; 485 int i; 486 487 for (i = 0; i < 1000; i++) { 488 f = fopen(test_file_name, "w+"); 489 if (f) { 490 fclose(f); 491 unlink(test_file_name); 492 } 493 } 494 } 495 496 static const char *do_determine_event(bool excl_kernel) 497 { 498 const char *event = excl_kernel ? "cycles:u" : "cycles"; 499 500 #ifdef __s390x__ 501 char cpuid[128], model[16], model_c[16], cpum_cf_v[16]; 502 unsigned int family; 503 int ret, cpum_cf_a; 504 505 if (get_cpuid(cpuid, sizeof(cpuid))) 506 goto out_clocks; 507 ret = sscanf(cpuid, "%*[^,],%u,%[^,],%[^,],%[^,],%x", &family, model_c, 508 model, cpum_cf_v, &cpum_cf_a); 509 if (ret != 5) /* Not available */ 510 goto out_clocks; 511 if (excl_kernel && (cpum_cf_a & 4)) 512 return event; 513 if (!excl_kernel && (cpum_cf_a & 2)) 514 return event; 515 516 /* Fall through: missing authorization */ 517 out_clocks: 518 event = excl_kernel ? "cpu-clock:u" : "cpu-clock"; 519 520 #endif 521 return event; 522 } 523 524 static void do_something(void) 525 { 526 fs_something(); 527 528 sort_something(); 529 530 syscall_something(); 531 } 532 533 enum { 534 TEST_CODE_READING_OK, 535 TEST_CODE_READING_NO_VMLINUX, 536 TEST_CODE_READING_NO_KCORE, 537 TEST_CODE_READING_NO_ACCESS, 538 TEST_CODE_READING_NO_KERNEL_OBJ, 539 }; 540 541 static int do_test_code_reading(bool try_kcore) 542 { 543 struct machine *machine; 544 struct thread *thread; 545 struct record_opts opts = { 546 .mmap_pages = UINT_MAX, 547 .user_freq = UINT_MAX, 548 .user_interval = ULLONG_MAX, 549 .freq = 500, 550 .target = { 551 .uses_mmap = true, 552 }, 553 }; 554 struct state state = { 555 .done_cnt = 0, 556 }; 557 struct perf_thread_map *threads = NULL; 558 struct perf_cpu_map *cpus = NULL; 559 struct evlist *evlist = NULL; 560 struct evsel *evsel = NULL; 561 int err = -1, ret; 562 pid_t pid; 563 struct map *map; 564 bool have_vmlinux, have_kcore, excl_kernel = false; 565 566 pid = getpid(); 567 568 machine = machine__new_host(); 569 machine->env = &perf_env; 570 571 ret = machine__create_kernel_maps(machine); 572 if (ret < 0) { 573 pr_debug("machine__create_kernel_maps failed\n"); 574 goto out_err; 575 } 576 577 /* Force the use of kallsyms instead of vmlinux to try kcore */ 578 if (try_kcore) 579 symbol_conf.kallsyms_name = "/proc/kallsyms"; 580 581 /* Load kernel map */ 582 map = machine__kernel_map(machine); 583 ret = map__load(map); 584 if (ret < 0) { 585 pr_debug("map__load failed\n"); 586 goto out_err; 587 } 588 have_vmlinux = dso__is_vmlinux(map->dso); 589 have_kcore = dso__is_kcore(map->dso); 590 591 /* 2nd time through we just try kcore */ 592 if (try_kcore && !have_kcore) 593 return TEST_CODE_READING_NO_KCORE; 594 595 /* No point getting kernel events if there is no kernel object */ 596 if (!have_vmlinux && !have_kcore) 597 excl_kernel = true; 598 599 threads = thread_map__new_by_tid(pid); 600 if (!threads) { 601 pr_debug("thread_map__new_by_tid failed\n"); 602 goto out_err; 603 } 604 605 ret = perf_event__synthesize_thread_map(NULL, threads, 606 perf_event__process, machine, false); 607 if (ret < 0) { 608 pr_debug("perf_event__synthesize_thread_map failed\n"); 609 goto out_err; 610 } 611 612 thread = machine__findnew_thread(machine, pid, pid); 613 if (!thread) { 614 pr_debug("machine__findnew_thread failed\n"); 615 goto out_put; 616 } 617 618 cpus = perf_cpu_map__new(NULL); 619 if (!cpus) { 620 pr_debug("perf_cpu_map__new failed\n"); 621 goto out_put; 622 } 623 624 while (1) { 625 const char *str; 626 627 evlist = evlist__new(); 628 if (!evlist) { 629 pr_debug("perf_evlist__new failed\n"); 630 goto out_put; 631 } 632 633 perf_evlist__set_maps(&evlist->core, cpus, threads); 634 635 str = do_determine_event(excl_kernel); 636 pr_debug("Parsing event '%s'\n", str); 637 ret = parse_events(evlist, str, NULL); 638 if (ret < 0) { 639 pr_debug("parse_events failed\n"); 640 goto out_put; 641 } 642 643 perf_evlist__config(evlist, &opts, NULL); 644 645 evsel = perf_evlist__first(evlist); 646 647 evsel->core.attr.comm = 1; 648 evsel->core.attr.disabled = 1; 649 evsel->core.attr.enable_on_exec = 0; 650 651 ret = evlist__open(evlist); 652 if (ret < 0) { 653 if (!excl_kernel) { 654 excl_kernel = true; 655 /* 656 * Both cpus and threads are now owned by evlist 657 * and will be freed by following perf_evlist__set_maps 658 * call. Getting refference to keep them alive. 659 */ 660 perf_cpu_map__get(cpus); 661 perf_thread_map__get(threads); 662 perf_evlist__set_maps(&evlist->core, NULL, NULL); 663 evlist__delete(evlist); 664 evlist = NULL; 665 continue; 666 } 667 668 if (verbose > 0) { 669 char errbuf[512]; 670 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); 671 pr_debug("perf_evlist__open() failed!\n%s\n", errbuf); 672 } 673 674 goto out_put; 675 } 676 break; 677 } 678 679 ret = perf_evlist__mmap(evlist, UINT_MAX); 680 if (ret < 0) { 681 pr_debug("perf_evlist__mmap failed\n"); 682 goto out_put; 683 } 684 685 evlist__enable(evlist); 686 687 do_something(); 688 689 evlist__disable(evlist); 690 691 ret = process_events(machine, evlist, &state); 692 if (ret < 0) 693 goto out_put; 694 695 if (!have_vmlinux && !have_kcore && !try_kcore) 696 err = TEST_CODE_READING_NO_KERNEL_OBJ; 697 else if (!have_vmlinux && !try_kcore) 698 err = TEST_CODE_READING_NO_VMLINUX; 699 else if (excl_kernel) 700 err = TEST_CODE_READING_NO_ACCESS; 701 else 702 err = TEST_CODE_READING_OK; 703 out_put: 704 thread__put(thread); 705 out_err: 706 707 if (evlist) { 708 evlist__delete(evlist); 709 } else { 710 perf_cpu_map__put(cpus); 711 perf_thread_map__put(threads); 712 } 713 machine__delete_threads(machine); 714 machine__delete(machine); 715 716 return err; 717 } 718 719 int test__code_reading(struct test *test __maybe_unused, int subtest __maybe_unused) 720 { 721 int ret; 722 723 ret = do_test_code_reading(false); 724 if (!ret) 725 ret = do_test_code_reading(true); 726 727 switch (ret) { 728 case TEST_CODE_READING_OK: 729 return 0; 730 case TEST_CODE_READING_NO_VMLINUX: 731 pr_debug("no vmlinux\n"); 732 return 0; 733 case TEST_CODE_READING_NO_KCORE: 734 pr_debug("no kcore\n"); 735 return 0; 736 case TEST_CODE_READING_NO_ACCESS: 737 pr_debug("no access\n"); 738 return 0; 739 case TEST_CODE_READING_NO_KERNEL_OBJ: 740 pr_debug("no kernel obj\n"); 741 return 0; 742 default: 743 return -1; 744 }; 745 } 746