1 #include <sys/types.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <stdio.h> 5 #include <inttypes.h> 6 #include <ctype.h> 7 #include <string.h> 8 9 #include "parse-events.h" 10 #include "evlist.h" 11 #include "evsel.h" 12 #include "thread_map.h" 13 #include "cpumap.h" 14 #include "machine.h" 15 #include "event.h" 16 #include "thread.h" 17 18 #include "tests.h" 19 20 #define BUFSZ 1024 21 #define READLEN 128 22 23 struct state { 24 u64 done[1024]; 25 size_t done_cnt; 26 }; 27 28 static unsigned int hex(char c) 29 { 30 if (c >= '0' && c <= '9') 31 return c - '0'; 32 if (c >= 'a' && c <= 'f') 33 return c - 'a' + 10; 34 return c - 'A' + 10; 35 } 36 37 static void read_objdump_line(const char *line, size_t line_len, void **buf, 38 size_t *len) 39 { 40 const char *p; 41 size_t i; 42 43 /* Skip to a colon */ 44 p = strchr(line, ':'); 45 if (!p) 46 return; 47 i = p + 1 - line; 48 49 /* Read bytes */ 50 while (*len) { 51 char c1, c2; 52 53 /* Skip spaces */ 54 for (; i < line_len; i++) { 55 if (!isspace(line[i])) 56 break; 57 } 58 /* Get 2 hex digits */ 59 if (i >= line_len || !isxdigit(line[i])) 60 break; 61 c1 = line[i++]; 62 if (i >= line_len || !isxdigit(line[i])) 63 break; 64 c2 = line[i++]; 65 /* Followed by a space */ 66 if (i < line_len && line[i] && !isspace(line[i])) 67 break; 68 /* Store byte */ 69 *(unsigned char *)*buf = (hex(c1) << 4) | hex(c2); 70 *buf += 1; 71 *len -= 1; 72 } 73 } 74 75 static int read_objdump_output(FILE *f, void **buf, size_t *len) 76 { 77 char *line = NULL; 78 size_t line_len; 79 ssize_t ret; 80 int err = 0; 81 82 while (1) { 83 ret = getline(&line, &line_len, f); 84 if (feof(f)) 85 break; 86 if (ret < 0) { 87 pr_debug("getline failed\n"); 88 err = -1; 89 break; 90 } 91 read_objdump_line(line, ret, buf, len); 92 } 93 94 free(line); 95 96 return err; 97 } 98 99 static int read_via_objdump(const char *filename, u64 addr, void *buf, 100 size_t len) 101 { 102 char cmd[PATH_MAX * 2]; 103 const char *fmt; 104 FILE *f; 105 int ret; 106 107 fmt = "%s -d --start-address=0x%"PRIx64" --stop-address=0x%"PRIx64" %s"; 108 ret = snprintf(cmd, sizeof(cmd), fmt, "objdump", addr, addr + len, 109 filename); 110 if (ret <= 0 || (size_t)ret >= sizeof(cmd)) 111 return -1; 112 113 pr_debug("Objdump command is: %s\n", cmd); 114 115 /* Ignore objdump errors */ 116 strcat(cmd, " 2>/dev/null"); 117 118 f = popen(cmd, "r"); 119 if (!f) { 120 pr_debug("popen failed\n"); 121 return -1; 122 } 123 124 ret = read_objdump_output(f, &buf, &len); 125 if (len) { 126 pr_debug("objdump read too few bytes\n"); 127 if (!ret) 128 ret = len; 129 } 130 131 pclose(f); 132 133 return ret; 134 } 135 136 static int read_object_code(u64 addr, size_t len, u8 cpumode, 137 struct thread *thread, struct machine *machine, 138 struct state *state) 139 { 140 struct addr_location al; 141 unsigned char buf1[BUFSZ]; 142 unsigned char buf2[BUFSZ]; 143 size_t ret_len; 144 u64 objdump_addr; 145 int ret; 146 147 pr_debug("Reading object code for memory address: %#"PRIx64"\n", addr); 148 149 thread__find_addr_map(thread, machine, cpumode, MAP__FUNCTION, addr, 150 &al); 151 if (!al.map || !al.map->dso) { 152 pr_debug("thread__find_addr_map failed\n"); 153 return -1; 154 } 155 156 pr_debug("File is: %s\n", al.map->dso->long_name); 157 158 if (al.map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 159 !dso__is_kcore(al.map->dso)) { 160 pr_debug("Unexpected kernel address - skipping\n"); 161 return 0; 162 } 163 164 pr_debug("On file address is: %#"PRIx64"\n", al.addr); 165 166 if (len > BUFSZ) 167 len = BUFSZ; 168 169 /* Do not go off the map */ 170 if (addr + len > al.map->end) 171 len = al.map->end - addr; 172 173 /* Read the object code using perf */ 174 ret_len = dso__data_read_offset(al.map->dso, machine, al.addr, buf1, 175 len); 176 if (ret_len != len) { 177 pr_debug("dso__data_read_offset failed\n"); 178 return -1; 179 } 180 181 /* 182 * Converting addresses for use by objdump requires more information. 183 * map__load() does that. See map__rip_2objdump() for details. 184 */ 185 if (map__load(al.map, NULL)) 186 return -1; 187 188 /* objdump struggles with kcore - try each map only once */ 189 if (dso__is_kcore(al.map->dso)) { 190 size_t d; 191 192 for (d = 0; d < state->done_cnt; d++) { 193 if (state->done[d] == al.map->start) { 194 pr_debug("kcore map tested already"); 195 pr_debug(" - skipping\n"); 196 return 0; 197 } 198 } 199 if (state->done_cnt >= ARRAY_SIZE(state->done)) { 200 pr_debug("Too many kcore maps - skipping\n"); 201 return 0; 202 } 203 state->done[state->done_cnt++] = al.map->start; 204 } 205 206 /* Read the object code using objdump */ 207 objdump_addr = map__rip_2objdump(al.map, al.addr); 208 ret = read_via_objdump(al.map->dso->long_name, objdump_addr, buf2, len); 209 if (ret > 0) { 210 /* 211 * The kernel maps are inaccurate - assume objdump is right in 212 * that case. 213 */ 214 if (cpumode == PERF_RECORD_MISC_KERNEL || 215 cpumode == PERF_RECORD_MISC_GUEST_KERNEL) { 216 len -= ret; 217 if (len) { 218 pr_debug("Reducing len to %zu\n", len); 219 } else if (dso__is_kcore(al.map->dso)) { 220 /* 221 * objdump cannot handle very large segments 222 * that may be found in kcore. 223 */ 224 pr_debug("objdump failed for kcore"); 225 pr_debug(" - skipping\n"); 226 return 0; 227 } else { 228 return -1; 229 } 230 } 231 } 232 if (ret < 0) { 233 pr_debug("read_via_objdump failed\n"); 234 return -1; 235 } 236 237 /* The results should be identical */ 238 if (memcmp(buf1, buf2, len)) { 239 pr_debug("Bytes read differ from those read by objdump\n"); 240 return -1; 241 } 242 pr_debug("Bytes read match those read by objdump\n"); 243 244 return 0; 245 } 246 247 static int process_sample_event(struct machine *machine, 248 struct perf_evlist *evlist, 249 union perf_event *event, struct state *state) 250 { 251 struct perf_sample sample; 252 struct thread *thread; 253 u8 cpumode; 254 255 if (perf_evlist__parse_sample(evlist, event, &sample)) { 256 pr_debug("perf_evlist__parse_sample failed\n"); 257 return -1; 258 } 259 260 thread = machine__findnew_thread(machine, sample.pid, sample.pid); 261 if (!thread) { 262 pr_debug("machine__findnew_thread failed\n"); 263 return -1; 264 } 265 266 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 267 268 return read_object_code(sample.ip, READLEN, cpumode, thread, machine, 269 state); 270 } 271 272 static int process_event(struct machine *machine, struct perf_evlist *evlist, 273 union perf_event *event, struct state *state) 274 { 275 if (event->header.type == PERF_RECORD_SAMPLE) 276 return process_sample_event(machine, evlist, event, state); 277 278 if (event->header.type < PERF_RECORD_MAX) 279 return machine__process_event(machine, event); 280 281 return 0; 282 } 283 284 static int process_events(struct machine *machine, struct perf_evlist *evlist, 285 struct state *state) 286 { 287 union perf_event *event; 288 int i, ret; 289 290 for (i = 0; i < evlist->nr_mmaps; i++) { 291 while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { 292 ret = process_event(machine, evlist, event, state); 293 if (ret < 0) 294 return ret; 295 } 296 } 297 return 0; 298 } 299 300 static int comp(const void *a, const void *b) 301 { 302 return *(int *)a - *(int *)b; 303 } 304 305 static void do_sort_something(void) 306 { 307 int buf[40960], i; 308 309 for (i = 0; i < (int)ARRAY_SIZE(buf); i++) 310 buf[i] = ARRAY_SIZE(buf) - i - 1; 311 312 qsort(buf, ARRAY_SIZE(buf), sizeof(int), comp); 313 314 for (i = 0; i < (int)ARRAY_SIZE(buf); i++) { 315 if (buf[i] != i) { 316 pr_debug("qsort failed\n"); 317 break; 318 } 319 } 320 } 321 322 static void sort_something(void) 323 { 324 int i; 325 326 for (i = 0; i < 10; i++) 327 do_sort_something(); 328 } 329 330 static void syscall_something(void) 331 { 332 int pipefd[2]; 333 int i; 334 335 for (i = 0; i < 1000; i++) { 336 if (pipe(pipefd) < 0) { 337 pr_debug("pipe failed\n"); 338 break; 339 } 340 close(pipefd[1]); 341 close(pipefd[0]); 342 } 343 } 344 345 static void fs_something(void) 346 { 347 const char *test_file_name = "temp-perf-code-reading-test-file--"; 348 FILE *f; 349 int i; 350 351 for (i = 0; i < 1000; i++) { 352 f = fopen(test_file_name, "w+"); 353 if (f) { 354 fclose(f); 355 unlink(test_file_name); 356 } 357 } 358 } 359 360 static void do_something(void) 361 { 362 fs_something(); 363 364 sort_something(); 365 366 syscall_something(); 367 } 368 369 enum { 370 TEST_CODE_READING_OK, 371 TEST_CODE_READING_NO_VMLINUX, 372 TEST_CODE_READING_NO_KCORE, 373 TEST_CODE_READING_NO_ACCESS, 374 TEST_CODE_READING_NO_KERNEL_OBJ, 375 }; 376 377 static int do_test_code_reading(bool try_kcore) 378 { 379 struct machines machines; 380 struct machine *machine; 381 struct thread *thread; 382 struct perf_record_opts opts = { 383 .mmap_pages = UINT_MAX, 384 .user_freq = UINT_MAX, 385 .user_interval = ULLONG_MAX, 386 .freq = 4000, 387 .target = { 388 .uses_mmap = true, 389 }, 390 }; 391 struct state state = { 392 .done_cnt = 0, 393 }; 394 struct thread_map *threads = NULL; 395 struct cpu_map *cpus = NULL; 396 struct perf_evlist *evlist = NULL; 397 struct perf_evsel *evsel = NULL; 398 int err = -1, ret; 399 pid_t pid; 400 struct map *map; 401 bool have_vmlinux, have_kcore, excl_kernel = false; 402 403 pid = getpid(); 404 405 machines__init(&machines); 406 machine = &machines.host; 407 408 ret = machine__create_kernel_maps(machine); 409 if (ret < 0) { 410 pr_debug("machine__create_kernel_maps failed\n"); 411 goto out_err; 412 } 413 414 /* Force the use of kallsyms instead of vmlinux to try kcore */ 415 if (try_kcore) 416 symbol_conf.kallsyms_name = "/proc/kallsyms"; 417 418 /* Load kernel map */ 419 map = machine->vmlinux_maps[MAP__FUNCTION]; 420 ret = map__load(map, NULL); 421 if (ret < 0) { 422 pr_debug("map__load failed\n"); 423 goto out_err; 424 } 425 have_vmlinux = dso__is_vmlinux(map->dso); 426 have_kcore = dso__is_kcore(map->dso); 427 428 /* 2nd time through we just try kcore */ 429 if (try_kcore && !have_kcore) 430 return TEST_CODE_READING_NO_KCORE; 431 432 /* No point getting kernel events if there is no kernel object */ 433 if (!have_vmlinux && !have_kcore) 434 excl_kernel = true; 435 436 threads = thread_map__new_by_tid(pid); 437 if (!threads) { 438 pr_debug("thread_map__new_by_tid failed\n"); 439 goto out_err; 440 } 441 442 ret = perf_event__synthesize_thread_map(NULL, threads, 443 perf_event__process, machine); 444 if (ret < 0) { 445 pr_debug("perf_event__synthesize_thread_map failed\n"); 446 goto out_err; 447 } 448 449 thread = machine__findnew_thread(machine, pid, pid); 450 if (!thread) { 451 pr_debug("machine__findnew_thread failed\n"); 452 goto out_err; 453 } 454 455 cpus = cpu_map__new(NULL); 456 if (!cpus) { 457 pr_debug("cpu_map__new failed\n"); 458 goto out_err; 459 } 460 461 while (1) { 462 const char *str; 463 464 evlist = perf_evlist__new(); 465 if (!evlist) { 466 pr_debug("perf_evlist__new failed\n"); 467 goto out_err; 468 } 469 470 perf_evlist__set_maps(evlist, cpus, threads); 471 472 if (excl_kernel) 473 str = "cycles:u"; 474 else 475 str = "cycles"; 476 pr_debug("Parsing event '%s'\n", str); 477 ret = parse_events(evlist, str); 478 if (ret < 0) { 479 pr_debug("parse_events failed\n"); 480 goto out_err; 481 } 482 483 perf_evlist__config(evlist, &opts); 484 485 evsel = perf_evlist__first(evlist); 486 487 evsel->attr.comm = 1; 488 evsel->attr.disabled = 1; 489 evsel->attr.enable_on_exec = 0; 490 491 ret = perf_evlist__open(evlist); 492 if (ret < 0) { 493 if (!excl_kernel) { 494 excl_kernel = true; 495 perf_evlist__delete(evlist); 496 evlist = NULL; 497 continue; 498 } 499 pr_debug("perf_evlist__open failed\n"); 500 goto out_err; 501 } 502 break; 503 } 504 505 ret = perf_evlist__mmap(evlist, UINT_MAX, false); 506 if (ret < 0) { 507 pr_debug("perf_evlist__mmap failed\n"); 508 goto out_err; 509 } 510 511 perf_evlist__enable(evlist); 512 513 do_something(); 514 515 perf_evlist__disable(evlist); 516 517 ret = process_events(machine, evlist, &state); 518 if (ret < 0) 519 goto out_err; 520 521 if (!have_vmlinux && !have_kcore && !try_kcore) 522 err = TEST_CODE_READING_NO_KERNEL_OBJ; 523 else if (!have_vmlinux && !try_kcore) 524 err = TEST_CODE_READING_NO_VMLINUX; 525 else if (excl_kernel) 526 err = TEST_CODE_READING_NO_ACCESS; 527 else 528 err = TEST_CODE_READING_OK; 529 out_err: 530 if (evlist) { 531 perf_evlist__munmap(evlist); 532 perf_evlist__close(evlist); 533 perf_evlist__delete(evlist); 534 } 535 if (cpus) 536 cpu_map__delete(cpus); 537 if (threads) 538 thread_map__delete(threads); 539 machines__destroy_kernel_maps(&machines); 540 machine__delete_threads(machine); 541 machines__exit(&machines); 542 543 return err; 544 } 545 546 int test__code_reading(void) 547 { 548 int ret; 549 550 ret = do_test_code_reading(false); 551 if (!ret) 552 ret = do_test_code_reading(true); 553 554 switch (ret) { 555 case TEST_CODE_READING_OK: 556 return 0; 557 case TEST_CODE_READING_NO_VMLINUX: 558 fprintf(stderr, " (no vmlinux)"); 559 return 0; 560 case TEST_CODE_READING_NO_KCORE: 561 fprintf(stderr, " (no kcore)"); 562 return 0; 563 case TEST_CODE_READING_NO_ACCESS: 564 fprintf(stderr, " (no access)"); 565 return 0; 566 case TEST_CODE_READING_NO_KERNEL_OBJ: 567 fprintf(stderr, " (no kernel obj)"); 568 return 0; 569 default: 570 return -1; 571 }; 572 } 573