From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
To: acme@kernel.org, mhiramat@kernel.org
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
mingo@redhat.com, alexander.shishkin@linux.intel.com,
wangnan0@huawei.com, hemant@linux.vnet.ibm.com,
naveen.n.rao@linux.vnet.ibm.com,
Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Subject: [PATCH] perf probe: Move dwarf specific functions to dwarf-aux.c
Date: Mon, 29 Aug 2016 20:40:01 +0530 [thread overview]
Message-ID: <1472483401-4129-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com> (raw)
In-Reply-To: <20160827092752.109349f00b5e69e548a68074@kernel.org>
Move generic dwarf related functions from util/probe-finder.c to
util/dwarf-aux.c. Function names and their prototype are also
changed accordingly. No functionality changes.
Suggested-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
---
tools/perf/util/dwarf-aux.c | 135 ++++++++++++++++++++++++++++++++++++++++
tools/perf/util/dwarf-aux.h | 5 ++
tools/perf/util/probe-finder.c | 136 +----------------------------------------
3 files changed, 142 insertions(+), 134 deletions(-)
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index a347b19..8d595b9 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -1085,3 +1085,138 @@ int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
return -ENOTSUP;
}
#endif
+
+static bool die_has_loclist(Dwarf_Die *var_die)
+{
+ Dwarf_Attribute loc;
+ int tag = dwarf_tag(var_die);
+
+ if (tag != DW_TAG_formal_parameter &&
+ tag != DW_TAG_variable)
+ return false;
+
+ return (dwarf_attr_integrate(var_die, DW_AT_location, &loc) &&
+ dwarf_whatform(&loc) == DW_FORM_sec_offset);
+}
+
+/*
+ * For any object in given CU whose DW_AT_location is a location list,
+ * target program is compiled with optimization.
+ */
+bool die_is_optimized_target(Dwarf_Die *cu_die)
+{
+ Dwarf_Die tmp_die;
+
+ if (die_has_loclist(cu_die))
+ return true;
+
+ if (!dwarf_child(cu_die, &tmp_die) &&
+ die_is_optimized_target(&tmp_die))
+ return true;
+
+ if (!dwarf_siblingof(cu_die, &tmp_die) &&
+ die_is_optimized_target(&tmp_die))
+ return true;
+
+ return false;
+}
+
+static bool die_search_idx(Dwarf_Lines *lines, unsigned long nr_lines,
+ Dwarf_Addr pf_addr, unsigned long *idx)
+{
+ unsigned long i;
+ Dwarf_Addr addr;
+
+ for (i = 0; i < nr_lines; i++) {
+ if (dwarf_lineaddr(dwarf_onesrcline(lines, i), &addr))
+ return false;
+
+ if (addr == pf_addr) {
+ *idx = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool die_get_postprologue_addr(unsigned long entrypc_idx,
+ Dwarf_Lines *lines,
+ unsigned long nr_lines,
+ Dwarf_Addr highpc,
+ Dwarf_Addr *postprologue_addr)
+{
+ unsigned long i;
+ int entrypc_lno, lno;
+ Dwarf_Line *line;
+ Dwarf_Addr addr;
+ bool p_end;
+
+ /* entrypc_lno is actual source line number */
+ line = dwarf_onesrcline(lines, entrypc_idx);
+ if (dwarf_lineno(line, &entrypc_lno))
+ return false;
+
+ for (i = entrypc_idx; i < nr_lines; i++) {
+ line = dwarf_onesrcline(lines, i);
+
+ if (dwarf_lineaddr(line, &addr) ||
+ dwarf_lineno(line, &lno) ||
+ dwarf_lineprologueend(line, &p_end))
+ return false;
+
+ /* highpc is exclusive. [entrypc,highpc) */
+ if (addr >= highpc)
+ break;
+
+ /* clang supports prologue-end marker */
+ if (p_end)
+ break;
+
+ /* Actual next line in source */
+ if (lno != entrypc_lno)
+ break;
+
+ /*
+ * Single source line can have multiple line records.
+ * For Example,
+ * void foo() { printf("hello\n"); }
+ * contains two line records. One points to declaration and
+ * other points to printf() line. Variable 'lno' won't get
+ * incremented in this case but 'i' will.
+ */
+ if (i != entrypc_idx)
+ break;
+ }
+
+ dwarf_lineaddr(line, postprologue_addr);
+ if (*postprologue_addr >= highpc)
+ dwarf_lineaddr(dwarf_onesrcline(lines, i - 1),
+ postprologue_addr);
+
+ return true;
+}
+
+void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die,
+ Dwarf_Addr *entrypc)
+{
+ size_t nr_lines = 0;
+ unsigned long entrypc_idx = 0;
+ Dwarf_Lines *lines = NULL;
+ Dwarf_Addr postprologue_addr;
+ Dwarf_Addr highpc;
+
+ if (dwarf_highpc(sp_die, &highpc))
+ return;
+
+ if (dwarf_getsrclines(cu_die, &lines, &nr_lines))
+ return;
+
+ if (!die_search_idx(lines, nr_lines, *entrypc, &entrypc_idx))
+ return;
+
+ if (!die_get_postprologue_addr(entrypc_idx, lines, nr_lines,
+ highpc, &postprologue_addr))
+ return;
+
+ *entrypc = postprologue_addr;
+}
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index dc0ce1a..791884a 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -125,4 +125,9 @@ int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf);
/* Get the name and type of given variable DIE, stored as "type\tname" */
int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf);
int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf);
+
+bool die_is_optimized_target(Dwarf_Die *cu_die);
+void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die,
+ Dwarf_Addr *entrypc);
+
#endif
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 945cf7a..72f1152 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -901,138 +901,6 @@ static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
return die_walk_lines(sp_die, probe_point_lazy_walker, pf);
}
-static bool var_has_loclist(Dwarf_Die *cu_die)
-{
- Dwarf_Attribute loc;
- int tag = dwarf_tag(cu_die);
-
- if (tag != DW_TAG_formal_parameter &&
- tag != DW_TAG_variable)
- return false;
-
- return (dwarf_attr_integrate(cu_die, DW_AT_location, &loc) &&
- dwarf_whatform(&loc) == DW_FORM_sec_offset);
-}
-
-/*
- * For any object in given CU whose DW_AT_location is a location list,
- * target program is compiled with optimization.
- */
-static bool optimized_target(Dwarf_Die *cu_die)
-{
- Dwarf_Die tmp_die;
-
- if (var_has_loclist(cu_die))
- return true;
-
- if (!dwarf_child(cu_die, &tmp_die) && optimized_target(&tmp_die))
- return true;
-
- if (!dwarf_siblingof(cu_die, &tmp_die) && optimized_target(&tmp_die))
- return true;
-
- return false;
-}
-
-static bool get_entrypc_idx(Dwarf_Lines *lines, unsigned long nr_lines,
- Dwarf_Addr pf_addr, unsigned long *entrypc_idx)
-{
- unsigned long i;
- Dwarf_Addr addr;
-
- for (i = 0; i < nr_lines; i++) {
- if (dwarf_lineaddr(dwarf_onesrcline(lines, i), &addr))
- return false;
-
- if (addr == pf_addr) {
- *entrypc_idx = i;
- return true;
- }
- }
- return false;
-}
-
-static bool get_postprologue_addr(unsigned long entrypc_idx,
- Dwarf_Lines *lines,
- unsigned long nr_lines,
- Dwarf_Addr highpc,
- Dwarf_Addr *postprologue_addr)
-{
- unsigned long i;
- int entrypc_lno, lno;
- Dwarf_Line *line;
- Dwarf_Addr addr;
- bool p_end;
-
- /* entrypc_lno is actual source line number */
- line = dwarf_onesrcline(lines, entrypc_idx);
- if (dwarf_lineno(line, &entrypc_lno))
- return false;
-
- for (i = entrypc_idx; i < nr_lines; i++) {
- line = dwarf_onesrcline(lines, i);
-
- if (dwarf_lineaddr(line, &addr) ||
- dwarf_lineno(line, &lno) ||
- dwarf_lineprologueend(line, &p_end))
- return false;
-
- /* highpc is exclusive. [entrypc,highpc) */
- if (addr >= highpc)
- break;
-
- /* clang supports prologue-end marker */
- if (p_end)
- break;
-
- /* Actual next line in source */
- if (lno != entrypc_lno)
- break;
-
- /*
- * Single source line can have multiple line records.
- * For Example,
- * void foo() { printf("hello\n"); }
- * contains two line records. One points to declaration and
- * other points to printf() line. Variable 'lno' won't get
- * incremented in this case but 'i' will.
- */
- if (i != entrypc_idx)
- break;
- }
-
- dwarf_lineaddr(line, postprologue_addr);
- if (*postprologue_addr >= highpc)
- dwarf_lineaddr(dwarf_onesrcline(lines, i - 1),
- postprologue_addr);
-
- return true;
-}
-
-static void __skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
-{
- size_t nr_lines = 0;
- unsigned long entrypc_idx = 0;
- Dwarf_Lines *lines = NULL;
- Dwarf_Addr postprologue_addr;
- Dwarf_Addr highpc;
-
- if (dwarf_highpc(sp_die, &highpc))
- return;
-
- if (dwarf_getsrclines(&pf->cu_die, &lines, &nr_lines))
- return;
-
- if (!get_entrypc_idx(lines, nr_lines, pf->addr, &entrypc_idx))
- return;
-
- if (!get_postprologue_addr(entrypc_idx, lines, nr_lines,
- highpc, &postprologue_addr))
- return;
-
- pf->addr = postprologue_addr;
-}
-
static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
{
struct perf_probe_point *pp = &pf->pev->point;
@@ -1042,7 +910,7 @@ static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
return;
/* Compiled with optimization? */
- if (optimized_target(&pf->cu_die))
+ if (die_is_optimized_target(&pf->cu_die))
return;
/* Don't know entrypc? */
@@ -1062,7 +930,7 @@ static void skip_prologue(Dwarf_Die *sp_die, struct probe_finder *pf)
"Probe on address 0x%" PRIx64 " to force probing at the function entry.\n\n",
pf->addr);
- __skip_prologue(sp_die, pf);
+ die_skip_prologue(sp_die, &pf->cu_die, &pf->addr);
}
static int probe_point_inline_cb(Dwarf_Die *in_die, void *data)
--
2.5.5
next prev parent reply other threads:[~2016-08-29 15:10 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-03 8:58 [PATCH 1/2] perf probe: Helper function to check if probe with variable Ravi Bangoria
2016-08-03 8:58 ` [PATCH v2 2/2] perf uprobe: Skip prologue if program compiled without optimization Ravi Bangoria
2016-08-13 13:45 ` Ravi Bangoria
2016-08-25 12:30 ` Masami Hiramatsu
2016-08-18 9:17 ` Naveen N. Rao
2016-08-25 12:50 ` Masami Hiramatsu
2016-08-25 13:59 ` Jiri Olsa
2016-08-25 15:17 ` Arnaldo Carvalho de Melo
2016-08-25 15:44 ` Jiri Olsa
2016-08-26 19:30 ` Arnaldo Carvalho de Melo
2016-08-26 19:54 ` Arnaldo Carvalho de Melo
2016-08-27 0:27 ` Masami Hiramatsu
2016-08-29 15:10 ` Ravi Bangoria [this message]
2016-08-29 22:53 ` [PATCH] perf probe: Move dwarf specific functions to dwarf-aux.c Masami Hiramatsu
2016-08-30 8:39 ` [PATCH v2] " Ravi Bangoria
2016-08-30 14:10 ` Masami Hiramatsu
2016-09-05 13:27 ` [tip:perf/core] " tip-bot for Ravi Bangoria
2016-08-29 8:09 ` [PATCH v2 2/2] perf uprobe: Skip prologue if program compiled without optimization Ravi Bangoria
2016-08-29 8:08 ` Ravi Bangoria
2016-09-05 13:26 ` [tip:perf/core] " tip-bot for Ravi Bangoria
2016-08-25 12:32 ` [PATCH 1/2] perf probe: Helper function to check if probe with variable Masami Hiramatsu
2016-09-05 13:26 ` [tip:perf/core] perf probe: Add helper " tip-bot for Ravi Bangoria
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=1472483401-4129-1-git-send-email-ravi.bangoria@linux.vnet.ibm.com \
--to=ravi.bangoria@linux.vnet.ibm.com \
--cc=acme@kernel.org \
--cc=alexander.shishkin@linux.intel.com \
--cc=hemant@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhiramat@kernel.org \
--cc=mingo@redhat.com \
--cc=naveen.n.rao@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=wangnan0@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®