From: tip-bot for Stephane Eranian <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: dsahern@gmail.com, mingo@kernel.org, johnmccutchan@google.com,
hpa@zytor.com, cel@us.ibm.com, jolsa@redhat.com,
pawel.moll@arm.com, sukadev@linux.vnet.ibm.com,
namhyung@kernel.org, sonnyrao@chromium.org, tglx@linutronix.de,
linux-kernel@vger.kernel.org, ak@linux.intel.com,
acme@redhat.com, peterz@infradead.org, adrian.hunter@intel.com,
eranian@google.com
Subject: [tip:perf/core] perf symbols: add Java demangling support
Date: Tue, 9 Feb 2016 04:14:34 -0800 [thread overview]
Message-ID: <tip-e9c4bcdd349eb00f6c704450a063b3dcbea25864@git.kernel.org> (raw)
In-Reply-To: <1448874143-7269-2-git-send-email-eranian@google.com>
Commit-ID: e9c4bcdd349eb00f6c704450a063b3dcbea25864
Gitweb: http://git.kernel.org/tip/e9c4bcdd349eb00f6c704450a063b3dcbea25864
Author: Stephane Eranian <eranian@google.com>
AuthorDate: Mon, 30 Nov 2015 10:02:20 +0100
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 5 Feb 2016 09:46:45 -0300
perf symbols: add Java demangling support
Add Java function descriptor demangling support. Something bfd cannot
do.
Use the JAVA_DEMANGLE_NORET flag to avoid decoding the return type of
functions.
Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Carl Love <cel@us.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: John McCutchan <johnmccutchan@google.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sonny Rao <sonnyrao@chromium.org>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1448874143-7269-2-git-send-email-eranian@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/Build | 1 +
tools/perf/util/demangle-java.c | 199 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/demangle-java.h | 10 ++
tools/perf/util/symbol-elf.c | 3 +
4 files changed, 213 insertions(+)
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 5eec53a..edae107 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -105,6 +105,7 @@ libperf-y += scripting-engines/
libperf-$(CONFIG_ZLIB) += zlib.o
libperf-$(CONFIG_LZMA) += lzma.o
+libperf-y += demangle-java.o
CFLAGS_config.o += -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c
new file mode 100644
index 0000000..3e6062a
--- /dev/null
+++ b/tools/perf/util/demangle-java.c
@@ -0,0 +1,199 @@
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include "util.h"
+#include "debug.h"
+#include "symbol.h"
+
+#include "demangle-java.h"
+
+enum {
+ MODE_PREFIX = 0,
+ MODE_CLASS = 1,
+ MODE_FUNC = 2,
+ MODE_TYPE = 3,
+ MODE_CTYPE = 3, /* class arg */
+};
+
+#define BASE_ENT(c, n) [c - 'A']=n
+static const char *base_types['Z' - 'A' + 1] = {
+ BASE_ENT('B', "byte" ),
+ BASE_ENT('C', "char" ),
+ BASE_ENT('D', "double" ),
+ BASE_ENT('F', "float" ),
+ BASE_ENT('I', "int" ),
+ BASE_ENT('J', "long" ),
+ BASE_ENT('S', "short" ),
+ BASE_ENT('Z', "bool" ),
+};
+
+/*
+ * demangle Java symbol between str and end positions and stores
+ * up to maxlen characters into buf. The parser starts in mode.
+ *
+ * Use MODE_PREFIX to process entire prototype till end position
+ * Use MODE_TYPE to process return type if str starts on return type char
+ *
+ * Return:
+ * success: buf
+ * error : NULL
+ */
+static char *
+__demangle_java_sym(const char *str, const char *end, char *buf, int maxlen, int mode)
+{
+ int rlen = 0;
+ int array = 0;
+ int narg = 0;
+ const char *q;
+
+ if (!end)
+ end = str + strlen(str);
+
+ for (q = str; q != end; q++) {
+
+ if (rlen == (maxlen - 1))
+ break;
+
+ switch (*q) {
+ case 'L':
+ if (mode == MODE_PREFIX || mode == MODE_CTYPE) {
+ if (mode == MODE_CTYPE) {
+ if (narg)
+ rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
+ narg++;
+ }
+ rlen += scnprintf(buf + rlen, maxlen - rlen, "class ");
+ if (mode == MODE_PREFIX)
+ mode = MODE_CLASS;
+ } else
+ buf[rlen++] = *q;
+ break;
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ if (mode == MODE_TYPE) {
+ if (narg)
+ rlen += scnprintf(buf + rlen, maxlen - rlen, ", ");
+ rlen += scnprintf(buf + rlen, maxlen - rlen, "%s", base_types[*q - 'A']);
+ while (array--)
+ rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
+ array = 0;
+ narg++;
+ } else
+ buf[rlen++] = *q;
+ break;
+ case 'V':
+ if (mode == MODE_TYPE) {
+ rlen += scnprintf(buf + rlen, maxlen - rlen, "void");
+ while (array--)
+ rlen += scnprintf(buf + rlen, maxlen - rlen, "[]");
+ array = 0;
+ } else
+ buf[rlen++] = *q;
+ break;
+ case '[':
+ if (mode != MODE_TYPE)
+ goto error;
+ array++;
+ break;
+ case '(':
+ if (mode != MODE_FUNC)
+ goto error;
+ buf[rlen++] = *q;
+ mode = MODE_TYPE;
+ break;
+ case ')':
+ if (mode != MODE_TYPE)
+ goto error;
+ buf[rlen++] = *q;
+ narg = 0;
+ break;
+ case ';':
+ if (mode != MODE_CLASS && mode != MODE_CTYPE)
+ goto error;
+ /* safe because at least one other char to process */
+ if (isalpha(*(q + 1)))
+ rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
+ if (mode == MODE_CLASS)
+ mode = MODE_FUNC;
+ else if (mode == MODE_CTYPE)
+ mode = MODE_TYPE;
+ break;
+ case '/':
+ if (mode != MODE_CLASS && mode != MODE_CTYPE)
+ goto error;
+ rlen += scnprintf(buf + rlen, maxlen - rlen, ".");
+ break;
+ default :
+ buf[rlen++] = *q;
+ }
+ }
+ buf[rlen] = '\0';
+ return buf;
+error:
+ return NULL;
+}
+
+/*
+ * Demangle Java function signature (openJDK, not GCJ)
+ * input:
+ * str: string to parse. String is not modified
+ * flags: comobination of JAVA_DEMANGLE_* flags to modify demangling
+ * return:
+ * if input can be demangled, then a newly allocated string is returned.
+ * if input cannot be demangled, then NULL is returned
+ *
+ * Note: caller is responsible for freeing demangled string
+ */
+char *
+java_demangle_sym(const char *str, int flags)
+{
+ char *buf, *ptr;
+ char *p;
+ size_t len, l1 = 0;
+
+ if (!str)
+ return NULL;
+
+ /* find start of retunr type */
+ p = strrchr(str, ')');
+ if (!p)
+ return NULL;
+
+ /*
+ * expansion factor estimated to 3x
+ */
+ len = strlen(str) * 3 + 1;
+ buf = malloc(len);
+ if (!buf)
+ return NULL;
+
+ buf[0] = '\0';
+ if (!(flags & JAVA_DEMANGLE_NORET)) {
+ /*
+ * get return type first
+ */
+ ptr = __demangle_java_sym(p + 1, NULL, buf, len, MODE_TYPE);
+ if (!ptr)
+ goto error;
+
+ /* add space between return type and function prototype */
+ l1 = strlen(buf);
+ buf[l1++] = ' ';
+ }
+
+ /* process function up to return type */
+ ptr = __demangle_java_sym(str, p + 1, buf + l1, len - l1, MODE_PREFIX);
+ if (!ptr)
+ goto error;
+
+ return buf;
+error:
+ free(buf);
+ return NULL;
+}
diff --git a/tools/perf/util/demangle-java.h b/tools/perf/util/demangle-java.h
new file mode 100644
index 0000000..a981c1f
--- /dev/null
+++ b/tools/perf/util/demangle-java.h
@@ -0,0 +1,10 @@
+#ifndef __PERF_DEMANGLE_JAVA
+#define __PERF_DEMANGLE_JAVA 1
+/*
+ * demangle function flags
+ */
+#define JAVA_DEMANGLE_NORET 0x1 /* do not process return type */
+
+char * java_demangle_sym(const char *str, int flags);
+
+#endif /* __PERF_DEMANGLE_JAVA */
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 562b8eb..b1dd68f 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -6,6 +6,7 @@
#include <inttypes.h>
#include "symbol.h"
+#include "demangle-java.h"
#include "machine.h"
#include "vdso.h"
#include <symbol/kallsyms.h>
@@ -1077,6 +1078,8 @@ new_symbol:
demangle_flags = DMGL_PARAMS | DMGL_ANSI;
demangled = bfd_demangle(NULL, elf_name, demangle_flags);
+ if (demangled == NULL)
+ demangled = java_demangle_sym(elf_name, JAVA_DEMANGLE_NORET);
if (demangled != NULL)
elf_name = demangled;
}
next prev parent reply other threads:[~2016-02-09 12:15 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-30 9:02 [PATCH v8 0/4] perf: add support for profiling jitted code Stephane Eranian
2015-11-30 9:02 ` [PATCH v8 1/4] perf tools: add Java demangling support Stephane Eranian
2016-02-09 12:14 ` tip-bot for Stephane Eranian [this message]
2015-11-30 9:02 ` [PATCH v8 2/4] perf inject: add jitdump mmap injection support Stephane Eranian
2016-01-22 20:44 ` Arnaldo Carvalho de Melo
2016-01-22 21:22 ` Stephane Eranian
[not found] ` <20160122215542.GK4034@kernel.org>
[not found] ` <20160122220929.GL4034@kernel.org>
2016-01-22 22:10 ` Arnaldo Carvalho de Melo
2016-02-04 21:53 ` Arnaldo Carvalho de Melo
2016-02-04 23:02 ` Stephane Eranian
2016-02-05 13:47 ` Arnaldo Carvalho de Melo
2016-02-05 13:51 ` Arnaldo Carvalho de Melo
2016-02-05 13:57 ` Arnaldo Carvalho de Melo
2016-02-05 14:24 ` Arnaldo Carvalho de Melo
2016-02-08 18:53 ` Stephane Eranian
2016-02-11 22:16 ` Arnaldo Carvalho de Melo
2016-02-12 20:32 ` Stephane Eranian
2016-02-12 20:43 ` Arnaldo Carvalho de Melo
2016-02-15 2:16 ` Stephane Eranian
2016-02-15 17:14 ` Arnaldo Carvalho de Melo
2016-02-09 12:14 ` [tip:perf/core] perf build: Add libcrypto feature detection tip-bot for Stephane Eranian
2016-02-09 12:15 ` [tip:perf/core] perf inject: Make sure mmap records are ordered when injecting build_ids tip-bot for Arnaldo Carvalho de Melo
2016-02-09 12:15 ` [tip:perf/core] perf inject: Add jitdump mmap injection support tip-bot for Stephane Eranian
2015-11-30 9:02 ` [PATCH v8 3/4] perf tools: add JVMTI agent library Stephane Eranian
2016-02-09 12:16 ` [tip:perf/core] " tip-bot for Stephane Eranian
2015-11-30 9:02 ` [PATCH v8 4/4] perf/jit: add source line info support Stephane Eranian
2016-02-09 12:16 ` [tip:perf/core] perf jit: " tip-bot for Stephane Eranian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-e9c4bcdd349eb00f6c704450a063b3dcbea25864@git.kernel.org \
--to=tipbot@zytor.com \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=ak@linux.intel.com \
--cc=cel@us.ibm.com \
--cc=dsahern@gmail.com \
--cc=eranian@google.com \
--cc=hpa@zytor.com \
--cc=johnmccutchan@google.com \
--cc=jolsa@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=namhyung@kernel.org \
--cc=pawel.moll@arm.com \
--cc=peterz@infradead.org \
--cc=sonnyrao@chromium.org \
--cc=sukadev@linux.vnet.ibm.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.