From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753914AbcFPIEH (ORCPT ); Thu, 16 Jun 2016 04:04:07 -0400 Received: from szxga02-in.huawei.com ([119.145.14.65]:52744 "EHLO szxga02-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751681AbcFPIDi (ORCPT ); Thu, 16 Jun 2016 04:03:38 -0400 From: Wang Nan To: CC: , , Wang Nan , Arnaldo Carvalho de Melo , "Alexei Starovoitov" , Jiri Olsa Subject: [PATCH 1/2] perf llvm: Allow dump llvm output object file using llvm.dump-obj Date: Thu, 16 Jun 2016 08:02:40 +0000 Message-ID: <1466064161-48553-2-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 In-Reply-To: <1466064161-48553-1-git-send-email-wangnan0@huawei.com> References: <1466064161-48553-1-git-send-email-wangnan0@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090205.57625D44.0015,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 5c55abf52aec94cdf4cfc335d44d03bd Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add a 'llvm.dump-obj' config option to enable perf dump BPF object files compiled by LLVM. This option is useful when using BPF objects in embedded platforms. LLVM compiler won't be deployed in these platforms, and currently we don't support dynamic compiling library. Before this patch users have to explicitly issue llvm commands to compile BPF scripts, and can't use helpers (like include path detection and default macros) in perf. With this option, user is allowed to use perf to compile their BPF objects then copy them into their embedded platforms. Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Jiri Olsa --- tools/perf/util/llvm-utils.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/llvm-utils.h | 5 +++++ 2 files changed, 47 insertions(+) diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c index 33071d6..ede8f7d 100644 --- a/tools/perf/util/llvm-utils.c +++ b/tools/perf/util/llvm-utils.c @@ -42,6 +42,8 @@ int perf_llvm_config(const char *var, const char *value) llvm_param.kbuild_dir = strdup(value); else if (!strcmp(var, "kbuild-opts")) llvm_param.kbuild_opts = strdup(value); + else if (!strcmp(var, "dump-obj")) + llvm_param.dump_obj = !!perf_config_bool(var, value); else return -1; llvm_param.user_set_param = true; @@ -326,6 +328,42 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts) pr_debug("include option is set to %s\n", *kbuild_include_opts); } +static void +dump_obj(const char *path, void *obj_buf, size_t size) +{ + char *obj_path = strdup(path); + FILE *fp; + char *p; + + if (!obj_path) { + pr_warning("WARNING: No enough memory, skip object dumpping\n"); + return; + } + + p = strrchr(obj_path, '.'); + if (!p || (strcmp(p, ".c") != 0)) { + pr_warning("WARNING: invalid llvm source path: '%s', skip object dumpping\n", + obj_path); + goto out; + } + + p[1] = 'o'; + fp = fopen(obj_path, "wb"); + if (!fp) { + pr_warning("WARNING: failed to open '%s': %s, skip object dumpping\n", + obj_path, strerror(errno)); + goto out; + } + + pr_info("LLVM: dumpping %s\n", obj_path); + if (fwrite(obj_buf, size, 1, fp) != 1) + pr_warning("WARNING: failed to write to file '%s': %s, skip object dumpping\n", + obj_path, strerror(errno)); + fclose(fp); +out: + free(obj_path); +} + int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz) { @@ -411,6 +449,10 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf, free(kbuild_dir); free(kbuild_include_opts); + + if (llvm_param.dump_obj) + dump_obj(path, obj_buf, obj_buf_sz); + if (!p_obj_buf) free(obj_buf); else diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h index 23b9a74..9f501ce 100644 --- a/tools/perf/util/llvm-utils.h +++ b/tools/perf/util/llvm-utils.h @@ -30,6 +30,11 @@ struct llvm_param { */ const char *kbuild_opts; /* + * Default is false. If set to true, write compiling result + * to object file. + */ + bool dump_obj; + /* * Default is false. If one of the above fields is set by user * explicitly then user_set_llvm is set to true. This is used * for perf test. If user doesn't set anything in .perfconfig -- 1.8.3.4