aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/llvm-utils.c42
-rw-r--r--tools/perf/util/llvm-utils.h5
2 files changed, 47 insertions, 0 deletions
diff --git a/tools/perf/util/llvm-utils.c b/tools/perf/util/llvm-utils.c
index 33071d6159bc..878a566763c3 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)
42 llvm_param.kbuild_dir = strdup(value); 42 llvm_param.kbuild_dir = strdup(value);
43 else if (!strcmp(var, "kbuild-opts")) 43 else if (!strcmp(var, "kbuild-opts"))
44 llvm_param.kbuild_opts = strdup(value); 44 llvm_param.kbuild_opts = strdup(value);
45 else if (!strcmp(var, "dump-obj"))
46 llvm_param.dump_obj = !!perf_config_bool(var, value);
45 else 47 else
46 return -1; 48 return -1;
47 llvm_param.user_set_param = true; 49 llvm_param.user_set_param = true;
@@ -326,6 +328,42 @@ get_kbuild_opts(char **kbuild_dir, char **kbuild_include_opts)
326 pr_debug("include option is set to %s\n", *kbuild_include_opts); 328 pr_debug("include option is set to %s\n", *kbuild_include_opts);
327} 329}
328 330
331static void
332dump_obj(const char *path, void *obj_buf, size_t size)
333{
334 char *obj_path = strdup(path);
335 FILE *fp;
336 char *p;
337
338 if (!obj_path) {
339 pr_warning("WARNING: No enough memory, skip object dumping\n");
340 return;
341 }
342
343 p = strrchr(obj_path, '.');
344 if (!p || (strcmp(p, ".c") != 0)) {
345 pr_warning("WARNING: invalid llvm source path: '%s', skip object dumping\n",
346 obj_path);
347 goto out;
348 }
349
350 p[1] = 'o';
351 fp = fopen(obj_path, "wb");
352 if (!fp) {
353 pr_warning("WARNING: failed to open '%s': %s, skip object dumping\n",
354 obj_path, strerror(errno));
355 goto out;
356 }
357
358 pr_info("LLVM: dumping %s\n", obj_path);
359 if (fwrite(obj_buf, size, 1, fp) != 1)
360 pr_warning("WARNING: failed to write to file '%s': %s, skip object dumping\n",
361 obj_path, strerror(errno));
362 fclose(fp);
363out:
364 free(obj_path);
365}
366
329int llvm__compile_bpf(const char *path, void **p_obj_buf, 367int llvm__compile_bpf(const char *path, void **p_obj_buf,
330 size_t *p_obj_buf_sz) 368 size_t *p_obj_buf_sz)
331{ 369{
@@ -411,6 +449,10 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
411 449
412 free(kbuild_dir); 450 free(kbuild_dir);
413 free(kbuild_include_opts); 451 free(kbuild_include_opts);
452
453 if (llvm_param.dump_obj)
454 dump_obj(path, obj_buf, obj_buf_sz);
455
414 if (!p_obj_buf) 456 if (!p_obj_buf)
415 free(obj_buf); 457 free(obj_buf);
416 else 458 else
diff --git a/tools/perf/util/llvm-utils.h b/tools/perf/util/llvm-utils.h
index 23b9a743fe72..9f501cef06a1 100644
--- a/tools/perf/util/llvm-utils.h
+++ b/tools/perf/util/llvm-utils.h
@@ -30,6 +30,11 @@ struct llvm_param {
30 */ 30 */
31 const char *kbuild_opts; 31 const char *kbuild_opts;
32 /* 32 /*
33 * Default is false. If set to true, write compiling result
34 * to object file.
35 */
36 bool dump_obj;
37 /*
33 * Default is false. If one of the above fields is set by user 38 * Default is false. If one of the above fields is set by user
34 * explicitly then user_set_llvm is set to true. This is used 39 * explicitly then user_set_llvm is set to true. This is used
35 * for perf test. If user doesn't set anything in .perfconfig 40 * for perf test. If user doesn't set anything in .perfconfig