diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6031167939ae..b2a3f5b652fe 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -961,6 +961,7 @@ install-tests: all install-gtk $(call QUIET_INSTALL, tests) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ + $(INSTALL) tests/pe-file.exe* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 84352fc49a20..69bea7996f18 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -60,6 +60,7 @@ perf-y += api-io.o perf-y += demangle-java-test.o perf-y += pfm.o perf-y += parse-metric.o +perf-y += pe-file-parsing.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index d328caaba45d..651b8ea3354a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -341,6 +341,10 @@ static struct test generic_tests[] = { .desc = "Parse and process metrics", .func = test__parse_metric, }, + { + .desc = "PE file support", + .func = test__pe_file_parsing, + }, { .func = NULL, }, diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c new file mode 100644 index 000000000000..19eae3e8e229 --- /dev/null +++ b/tools/perf/tests/pe-file-parsing.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "util/build-id.h" +#include "util/symbol.h" +#include "util/dso.h" + +#include "tests.h" + +#ifdef HAVE_LIBBFD_SUPPORT + +static int run_dir(const char *d) +{ + char filename[PATH_MAX]; + char debugfile[PATH_MAX]; + char build_id[BUILD_ID_SIZE]; + char debuglink[PATH_MAX]; + char expect_build_id[] = { + 0x5a, 0x0f, 0xd8, 0x82, 0xb5, 0x30, 0x84, 0x22, + 0x4b, 0xa4, 0x7b, 0x62, 0x4c, 0x55, 0xa4, 0x69, + }; + char expect_debuglink[PATH_MAX] = "pe-file.exe.debug"; + struct dso *dso; + struct symbol *sym; + int ret; + + scnprintf(filename, PATH_MAX, "%s/pe-file.exe", d); + ret = filename__read_build_id(filename, build_id, BUILD_ID_SIZE); + TEST_ASSERT_VAL("Failed to read build_id", + ret == sizeof(expect_build_id)); + TEST_ASSERT_VAL("Wrong build_id", !memcmp(build_id, expect_build_id, + sizeof(expect_build_id))); + + ret = filename__read_debuglink(filename, debuglink, PATH_MAX); + TEST_ASSERT_VAL("Failed to read debuglink", ret == 0); + TEST_ASSERT_VAL("Wrong debuglink", + !strcmp(debuglink, expect_debuglink)); + + scnprintf(debugfile, PATH_MAX, "%s/%s", d, debuglink); + ret = filename__read_build_id(debugfile, build_id, BUILD_ID_SIZE); + TEST_ASSERT_VAL("Failed to read debug file build_id", + ret == sizeof(expect_build_id)); + TEST_ASSERT_VAL("Wrong build_id", !memcmp(build_id, expect_build_id, + sizeof(expect_build_id))); + + dso = dso__new(filename); + TEST_ASSERT_VAL("Failed to get dso", dso); + + ret = dso__load_bfd_symbols(dso, debugfile); + TEST_ASSERT_VAL("Failed to load symbols", ret == 0); + + dso__sort_by_name(dso); + sym = dso__find_symbol_by_name(dso, "main"); + TEST_ASSERT_VAL("Failed to find main", sym); + dso__delete(dso); + + return TEST_OK; +} + +int test__pe_file_parsing(struct test *test __maybe_unused, + int subtest __maybe_unused) +{ + struct stat st; + char path_dir[PATH_MAX]; + + /* First try development tree tests. */ + if (!lstat("./tests", &st)) + return run_dir("./tests"); + + /* Then installed path. */ + snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path()); + + if (!lstat(path_dir, &st)) + return run_dir(path_dir); + + return TEST_SKIP; +} + +#else + +int test__pe_file_parsing(struct test *test __maybe_unused, + int subtest __maybe_unused) +{ + return TEST_SKIP; +} + +#endif diff --git a/tools/perf/tests/pe-file.c b/tools/perf/tests/pe-file.c new file mode 100644 index 000000000000..eb3df5e9886f --- /dev/null +++ b/tools/perf/tests/pe-file.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 + +// pe-file.exe and pe-file.exe.debug built with; +// x86_64-w64-mingw32-gcc -o pe-file.exe pe-file.c +// -Wl,--file-alignment,4096 -Wl,--build-id +// x86_64-w64-mingw32-objcopy --only-keep-debug +// --compress-debug-sections pe-file.exe pe-file.exe.debug +// x86_64-w64-mingw32-objcopy --strip-debug +// --add-gnu-debuglink=pe-file.exe.debug pe-file.exe + +int main(int argc, char const *argv[]) +{ + return 0; +} diff --git a/tools/perf/tests/pe-file.exe b/tools/perf/tests/pe-file.exe new file mode 100644 index 000000000000..838a46dae724 Binary files /dev/null and b/tools/perf/tests/pe-file.exe differ diff --git a/tools/perf/tests/pe-file.exe.debug b/tools/perf/tests/pe-file.exe.debug new file mode 100644 index 000000000000..287d6718d6c9 Binary files /dev/null and b/tools/perf/tests/pe-file.exe.debug differ diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 4447a516c689..ef0f33c6ba23 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -122,6 +122,7 @@ int test__pfm(struct test *test, int subtest); const char *test__pfm_subtest_get_desc(int subtest); int test__pfm_subtest_get_nr(void); int test__parse_metric(struct test *test, int subtest); +int test__pe_file_parsing(struct test *test, int subtest); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void);