aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/perf/util/genelf_debug.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/perf/util/genelf_debug.c52
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;
}