diff options
Diffstat (limited to 'tools/perf/util/llvm-utils.c')
-rw-r--r-- | tools/perf/util/llvm-utils.c | 42 |
1 files changed, 42 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 | ||
331 | static void | ||
332 | dump_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); | ||
363 | out: | ||
364 | free(obj_path); | ||
365 | } | ||
366 | |||
329 | int llvm__compile_bpf(const char *path, void **p_obj_buf, | 367 | int 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 |