diff options
Diffstat (limited to '')
-rw-r--r-- | tools/perf/util/genelf_debug.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/tools/perf/util/genelf_debug.c b/tools/perf/util/genelf_debug.c index dd40683bd4c0..8588b3e35e00 100644 --- a/tools/perf/util/genelf_debug.c +++ b/tools/perf/util/genelf_debug.c @@ -11,6 +11,7 @@ * @author Philippe Elie */ #include <linux/compiler.h> +#include <linux/zalloc.h> #include <sys/types.h> #include <stdio.h> #include <getopt.h> @@ -87,6 +88,12 @@ buffer_ext_init(struct buffer_ext *be) be->max_sz = 0; } +static void +buffer_ext_exit(struct buffer_ext *be) +{ + zfree(&be->data); +} + static inline size_t buffer_ext_size(struct buffer_ext *be) { @@ -330,6 +337,9 @@ static void emit_lineno_info(struct buffer_ext *be, { size_t i; + /* as described in the jitdump format */ + const char repeated_name_marker[] = {'\xff', '\0'}; + /* * Machine state at start of a statement program * address = 0 @@ -356,7 +366,8 @@ static void emit_lineno_info(struct buffer_ext *be, /* * check if filename changed, if so add it */ - if (!cur_filename || strcmp(cur_filename, ent->name)) { + if ((!cur_filename || strcmp(cur_filename, ent->name)) && + strcmp(repeated_name_marker, ent->name)) { emit_lne_define_filename(be, ent->name); cur_filename = ent->name; emit_set_file(be, ++cur_file_idx); @@ -487,28 +498,28 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries Elf_Scn *scn; Elf_Shdr *shdr; struct buffer_ext dl, di, da; - int ret; + int ret = -1; buffer_ext_init(&dl); buffer_ext_init(&di); buffer_ext_init(&da); - ret = jit_process_debug_info(code_addr, debug, nr_debug_entries, &dl, &da, &di); - if (ret) - return -1; + if (jit_process_debug_info(code_addr, debug, nr_debug_entries, &dl, &da, &di)) + goto out; + /* * setup .debug_line section */ scn = elf_newscn(e); if (!scn) { warnx("cannot create section"); - return -1; + goto out; } d = elf_newdata(scn); if (!d) { warnx("cannot get new data"); - return -1; + goto out; } d->d_align = 1; @@ -521,7 +532,7 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries shdr = elf_getshdr(scn); if (!shdr) { warnx("cannot get section header"); - return -1; + goto out; } shdr->sh_name = 52; /* .debug_line */ @@ -536,13 +547,13 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries scn = elf_newscn(e); if (!scn) { warnx("cannot create section"); - return -1; + goto out; } d = elf_newdata(scn); if (!d) { warnx("cannot get new data"); - return -1; + goto out; } d->d_align = 1; @@ -555,7 +566,7 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries shdr = elf_getshdr(scn); if (!shdr) { warnx("cannot get section header"); - return -1; + goto out; } shdr->sh_name = 64; /* .debug_info */ @@ -570,13 +581,13 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries scn = elf_newscn(e); if (!scn) { warnx("cannot create section"); - return -1; + goto out; } d = elf_newdata(scn); if (!d) { warnx("cannot get new data"); - return -1; + goto out; } d->d_align = 1; @@ -589,7 +600,7 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries shdr = elf_getshdr(scn); if (!shdr) { warnx("cannot get section header"); - return -1; + goto out; } shdr->sh_name = 76; /* .debug_info */ @@ -601,9 +612,14 @@ jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries /* * now we update the ELF image with all the sections */ - if (elf_update(e, ELF_C_WRITE) < 0) { + if (elf_update(e, ELF_C_WRITE) < 0) warnx("elf_update debug failed"); - return -1; - } - return 0; + else + ret = 0; + +out: + buffer_ext_exit(&dl); + buffer_ext_exit(&di); + buffer_ext_exit(&da); + return ret; } |