Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tests: Add test for PE binary format support

This adds a precompiled file in PE binary format, with split debug file,
and tries to read its build_id and .gnu_debuglink sections, as well as
looking up the main symbol from the debug file. This should succeed if
libbfd is supported.

Committer testing:

$ perf test "PE file support"
68: PE file support : Ok
$

Signed-off-by: Remi Bernon <rbernon@codeweavers.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jacek Caban <jacek@codeweavers.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lore.kernel.org/lkml/20200821165238.1340315-3-rbernon@codeweavers.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Remi Bernon and committed by
Arnaldo Carvalho de Melo
ed21d6d7 eac9a434

+119
+1
tools/perf/Makefile.perf
··· 961 961 $(call QUIET_INSTALL, tests) \ 962 962 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 963 963 $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 964 + $(INSTALL) tests/pe-file.exe* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ 964 965 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ 965 966 $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ 966 967 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
+1
tools/perf/tests/Build
··· 60 60 perf-y += demangle-java-test.o 61 61 perf-y += pfm.o 62 62 perf-y += parse-metric.o 63 + perf-y += pe-file-parsing.o 63 64 64 65 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 65 66 $(call rule_mkdir)
+4
tools/perf/tests/builtin-test.c
··· 342 342 .func = test__parse_metric, 343 343 }, 344 344 { 345 + .desc = "PE file support", 346 + .func = test__pe_file_parsing, 347 + }, 348 + { 345 349 .func = NULL, 346 350 }, 347 351 };
+98
tools/perf/tests/pe-file-parsing.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <stdbool.h> 3 + #include <inttypes.h> 4 + #include <stdlib.h> 5 + #include <string.h> 6 + #include <linux/bitops.h> 7 + #include <linux/kernel.h> 8 + #include <linux/types.h> 9 + #include <sys/types.h> 10 + #include <sys/stat.h> 11 + #include <unistd.h> 12 + #include <subcmd/exec-cmd.h> 13 + 14 + #include "debug.h" 15 + #include "util/build-id.h" 16 + #include "util/symbol.h" 17 + #include "util/dso.h" 18 + 19 + #include "tests.h" 20 + 21 + #ifdef HAVE_LIBBFD_SUPPORT 22 + 23 + static int run_dir(const char *d) 24 + { 25 + char filename[PATH_MAX]; 26 + char debugfile[PATH_MAX]; 27 + char build_id[BUILD_ID_SIZE]; 28 + char debuglink[PATH_MAX]; 29 + char expect_build_id[] = { 30 + 0x5a, 0x0f, 0xd8, 0x82, 0xb5, 0x30, 0x84, 0x22, 31 + 0x4b, 0xa4, 0x7b, 0x62, 0x4c, 0x55, 0xa4, 0x69, 32 + }; 33 + char expect_debuglink[PATH_MAX] = "pe-file.exe.debug"; 34 + struct dso *dso; 35 + struct symbol *sym; 36 + int ret; 37 + 38 + scnprintf(filename, PATH_MAX, "%s/pe-file.exe", d); 39 + ret = filename__read_build_id(filename, build_id, BUILD_ID_SIZE); 40 + TEST_ASSERT_VAL("Failed to read build_id", 41 + ret == sizeof(expect_build_id)); 42 + TEST_ASSERT_VAL("Wrong build_id", !memcmp(build_id, expect_build_id, 43 + sizeof(expect_build_id))); 44 + 45 + ret = filename__read_debuglink(filename, debuglink, PATH_MAX); 46 + TEST_ASSERT_VAL("Failed to read debuglink", ret == 0); 47 + TEST_ASSERT_VAL("Wrong debuglink", 48 + !strcmp(debuglink, expect_debuglink)); 49 + 50 + scnprintf(debugfile, PATH_MAX, "%s/%s", d, debuglink); 51 + ret = filename__read_build_id(debugfile, build_id, BUILD_ID_SIZE); 52 + TEST_ASSERT_VAL("Failed to read debug file build_id", 53 + ret == sizeof(expect_build_id)); 54 + TEST_ASSERT_VAL("Wrong build_id", !memcmp(build_id, expect_build_id, 55 + sizeof(expect_build_id))); 56 + 57 + dso = dso__new(filename); 58 + TEST_ASSERT_VAL("Failed to get dso", dso); 59 + 60 + ret = dso__load_bfd_symbols(dso, debugfile); 61 + TEST_ASSERT_VAL("Failed to load symbols", ret == 0); 62 + 63 + dso__sort_by_name(dso); 64 + sym = dso__find_symbol_by_name(dso, "main"); 65 + TEST_ASSERT_VAL("Failed to find main", sym); 66 + dso__delete(dso); 67 + 68 + return TEST_OK; 69 + } 70 + 71 + int test__pe_file_parsing(struct test *test __maybe_unused, 72 + int subtest __maybe_unused) 73 + { 74 + struct stat st; 75 + char path_dir[PATH_MAX]; 76 + 77 + /* First try development tree tests. */ 78 + if (!lstat("./tests", &st)) 79 + return run_dir("./tests"); 80 + 81 + /* Then installed path. */ 82 + snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path()); 83 + 84 + if (!lstat(path_dir, &st)) 85 + return run_dir(path_dir); 86 + 87 + return TEST_SKIP; 88 + } 89 + 90 + #else 91 + 92 + int test__pe_file_parsing(struct test *test __maybe_unused, 93 + int subtest __maybe_unused) 94 + { 95 + return TEST_SKIP; 96 + } 97 + 98 + #endif
+14
tools/perf/tests/pe-file.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + // pe-file.exe and pe-file.exe.debug built with; 4 + // x86_64-w64-mingw32-gcc -o pe-file.exe pe-file.c 5 + // -Wl,--file-alignment,4096 -Wl,--build-id 6 + // x86_64-w64-mingw32-objcopy --only-keep-debug 7 + // --compress-debug-sections pe-file.exe pe-file.exe.debug 8 + // x86_64-w64-mingw32-objcopy --strip-debug 9 + // --add-gnu-debuglink=pe-file.exe.debug pe-file.exe 10 + 11 + int main(int argc, char const *argv[]) 12 + { 13 + return 0; 14 + }
tools/perf/tests/pe-file.exe

This is a binary file and will not be displayed.

tools/perf/tests/pe-file.exe.debug

This is a binary file and will not be displayed.

+1
tools/perf/tests/tests.h
··· 122 122 const char *test__pfm_subtest_get_desc(int subtest); 123 123 int test__pfm_subtest_get_nr(void); 124 124 int test__parse_metric(struct test *test, int subtest); 125 + int test__pe_file_parsing(struct test *test, int subtest); 125 126 126 127 bool test__bp_signal_is_supported(void); 127 128 bool test__bp_account_is_supported(void);