Em Thu, May 19, 2016 at 11:47:38AM +0000, He Kuang escreveu:
> Currently, perf script uses host unwind methods to parse perf.data
> callchain info regardless of the target architecture. So we get wrong
> result and no promotion when unwinding callchains of x86(32-bit) on

What you mean by "promotion" here? Can you use some other synonym so
that I can make sense of this description?

> x86(64-bit) machine.
> 
> This patch shows proper error messages when we do remote unwind
> x86(32-bit) on other machines. Same thing for other platforms will be
> added in next patches.
> 
> Common functions which will be used by both local unwind and remote
> unwind are separated into new file 'unwind-libunwind_common.c'.
> 
> Signed-off-by: He Kuang <heku...@huawei.com>
> ---
>  tools/perf/arch/common.c                  |  2 +-
>  tools/perf/arch/common.h                  |  1 +
>  tools/perf/config/Makefile                |  6 ++++++
>  tools/perf/util/Build                     |  1 +
>  tools/perf/util/thread.c                  |  2 ++
>  tools/perf/util/unwind-libunwind_common.c | 34 
> +++++++++++++++++++++++++++++++
>  tools/perf/util/unwind.h                  |  5 +++++
>  7 files changed, 50 insertions(+), 1 deletion(-)
>  create mode 100644 tools/perf/util/unwind-libunwind_common.c
> 
> diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
> index e83c8ce..fa090a9 100644
> --- a/tools/perf/arch/common.c
> +++ b/tools/perf/arch/common.c
> @@ -102,7 +102,7 @@ static int lookup_triplets(const char *const *triplets, 
> const char *name)
>   * Return architecture name in a normalized form.
>   * The conversion logic comes from the Makefile.
>   */
> -static const char *normalize_arch(char *arch)
> +const char *normalize_arch(char *arch)
>  {
>       if (!strcmp(arch, "x86_64"))
>               return "x86";
> diff --git a/tools/perf/arch/common.h b/tools/perf/arch/common.h
> index 7529cfb..6b01c73 100644
> --- a/tools/perf/arch/common.h
> +++ b/tools/perf/arch/common.h
> @@ -6,5 +6,6 @@
>  extern const char *objdump_path;
>  
>  int perf_env__lookup_objdump(struct perf_env *env);
> +const char *normalize_arch(char *arch);
>  
>  #endif /* ARCH_PERF_COMMON_H */
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 1e46277..a86b864 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -345,6 +345,12 @@ ifeq ($(ARCH),powerpc)
>  endif
>  
>  ifndef NO_LIBUNWIND
> +  ifeq ($(feature-libunwind-x86), 1)
> +    LIBUNWIND_LIBS += -lunwind-x86
> +    $(call detected,CONFIG_LIBUNWIND_X86)
> +    CFLAGS += -DHAVE_LIBUNWIND_X86_SUPPORT
> +  endif
> +
>    ifneq ($(feature-libunwind), 1)
>      msg := $(warning No libunwind found. Please install libunwind-dev[el] >= 
> 1.1 and/or set LIBUNWIND_DIR);
>      NO_LIBUNWIND := 1
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 8c6c8a0..25c31fb 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -100,6 +100,7 @@ libperf-$(CONFIG_DWARF) += dwarf-aux.o
>  
>  libperf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
>  libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind.o
> +libperf-$(CONFIG_LIBUNWIND)          += unwind-libunwind_common.o
>  
>  libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
>  
> diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
> index 45fcb71..3043113 100644
> --- a/tools/perf/util/thread.c
> +++ b/tools/perf/util/thread.c
> @@ -205,6 +205,8 @@ void thread__insert_map(struct thread *thread, struct map 
> *map)
>  {
>       map_groups__fixup_overlappings(thread->mg, map, stderr);
>       map_groups__insert(thread->mg, map);
> +
> +     unwind__get_arch(thread, map);
>  }
>  
>  static int thread__clone_map_groups(struct thread *thread,
> diff --git a/tools/perf/util/unwind-libunwind_common.c 
> b/tools/perf/util/unwind-libunwind_common.c
> new file mode 100644
> index 0000000..3946c99
> --- /dev/null
> +++ b/tools/perf/util/unwind-libunwind_common.c
> @@ -0,0 +1,34 @@
> +#include "thread.h"
> +#include "session.h"
> +#include "unwind.h"
> +#include "symbol.h"
> +#include "debug.h"
> +#include "arch/common.h"
> +
> +void unwind__get_arch(struct thread *thread, struct map *map)
> +{
> +     const char *arch;
> +     enum dso_type dso_type;
> +
> +     if (!thread->mg->machine->env)
> +             return;
> +
> +     dso_type = dso__type(map->dso, thread->mg->machine);
> +     if (dso_type == DSO__TYPE_UNKNOWN)
> +             return;
> +
> +     if (thread->addr_space)
> +             pr_debug("unwind: thread map already set, 64bit is %d, 
> dso=%s\n",
> +                      dso_type == DSO__TYPE_64BIT, map->dso->name);
> +
> +     arch = normalize_arch(thread->mg->machine->env->arch);
> +
> +     if (!strcmp(arch, "x86")) {
> +             if (dso_type != DSO__TYPE_64BIT)
> +#ifdef HAVE_LIBUNWIND_X86_SUPPORT
> +                     pr_err("unwind: target platform=%s is not 
> implemented\n", arch);
> +#else
> +                     pr_err("unwind: target platform=%s is not supported\n", 
> arch);
> +#endif
> +     }
> +}
> diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h
> index 12790cf..889d630 100644
> --- a/tools/perf/util/unwind.h
> +++ b/tools/perf/util/unwind.h
> @@ -24,6 +24,7 @@ int libunwind__arch_reg_id(int regnum);
>  int unwind__prepare_access(struct thread *thread);
>  void unwind__flush_access(struct thread *thread);
>  void unwind__finish_access(struct thread *thread);
> +void unwind__get_arch(struct thread *thread, struct map *map);
>  #else
>  static inline int unwind__prepare_access(struct thread *thread 
> __maybe_unused)
>  {
> @@ -32,6 +33,8 @@ static inline int unwind__prepare_access(struct thread 
> *thread __maybe_unused)
>  
>  static inline void unwind__flush_access(struct thread *thread 
> __maybe_unused) {}
>  static inline void unwind__finish_access(struct thread *thread 
> __maybe_unused) {}
> +static inline void unwind__get_arch(struct thread *thread __maybe_unused,
> +                                 struct map *map __maybe_unused) {}
>  #endif
>  #else
>  static inline int
> @@ -51,5 +54,7 @@ static inline int unwind__prepare_access(struct thread 
> *thread __maybe_unused)
>  
>  static inline void unwind__flush_access(struct thread *thread 
> __maybe_unused) {}
>  static inline void unwind__finish_access(struct thread *thread 
> __maybe_unused) {}
> +static inline void unwind__get_arch(struct thread *thread __maybe_unused,
> +                                 struct map *map __maybe_unused) {}
>  #endif /* HAVE_DWARF_UNWIND_SUPPORT */
>  #endif /* __UNWIND_H */
> -- 
> 1.8.5.2

Reply via email to