mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-03 09:34:42 +00:00
perf/core improvements and fixes:
- Handle legacy syscalls tracepoints (David Ahern, Arnaldo Carvalho de Melo) - Indicate which callchain entries are annotated in the TUI hists browser (report/top) (Arnaldo Carvalho de Melo) - Fix failure to add multiple probes without debuginfo (He Kuang) - Fix 'trace' summary_only option (David Ahern) - Fix race in build_id_cache__add_s() in 'buildid-cache' (Milos Vyletel) - Don't allow empty argument for field-separator, fixing segfault (Wang Nan) Infrastructure: - Add destructor for format_field in libtraceevent (David Ahern) - Prep work for support lzma compressed kernel modules (Jiri Olsa) - Update .gitignore with recently added/renamed feature detection files (Yunlong Song) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVDb3fAAoJEBpxZoYYoA71e+8IAIOaduovJL55TEFKtvniQjf3 8HIgVICyQq5i1urhEz3dE1d1MBpABCEEegjmWFd3gB0wKgpezxINTHvpkRfbf+QM 7aOa0i9DpAYsGcOXl+uV3d6UzcpPRm4Too5VVR6ZJgn1zB2KmVtei8OccwfSHKE6 Vz14vg6Fl7ATKiQphDuChhDvvAzPKidjD6BX3/C0BBnAzP+dNLzqo23YWtREuZNy mOQURRSXOL/GCfqDR1O5RfX8rfnETOy9GH+rJNhaQya/HxnIi2ZV8e4TLxHD9NpK Gs+tJ0FvOIiuo3nDUflmwWFuCnhbDcatmz76ueiC22slw8kdpU1Uu/LGcYNoKjw= =+DHx -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-2' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: - Handle legacy syscalls tracepoints (David Ahern, Arnaldo Carvalho de Melo) - Indicate which callchain entries are annotated in the TUI hists browser (report/top) (Arnaldo Carvalho de Melo) - Fix failure to add multiple probes without debuginfo (He Kuang) - Fix 'trace' summary_only option (David Ahern) - Fix race in build_id_cache__add_s() in 'buildid-cache' (Milos Vyletel) - Don't allow empty argument for field-separator, fixing segfault (Wang Nan) Infrastructure: - Add destructor for format_field in libtraceevent (David Ahern) - Prep work for support lzma compressed kernel modules (Jiri Olsa) - Update .gitignore with recently added/renamed feature detection files (Yunlong Song) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
963a70b8a2
171
tools/build/Makefile.feature
Normal file
171
tools/build/Makefile.feature
Normal file
@ -0,0 +1,171 @@
|
||||
feature_dir := $(srctree)/tools/build/feature
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
OUTPUT_FEATURES = $(OUTPUT)feature/
|
||||
$(shell mkdir -p $(OUTPUT_FEATURES))
|
||||
endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||
endef
|
||||
|
||||
feature_set = $(eval $(feature_set_code))
|
||||
define feature_set_code
|
||||
feature-$(1) := 1
|
||||
endef
|
||||
|
||||
#
|
||||
# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
|
||||
#
|
||||
|
||||
#
|
||||
# Note that this is not a complete list of all feature tests, just
|
||||
# those that are typically built on a fully configured system.
|
||||
#
|
||||
# [ Feature tests not mentioned here have to be built explicitly in
|
||||
# the rule that uses them - an example for that is the 'bionic'
|
||||
# feature check. ]
|
||||
#
|
||||
FEATURE_TESTS = \
|
||||
backtrace \
|
||||
dwarf \
|
||||
fortify-source \
|
||||
sync-compare-and-swap \
|
||||
glibc \
|
||||
gtk2 \
|
||||
gtk2-infobar \
|
||||
libaudit \
|
||||
libbfd \
|
||||
libelf \
|
||||
libelf-getphdrnum \
|
||||
libelf-mmap \
|
||||
libnuma \
|
||||
libperl \
|
||||
libpython \
|
||||
libpython-version \
|
||||
libslang \
|
||||
libunwind \
|
||||
pthread-attr-setaffinity-np \
|
||||
stackprotector-all \
|
||||
timerfd \
|
||||
libdw-dwarf-unwind \
|
||||
zlib \
|
||||
lzma
|
||||
|
||||
FEATURE_DISPLAY = \
|
||||
dwarf \
|
||||
glibc \
|
||||
gtk2 \
|
||||
libaudit \
|
||||
libbfd \
|
||||
libelf \
|
||||
libnuma \
|
||||
libperl \
|
||||
libpython \
|
||||
libslang \
|
||||
libunwind \
|
||||
libdw-dwarf-unwind \
|
||||
zlib \
|
||||
lzma
|
||||
|
||||
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
|
||||
# If in the future we need per-feature checks/flags for features not
|
||||
# mentioned in this list we need to refactor this ;-).
|
||||
set_test_all_flags = $(eval $(set_test_all_flags_code))
|
||||
define set_test_all_flags_code
|
||||
FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
|
||||
FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
|
||||
endef
|
||||
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
|
||||
|
||||
#
|
||||
# Special fast-path for the 'all features are available' case:
|
||||
#
|
||||
$(call feature_check,all,$(MSG))
|
||||
|
||||
#
|
||||
# Just in case the build freshly failed, make sure we print the
|
||||
# feature matrix:
|
||||
#
|
||||
ifeq ($(feature-all), 1)
|
||||
#
|
||||
# test-all.c passed - just set all the core feature flags to 1:
|
||||
#
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
|
||||
else
|
||||
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C $(feature_dir) $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
endif
|
||||
|
||||
#
|
||||
# Print the result of the feature test:
|
||||
#
|
||||
feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
|
||||
|
||||
define feature_print_status_code
|
||||
ifeq ($(feature-$(1)), 1)
|
||||
MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
|
||||
else
|
||||
MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
|
||||
endif
|
||||
endef
|
||||
|
||||
feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
|
||||
define feature_print_text_code
|
||||
MSG = $(shell printf '...%30s: %s' $(1) $(2))
|
||||
endef
|
||||
|
||||
FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
|
||||
FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
# The $(feature_display) controls the default detection message
|
||||
# output. It's set if:
|
||||
# - detected features differes from stored features from
|
||||
# last build (in FEATURE-DUMP file)
|
||||
# - one of the $(FEATURE_DISPLAY) is not detected
|
||||
# - VF is enabled
|
||||
|
||||
ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
|
||||
$(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
|
||||
feature_display := 1
|
||||
endif
|
||||
|
||||
feature_display_check = $(eval $(feature_check_code))
|
||||
define feature_display_check_code
|
||||
ifneq ($(feature-$(1)), 1)
|
||||
feature_display := 1
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_display_check,$(feat)))
|
||||
|
||||
ifeq ($(VF),1)
|
||||
feature_display := 1
|
||||
feature_verbose := 1
|
||||
endif
|
||||
|
||||
ifeq ($(feature_display),1)
|
||||
$(info )
|
||||
$(info Auto-detecting system features:)
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
$(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
ifneq ($(feature_verbose),1)
|
||||
$(info )
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(feature_verbose),1)
|
||||
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
|
||||
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
|
||||
$(info )
|
||||
endif
|
@ -1,2 +1,3 @@
|
||||
*.d
|
||||
*.bin
|
||||
*.output
|
@ -32,7 +32,8 @@ FILES= \
|
||||
test-libbabeltrace.bin \
|
||||
test-compile-32.bin \
|
||||
test-compile-x32.bin \
|
||||
test-zlib.bin
|
||||
test-zlib.bin \
|
||||
test-lzma.bin
|
||||
|
||||
CC := $(CROSS_COMPILE)gcc -MD
|
||||
PKG_CONFIG := $(CROSS_COMPILE)pkg-config
|
||||
@ -45,7 +46,7 @@ __BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@)
|
||||
###############################
|
||||
|
||||
test-all.bin:
|
||||
$(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz
|
||||
$(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz -llzma
|
||||
|
||||
test-hello.bin:
|
||||
$(BUILD)
|
||||
@ -152,6 +153,9 @@ test-compile-x32.bin:
|
||||
test-zlib.bin:
|
||||
$(BUILD) -lz
|
||||
|
||||
test-lzma.bin:
|
||||
$(BUILD) -llzma
|
||||
|
||||
-include *.d
|
||||
|
||||
###############################
|
@ -113,6 +113,10 @@
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
#define main main_test_lzma
|
||||
# include "test-lzma.c"
|
||||
#undef main
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
main_test_libpython();
|
||||
@ -138,6 +142,7 @@ int main(int argc, char *argv[])
|
||||
main_test_sync_compare_and_swap(argc, argv);
|
||||
main_test_zlib();
|
||||
main_test_pthread_attr_setaffinity_np();
|
||||
main_test_lzma();
|
||||
|
||||
return 0;
|
||||
}
|
10
tools/build/feature/test-lzma.c
Normal file
10
tools/build/feature/test-lzma.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <lzma.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
int ret;
|
||||
|
||||
ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
|
||||
return ret ? -1 : 0;
|
||||
}
|
@ -6228,15 +6228,20 @@ void pevent_ref(struct pevent *pevent)
|
||||
pevent->ref_count++;
|
||||
}
|
||||
|
||||
void pevent_free_format_field(struct format_field *field)
|
||||
{
|
||||
free(field->type);
|
||||
free(field->name);
|
||||
free(field);
|
||||
}
|
||||
|
||||
static void free_format_fields(struct format_field *field)
|
||||
{
|
||||
struct format_field *next;
|
||||
|
||||
while (field) {
|
||||
next = field->next;
|
||||
free(field->type);
|
||||
free(field->name);
|
||||
free(field);
|
||||
pevent_free_format_field(field);
|
||||
field = next;
|
||||
}
|
||||
}
|
||||
|
@ -619,6 +619,7 @@ enum pevent_errno pevent_parse_format(struct pevent *pevent,
|
||||
const char *buf,
|
||||
unsigned long size, const char *sys);
|
||||
void pevent_free_format(struct event_format *event);
|
||||
void pevent_free_format_field(struct format_field *field);
|
||||
|
||||
void *pevent_get_field_raw(struct trace_seq *s, struct event_format *event,
|
||||
const char *name, struct pevent_record *record,
|
||||
|
2
tools/perf/.gitignore
vendored
2
tools/perf/.gitignore
vendored
@ -1,7 +1,7 @@
|
||||
PERF-CFLAGS
|
||||
PERF-GUI-VARS
|
||||
PERF-VERSION-FILE
|
||||
PERF-FEATURES
|
||||
FEATURE-DUMP
|
||||
perf
|
||||
perf-read-vdso32
|
||||
perf-read-vdsox32
|
||||
|
@ -71,6 +71,8 @@ include config/utilities.mak
|
||||
#
|
||||
# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
|
||||
# for CTF data format.
|
||||
#
|
||||
# Define NO_LZMA if you do not want to support compressed (xz) kernel modules
|
||||
|
||||
ifeq ($(srctree),)
|
||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||
@ -521,7 +523,7 @@ $(INSTALL_DOC_TARGETS):
|
||||
#
|
||||
config-clean:
|
||||
$(call QUIET_CLEAN, config)
|
||||
$(Q)$(MAKE) -C config/feature-checks clean >/dev/null
|
||||
$(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
|
||||
|
||||
clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
|
||||
$(call QUIET_CLEAN, core-objs) $(RM) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
|
||||
|
@ -802,7 +802,7 @@ static const struct option options[] = {
|
||||
OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
|
||||
"sort by key(s): pid, comm, dso, symbol, parent, cpu, srcline, ..."
|
||||
" Please refer the man page for the complete list."),
|
||||
OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
|
||||
OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
|
||||
"separator for columns, no spaces will be added between "
|
||||
"columns '.' is reserved."),
|
||||
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
|
||||
|
@ -286,7 +286,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"input file name"),
|
||||
OPT_STRING('C', "cpu", &mem.cpu_list, "cpu",
|
||||
"list of cpus to profile"),
|
||||
OPT_STRING('x', "field-separator", &symbol_conf.field_sep,
|
||||
OPT_STRING_NOEMPTY('x', "field-separator", &symbol_conf.field_sep,
|
||||
"separator",
|
||||
"separator for columns, no spaces will be added"
|
||||
" between columns '.' is reserved."),
|
||||
|
@ -1135,6 +1135,8 @@ static struct syscall_fmt *syscall_fmt__find(const char *name)
|
||||
|
||||
struct syscall {
|
||||
struct event_format *tp_format;
|
||||
int nr_args;
|
||||
struct format_field *args;
|
||||
const char *name;
|
||||
bool filtered;
|
||||
bool is_exit;
|
||||
@ -1442,14 +1444,14 @@ static int syscall__set_arg_fmts(struct syscall *sc)
|
||||
struct format_field *field;
|
||||
int idx = 0;
|
||||
|
||||
sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *));
|
||||
sc->arg_scnprintf = calloc(sc->nr_args, sizeof(void *));
|
||||
if (sc->arg_scnprintf == NULL)
|
||||
return -1;
|
||||
|
||||
if (sc->fmt)
|
||||
sc->arg_parm = sc->fmt->arg_parm;
|
||||
|
||||
for (field = sc->tp_format->format.fields->next; field; field = field->next) {
|
||||
for (field = sc->args; field; field = field->next) {
|
||||
if (sc->fmt && sc->fmt->arg_scnprintf[idx])
|
||||
sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx];
|
||||
else if (field->flags & FIELD_IS_POINTER)
|
||||
@ -1515,6 +1517,14 @@ static int trace__read_syscall_info(struct trace *trace, int id)
|
||||
if (sc->tp_format == NULL)
|
||||
return -1;
|
||||
|
||||
sc->args = sc->tp_format->format.fields;
|
||||
sc->nr_args = sc->tp_format->format.nr_fields;
|
||||
/* drop nr field - not relevant here; does not exist on older kernels */
|
||||
if (sc->args && strcmp(sc->args->name, "nr") == 0) {
|
||||
sc->args = sc->args->next;
|
||||
--sc->nr_args;
|
||||
}
|
||||
|
||||
sc->is_exit = !strcmp(name, "exit_group") || !strcmp(name, "exit");
|
||||
|
||||
return syscall__set_arg_fmts(sc);
|
||||
@ -1537,7 +1547,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
|
||||
unsigned char *p;
|
||||
unsigned long val;
|
||||
|
||||
if (sc->tp_format != NULL) {
|
||||
if (sc->args != NULL) {
|
||||
struct format_field *field;
|
||||
u8 bit = 1;
|
||||
struct syscall_arg arg = {
|
||||
@ -1547,7 +1557,7 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size,
|
||||
.thread = thread,
|
||||
};
|
||||
|
||||
for (field = sc->tp_format->format.fields->next; field;
|
||||
for (field = sc->args; field;
|
||||
field = field->next, ++arg.idx, bit <<= 1) {
|
||||
if (arg.mask & bit)
|
||||
continue;
|
||||
@ -1724,7 +1734,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
|
||||
return -1;
|
||||
}
|
||||
|
||||
printed += trace__printf_interrupted_entry(trace, sample);
|
||||
if (!trace->summary_only)
|
||||
printed += trace__printf_interrupted_entry(trace, sample);
|
||||
|
||||
ttrace->entry_time = sample->time;
|
||||
msg = ttrace->entry_str;
|
||||
|
@ -176,102 +176,7 @@ LDFLAGS += -Wl,-z,noexecstack
|
||||
|
||||
EXTLIBS = -lpthread -lrt -lm -ldl
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
|
||||
$(shell mkdir -p $(OUTPUT_FEATURES))
|
||||
endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||
endef
|
||||
|
||||
feature_set = $(eval $(feature_set_code))
|
||||
define feature_set_code
|
||||
feature-$(1) := 1
|
||||
endef
|
||||
|
||||
#
|
||||
# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
|
||||
#
|
||||
|
||||
#
|
||||
# Note that this is not a complete list of all feature tests, just
|
||||
# those that are typically built on a fully configured system.
|
||||
#
|
||||
# [ Feature tests not mentioned here have to be built explicitly in
|
||||
# the rule that uses them - an example for that is the 'bionic'
|
||||
# feature check. ]
|
||||
#
|
||||
FEATURE_TESTS = \
|
||||
backtrace \
|
||||
dwarf \
|
||||
fortify-source \
|
||||
sync-compare-and-swap \
|
||||
glibc \
|
||||
gtk2 \
|
||||
gtk2-infobar \
|
||||
libaudit \
|
||||
libbfd \
|
||||
libelf \
|
||||
libelf-getphdrnum \
|
||||
libelf-mmap \
|
||||
libnuma \
|
||||
libperl \
|
||||
libpython \
|
||||
libpython-version \
|
||||
libslang \
|
||||
libunwind \
|
||||
pthread-attr-setaffinity-np \
|
||||
stackprotector-all \
|
||||
timerfd \
|
||||
libdw-dwarf-unwind \
|
||||
zlib
|
||||
|
||||
FEATURE_DISPLAY = \
|
||||
dwarf \
|
||||
glibc \
|
||||
gtk2 \
|
||||
libaudit \
|
||||
libbfd \
|
||||
libelf \
|
||||
libnuma \
|
||||
libperl \
|
||||
libpython \
|
||||
libslang \
|
||||
libunwind \
|
||||
libdw-dwarf-unwind \
|
||||
zlib
|
||||
|
||||
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
|
||||
# If in the future we need per-feature checks/flags for features not
|
||||
# mentioned in this list we need to refactor this ;-).
|
||||
set_test_all_flags = $(eval $(set_test_all_flags_code))
|
||||
define set_test_all_flags_code
|
||||
FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1))
|
||||
FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
|
||||
endef
|
||||
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
|
||||
|
||||
#
|
||||
# Special fast-path for the 'all features are available' case:
|
||||
#
|
||||
$(call feature_check,all,$(MSG))
|
||||
|
||||
#
|
||||
# Just in case the build freshly failed, make sure we print the
|
||||
# feature matrix:
|
||||
#
|
||||
ifeq ($(feature-all), 1)
|
||||
#
|
||||
# test-all.c passed - just set all the core feature flags to 1:
|
||||
#
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
|
||||
else
|
||||
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
endif
|
||||
include $(srctree)/tools/build/Makefile.feature
|
||||
|
||||
ifeq ($(feature-stackprotector-all), 1)
|
||||
CFLAGS += -fstack-protector-all
|
||||
@ -636,6 +541,17 @@ ifndef NO_ZLIB
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_LZMA
|
||||
ifeq ($(feature-lzma), 1)
|
||||
CFLAGS += -DHAVE_LZMA_SUPPORT
|
||||
EXTLIBS += -llzma
|
||||
$(call detected,CONFIG_LZMA)
|
||||
else
|
||||
msg := $(warning No liblzma found, disables xz kernel module decompression, please install xz-devel/liblzma-dev);
|
||||
NO_LZMA := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_BACKTRACE
|
||||
ifeq ($(feature-backtrace), 1)
|
||||
CFLAGS += -DHAVE_BACKTRACE_SUPPORT
|
||||
@ -763,80 +679,12 @@ plugindir=$(libdir)/traceevent/plugins
|
||||
plugindir_SQ= $(subst ','\'',$(plugindir))
|
||||
endif
|
||||
|
||||
#
|
||||
# Print the result of the feature test:
|
||||
#
|
||||
feature_print_status = $(eval $(feature_print_status_code)) $(info $(MSG))
|
||||
|
||||
define feature_print_status_code
|
||||
ifeq ($(feature-$(1)), 1)
|
||||
MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
|
||||
else
|
||||
MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
|
||||
endif
|
||||
endef
|
||||
|
||||
print_var = $(eval $(print_var_code)) $(info $(MSG))
|
||||
define print_var_code
|
||||
MSG = $(shell printf '...%30s: %s' $(1) $($(1)))
|
||||
endef
|
||||
|
||||
feature_print_text = $(eval $(feature_print_text_code)) $(info $(MSG))
|
||||
define feature_print_text_code
|
||||
MSG = $(shell printf '...%30s: %s' $(1) $(2))
|
||||
endef
|
||||
|
||||
FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
|
||||
FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
# The $(feature_display) controls the default detection message
|
||||
# output. It's set if:
|
||||
# - detected features differes from stored features from
|
||||
# last build (in FEATURE-DUMP file)
|
||||
# - one of the $(FEATURE_DISPLAY) is not detected
|
||||
# - VF is enabled
|
||||
|
||||
ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
|
||||
$(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
|
||||
feature_display := 1
|
||||
endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
ifneq ($(feature-$(1)), 1)
|
||||
feature_display := 1
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_check,$(feat)))
|
||||
|
||||
ifeq ($(VF),1)
|
||||
feature_display := 1
|
||||
feature_verbose := 1
|
||||
endif
|
||||
|
||||
ifeq ($(feature_display),1)
|
||||
$(info )
|
||||
$(info Auto-detecting system features:)
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
$(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
ifneq ($(feature_verbose),1)
|
||||
$(info )
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(feature_verbose),1)
|
||||
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
|
||||
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
|
||||
$(info )
|
||||
$(call print_var,prefix)
|
||||
$(call print_var,bindir)
|
||||
$(call print_var,libdir)
|
||||
|
@ -30,6 +30,7 @@ perf-y += keep-tracking.o
|
||||
perf-y += code-reading.o
|
||||
perf-y += sample-parsing.o
|
||||
perf-y += parse-no-sample-id-all.o
|
||||
perf-y += kmod-path.o
|
||||
|
||||
perf-$(CONFIG_X86) += perf-time-to-tsc.o
|
||||
|
||||
|
@ -166,6 +166,10 @@ static struct test {
|
||||
.desc = "Add fd to a fdarray, making it autogrow",
|
||||
.func = test__fdarray__add,
|
||||
},
|
||||
{
|
||||
.desc = "Test kmod_path__parse function",
|
||||
.func = test__kmod_path__parse,
|
||||
},
|
||||
{
|
||||
.func = NULL,
|
||||
},
|
||||
|
73
tools/perf/tests/kmod-path.c
Normal file
73
tools/perf/tests/kmod-path.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <stdbool.h>
|
||||
#include "tests.h"
|
||||
#include "dso.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int test(const char *path, bool alloc_name, bool alloc_ext,
|
||||
bool kmod, bool comp, const char *name, const char *ext)
|
||||
{
|
||||
struct kmod_path m;
|
||||
|
||||
memset(&m, 0x0, sizeof(m));
|
||||
|
||||
TEST_ASSERT_VAL("kmod_path__parse",
|
||||
!__kmod_path__parse(&m, path, alloc_name, alloc_ext));
|
||||
|
||||
pr_debug("%s - alloc name %d, alloc ext %d, kmod %d, comp %d, name '%s', ext '%s'\n",
|
||||
path, alloc_name, alloc_ext, m.kmod, m.comp, m.name, m.ext);
|
||||
|
||||
TEST_ASSERT_VAL("wrong kmod", m.kmod == kmod);
|
||||
TEST_ASSERT_VAL("wrong comp", m.comp == comp);
|
||||
|
||||
if (ext)
|
||||
TEST_ASSERT_VAL("wrong ext", m.ext && !strcmp(ext, m.ext));
|
||||
else
|
||||
TEST_ASSERT_VAL("wrong ext", !m.ext);
|
||||
|
||||
if (name)
|
||||
TEST_ASSERT_VAL("wrong name", m.name && !strcmp(name, m.name));
|
||||
else
|
||||
TEST_ASSERT_VAL("wrong name", !m.name);
|
||||
|
||||
free(m.name);
|
||||
free(m.ext);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define T(path, an, ae, k, c, n, e) \
|
||||
TEST_ASSERT_VAL("failed", !test(path, an, ae, k, c, n, e))
|
||||
|
||||
int test__kmod_path__parse(void)
|
||||
{
|
||||
/* path alloc_name alloc_ext kmod comp name ext */
|
||||
T("/xxxx/xxxx/x-x.ko", true , true , true, false, "[x_x]", NULL);
|
||||
T("/xxxx/xxxx/x-x.ko", false , true , true, false, NULL , NULL);
|
||||
T("/xxxx/xxxx/x-x.ko", true , false , true, false, "[x_x]", NULL);
|
||||
T("/xxxx/xxxx/x-x.ko", false , false , true, false, NULL , NULL);
|
||||
|
||||
/* path alloc_name alloc_ext kmod comp name ext */
|
||||
T("/xxxx/xxxx/x.ko.gz", true , true , true, true, "[x]", "gz");
|
||||
T("/xxxx/xxxx/x.ko.gz", false , true , true, true, NULL , "gz");
|
||||
T("/xxxx/xxxx/x.ko.gz", true , false , true, true, "[x]", NULL);
|
||||
T("/xxxx/xxxx/x.ko.gz", false , false , true, true, NULL , NULL);
|
||||
|
||||
/* path alloc_name alloc_ext kmod comp name ext */
|
||||
T("/xxxx/xxxx/x.gz", true , true , false, true, "x.gz" ,"gz");
|
||||
T("/xxxx/xxxx/x.gz", false , true , false, true, NULL ,"gz");
|
||||
T("/xxxx/xxxx/x.gz", true , false , false, true, "x.gz" , NULL);
|
||||
T("/xxxx/xxxx/x.gz", false , false , false, true, NULL , NULL);
|
||||
|
||||
/* path alloc_name alloc_ext kmod comp name ext */
|
||||
T("x.gz", true , true , false, true, "x.gz", "gz");
|
||||
T("x.gz", false , true , false, true, NULL , "gz");
|
||||
T("x.gz", true , false , false, true, "x.gz", NULL);
|
||||
T("x.gz", false , false , false, true, NULL , NULL);
|
||||
|
||||
/* path alloc_name alloc_ext kmod comp name ext */
|
||||
T("x.ko.gz", true , true , true, true, "[x]", "gz");
|
||||
T("x.ko.gz", false , true , true, true, NULL , "gz");
|
||||
T("x.ko.gz", true , false , true, true, "[x]", NULL);
|
||||
T("x.ko.gz", false , false , true, true, NULL , NULL);
|
||||
|
||||
return 0;
|
||||
}
|
@ -51,6 +51,7 @@ int test__hists_cumulate(void);
|
||||
int test__switch_tracking(void);
|
||||
int test__fdarray__filter(void);
|
||||
int test__fdarray__add(void);
|
||||
int test__kmod_path__parse(void);
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__arm__)
|
||||
#ifdef HAVE_DWARF_UNWIND_SUPPORT
|
||||
|
@ -511,6 +511,7 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
|
||||
{
|
||||
int color, width;
|
||||
char folded_sign = callchain_list__folded(chain);
|
||||
bool show_annotated = browser->show_dso && chain->ms.sym && symbol__annotation(chain->ms.sym)->src;
|
||||
|
||||
color = HE_COLORSET_NORMAL;
|
||||
width = browser->b.width - (offset + 2);
|
||||
@ -523,7 +524,8 @@ static void hist_browser__show_callchain_entry(struct hist_browser *browser,
|
||||
ui_browser__set_color(&browser->b, color);
|
||||
hist_browser__gotorc(browser, row, 0);
|
||||
slsmg_write_nstring(" ", offset);
|
||||
slsmg_printf("%c ", folded_sign);
|
||||
slsmg_printf("%c", folded_sign);
|
||||
ui_browser__write_graph(&browser->b, show_annotated ? SLSMG_RARROW_CHAR : ' ');
|
||||
slsmg_write_nstring(str, width);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,7 @@ libperf-y += scripting-engines/
|
||||
|
||||
libperf-$(CONFIG_PERF_REGS) += perf_regs.o
|
||||
libperf-$(CONFIG_ZLIB) += zlib.o
|
||||
libperf-$(CONFIG_LZMA) += lzma.o
|
||||
|
||||
CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
|
||||
CFLAGS_exec_cmd.o += -DPERF_EXEC_PATH="BUILD_STR($(perfexecdir_SQ))" -DPREFIX="BUILD_STR($(prefix_SQ))"
|
||||
|
@ -374,7 +374,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name,
|
||||
if (is_kallsyms) {
|
||||
if (copyfile("/proc/kallsyms", filename))
|
||||
goto out_free;
|
||||
} else if (link(realname, filename) && copyfile(name, filename))
|
||||
} else if (link(realname, filename) && errno != EEXIST &&
|
||||
copyfile(name, filename))
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,9 @@ static const struct {
|
||||
} compressions[] = {
|
||||
#ifdef HAVE_ZLIB_SUPPORT
|
||||
{ "gz", gzip_decompress_to_file },
|
||||
#endif
|
||||
#ifdef HAVE_LZMA_SUPPORT
|
||||
{ "xz", lzma_decompress_to_file },
|
||||
#endif
|
||||
{ NULL, NULL },
|
||||
};
|
||||
@ -208,6 +211,72 @@ bool dso__needs_decompress(struct dso *dso)
|
||||
dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parses kernel module specified in @path and updates
|
||||
* @m argument like:
|
||||
*
|
||||
* @comp - true if @path contains supported compression suffix,
|
||||
* false otherwise
|
||||
* @kmod - true if @path contains '.ko' suffix in right position,
|
||||
* false otherwise
|
||||
* @name - if (@alloc_name && @kmod) is true, it contains strdup-ed base name
|
||||
* of the kernel module without suffixes, otherwise strudup-ed
|
||||
* base name of @path
|
||||
* @ext - if (@alloc_ext && @comp) is true, it contains strdup-ed string
|
||||
* the compression suffix
|
||||
*
|
||||
* Returns 0 if there's no strdup error, -ENOMEM otherwise.
|
||||
*/
|
||||
int __kmod_path__parse(struct kmod_path *m, const char *path,
|
||||
bool alloc_name, bool alloc_ext)
|
||||
{
|
||||
const char *name = strrchr(path, '/');
|
||||
const char *ext = strrchr(path, '.');
|
||||
|
||||
memset(m, 0x0, sizeof(*m));
|
||||
name = name ? name + 1 : path;
|
||||
|
||||
/* No extension, just return name. */
|
||||
if (ext == NULL) {
|
||||
if (alloc_name) {
|
||||
m->name = strdup(name);
|
||||
return m->name ? 0 : -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_supported_compression(ext + 1)) {
|
||||
m->comp = true;
|
||||
ext -= 3;
|
||||
}
|
||||
|
||||
/* Check .ko extension only if there's enough name left. */
|
||||
if (ext > name)
|
||||
m->kmod = !strncmp(ext, ".ko", 3);
|
||||
|
||||
if (alloc_name) {
|
||||
if (m->kmod) {
|
||||
if (asprintf(&m->name, "[%.*s]", (int) (ext - name), name) == -1)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
if (asprintf(&m->name, "%s", name) == -1)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
strxfrchar(m->name, '-', '_');
|
||||
}
|
||||
|
||||
if (alloc_ext && m->comp) {
|
||||
m->ext = strdup(ext + 4);
|
||||
if (!m->ext) {
|
||||
free((void *) m->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Global list of open DSOs and the counter.
|
||||
*/
|
||||
@ -1002,19 +1071,22 @@ struct dso *dsos__find(const struct dsos *dsos, const char *name,
|
||||
return dso__find_by_longname(&dsos->root, name);
|
||||
}
|
||||
|
||||
struct dso *dsos__addnew(struct dsos *dsos, const char *name)
|
||||
{
|
||||
struct dso *dso = dso__new(name);
|
||||
|
||||
if (dso != NULL) {
|
||||
dsos__add(dsos, dso);
|
||||
dso__set_basename(dso);
|
||||
}
|
||||
return dso;
|
||||
}
|
||||
|
||||
struct dso *__dsos__findnew(struct dsos *dsos, const char *name)
|
||||
{
|
||||
struct dso *dso = dsos__find(dsos, name, false);
|
||||
|
||||
if (!dso) {
|
||||
dso = dso__new(name);
|
||||
if (dso != NULL) {
|
||||
dsos__add(dsos, dso);
|
||||
dso__set_basename(dso);
|
||||
}
|
||||
}
|
||||
|
||||
return dso;
|
||||
return dso ? dso : dsos__addnew(dsos, name);
|
||||
}
|
||||
|
||||
size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
|
||||
|
@ -195,6 +195,20 @@ bool is_kernel_module(const char *pathname, bool *compressed);
|
||||
bool decompress_to_file(const char *ext, const char *filename, int output_fd);
|
||||
bool dso__needs_decompress(struct dso *dso);
|
||||
|
||||
struct kmod_path {
|
||||
char *name;
|
||||
char *ext;
|
||||
bool comp;
|
||||
bool kmod;
|
||||
};
|
||||
|
||||
int __kmod_path__parse(struct kmod_path *m, const char *path,
|
||||
bool alloc_name, bool alloc_ext);
|
||||
|
||||
#define kmod_path__parse(__m, __p) __kmod_path__parse(__m, __p, false, false)
|
||||
#define kmod_path__parse_name(__m, __p) __kmod_path__parse(__m, __p, true , false)
|
||||
#define kmod_path__parse_ext(__m, __p) __kmod_path__parse(__m, __p, false, true)
|
||||
|
||||
/*
|
||||
* The dso__data_* external interface provides following functions:
|
||||
* dso__data_fd
|
||||
@ -250,6 +264,7 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
|
||||
const char *short_name, int dso_type);
|
||||
|
||||
void dsos__add(struct dsos *dsos, struct dso *dso);
|
||||
struct dso *dsos__addnew(struct dsos *dsos, const char *name);
|
||||
struct dso *dsos__find(const struct dsos *dsos, const char *name,
|
||||
bool cmp_short);
|
||||
struct dso *__dsos__findnew(struct dsos *dsos, const char *name);
|
||||
|
95
tools/perf/util/lzma.c
Normal file
95
tools/perf/util/lzma.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include <lzma.h>
|
||||
#include <stdio.h>
|
||||
#include <linux/compiler.h>
|
||||
#include "util.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define BUFSIZE 8192
|
||||
|
||||
static const char *lzma_strerror(lzma_ret ret)
|
||||
{
|
||||
switch ((int) ret) {
|
||||
case LZMA_MEM_ERROR:
|
||||
return "Memory allocation failed";
|
||||
case LZMA_OPTIONS_ERROR:
|
||||
return "Unsupported decompressor flags";
|
||||
case LZMA_FORMAT_ERROR:
|
||||
return "The input is not in the .xz format";
|
||||
case LZMA_DATA_ERROR:
|
||||
return "Compressed file is corrupt";
|
||||
case LZMA_BUF_ERROR:
|
||||
return "Compressed file is truncated or otherwise corrupt";
|
||||
default:
|
||||
return "Unknown error, possibly a bug";
|
||||
}
|
||||
}
|
||||
|
||||
int lzma_decompress_to_file(const char *input, int output_fd)
|
||||
{
|
||||
lzma_action action = LZMA_RUN;
|
||||
lzma_stream strm = LZMA_STREAM_INIT;
|
||||
lzma_ret ret;
|
||||
|
||||
u8 buf_in[BUFSIZE];
|
||||
u8 buf_out[BUFSIZE];
|
||||
FILE *infile;
|
||||
|
||||
infile = fopen(input, "rb");
|
||||
if (!infile) {
|
||||
pr_err("lzma: fopen failed on %s: '%s'\n",
|
||||
input, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED);
|
||||
if (ret != LZMA_OK) {
|
||||
pr_err("lzma: lzma_stream_decoder failed %s (%d)\n",
|
||||
lzma_strerror(ret), ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strm.next_in = NULL;
|
||||
strm.avail_in = 0;
|
||||
strm.next_out = buf_out;
|
||||
strm.avail_out = sizeof(buf_out);
|
||||
|
||||
while (1) {
|
||||
if (strm.avail_in == 0 && !feof(infile)) {
|
||||
strm.next_in = buf_in;
|
||||
strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile);
|
||||
|
||||
if (ferror(infile)) {
|
||||
pr_err("lzma: read error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (feof(infile))
|
||||
action = LZMA_FINISH;
|
||||
}
|
||||
|
||||
ret = lzma_code(&strm, action);
|
||||
|
||||
if (strm.avail_out == 0 || ret == LZMA_STREAM_END) {
|
||||
ssize_t write_size = sizeof(buf_out) - strm.avail_out;
|
||||
|
||||
if (writen(output_fd, buf_out, write_size) != write_size) {
|
||||
pr_err("lzma: write error: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
strm.next_out = buf_out;
|
||||
strm.avail_out = sizeof(buf_out);
|
||||
}
|
||||
|
||||
if (ret != LZMA_OK) {
|
||||
if (ret == LZMA_STREAM_END)
|
||||
return 0;
|
||||
|
||||
pr_err("lzma: failed %s\n", lzma_strerror(ret));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(infile);
|
||||
return 0;
|
||||
}
|
@ -460,30 +460,56 @@ int machine__process_lost_event(struct machine *machine __maybe_unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dso*
|
||||
machine__module_dso(struct machine *machine, struct kmod_path *m,
|
||||
const char *filename)
|
||||
{
|
||||
struct dso *dso;
|
||||
|
||||
dso = dsos__find(&machine->kernel_dsos, m->name, true);
|
||||
if (!dso) {
|
||||
dso = dsos__addnew(&machine->kernel_dsos, m->name);
|
||||
if (dso == NULL)
|
||||
return NULL;
|
||||
|
||||
if (machine__is_host(machine))
|
||||
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
|
||||
else
|
||||
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
|
||||
|
||||
/* _KMODULE_COMP should be next to _KMODULE */
|
||||
if (m->kmod && m->comp)
|
||||
dso->symtab_type++;
|
||||
|
||||
dso__set_short_name(dso, strdup(m->name), true);
|
||||
dso__set_long_name(dso, strdup(filename), true);
|
||||
}
|
||||
|
||||
return dso;
|
||||
}
|
||||
|
||||
struct map *machine__new_module(struct machine *machine, u64 start,
|
||||
const char *filename)
|
||||
{
|
||||
struct map *map;
|
||||
struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
|
||||
bool compressed;
|
||||
struct map *map = NULL;
|
||||
struct dso *dso;
|
||||
struct kmod_path m;
|
||||
|
||||
if (dso == NULL)
|
||||
if (kmod_path__parse_name(&m, filename))
|
||||
return NULL;
|
||||
|
||||
dso = machine__module_dso(machine, &m, filename);
|
||||
if (dso == NULL)
|
||||
goto out;
|
||||
|
||||
map = map__new2(start, dso, MAP__FUNCTION);
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
|
||||
if (machine__is_host(machine))
|
||||
dso->symtab_type = DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE;
|
||||
else
|
||||
dso->symtab_type = DSO_BINARY_TYPE__GUEST_KMODULE;
|
||||
|
||||
/* _KMODULE_COMP should be next to _KMODULE */
|
||||
if (is_kernel_module(filename, &compressed) && compressed)
|
||||
dso->symtab_type++;
|
||||
goto out;
|
||||
|
||||
map_groups__insert(&machine->kmaps, map);
|
||||
|
||||
out:
|
||||
free(m.name);
|
||||
return map;
|
||||
}
|
||||
|
||||
@ -1044,40 +1070,11 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
|
||||
strlen(kmmap_prefix) - 1) == 0;
|
||||
if (event->mmap.filename[0] == '/' ||
|
||||
(!is_kernel_mmap && event->mmap.filename[0] == '[')) {
|
||||
|
||||
char short_module_name[1024];
|
||||
char *name, *dot;
|
||||
|
||||
if (event->mmap.filename[0] == '/') {
|
||||
name = strrchr(event->mmap.filename, '/');
|
||||
if (name == NULL)
|
||||
goto out_problem;
|
||||
|
||||
++name; /* skip / */
|
||||
dot = strrchr(name, '.');
|
||||
if (dot == NULL)
|
||||
goto out_problem;
|
||||
/* On some system, modules are compressed like .ko.gz */
|
||||
if (is_supported_compression(dot + 1))
|
||||
dot -= 3;
|
||||
if (!is_kmodule_extension(dot + 1))
|
||||
goto out_problem;
|
||||
snprintf(short_module_name, sizeof(short_module_name),
|
||||
"[%.*s]", (int)(dot - name), name);
|
||||
strxfrchar(short_module_name, '-', '_');
|
||||
} else
|
||||
strcpy(short_module_name, event->mmap.filename);
|
||||
|
||||
map = machine__new_module(machine, event->mmap.start,
|
||||
event->mmap.filename);
|
||||
if (map == NULL)
|
||||
goto out_problem;
|
||||
|
||||
name = strdup(short_module_name);
|
||||
if (name == NULL)
|
||||
goto out_problem;
|
||||
|
||||
dso__set_short_name(map->dso, name, true);
|
||||
map->end = map->start + event->mmap.len;
|
||||
} else if (is_kernel_mmap) {
|
||||
const char *symbol_name = (event->mmap.filename +
|
||||
|
@ -2507,7 +2507,6 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
|
||||
int max_tevs, const char *target)
|
||||
{
|
||||
struct map *map = NULL;
|
||||
struct kmap *kmap = NULL;
|
||||
struct ref_reloc_sym *reloc_sym = NULL;
|
||||
struct symbol *sym;
|
||||
struct probe_trace_event *tev;
|
||||
@ -2540,8 +2539,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
|
||||
}
|
||||
|
||||
if (!pev->uprobes && !pp->retprobe) {
|
||||
kmap = map__kmap(map);
|
||||
reloc_sym = kmap->ref_reloc_sym;
|
||||
reloc_sym = kernel_get_ref_reloc_sym();
|
||||
if (!reloc_sym) {
|
||||
pr_warning("Relocated base symbol is not found!\n");
|
||||
ret = -EINVAL;
|
||||
|
@ -329,4 +329,8 @@ bool find_process(const char *name);
|
||||
int gzip_decompress_to_file(const char *input, int output_fd);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LZMA_SUPPORT
|
||||
int lzma_decompress_to_file(const char *input, int output_fd);
|
||||
#endif
|
||||
|
||||
#endif /* GIT_COMPAT_UTIL_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user