lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sun,  1 Dec 2013 17:07:07 -0700
From:	David Ahern <dsahern@...il.com>
To:	acme@...stprotocols.net, linux-kernel@...r.kernel.org
Cc:	David Ahern <dsahern@...il.com>,
	Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>,
	Srikar Dronamraju <srikar@...ux.vnet.ibm.com>
Subject: [PATCH 2/2] perf probe: Allow user to specify address within executable

Allow user to specify an address within an executable. This is useful, for
example, in probing local functions. If the function name begins with 0x
then try to convert the supplied name to an address. If succuessful then
treat the function name as the address within the executable to be probed.

Signed-off-by: David Ahern <dsahern@...il.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>
Cc: Srikar Dronamraju <srikar@...ux.vnet.ibm.com>
---
 tools/perf/Documentation/perf-probe.txt |  2 +-
 tools/perf/util/probe-event.c           | 37 +++++++++++++++++++++++++--------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index b715cb71592b..ed500b311176 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -123,7 +123,7 @@ Probe points are defined by following syntax.
 
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'.
-'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  In addition, '@...' specifies a source file which has that function.
+'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  In addition, '@...' specifies a source file which has that function. If 'FUNC' starts with 0x and the entire string converts to an unsigned long it is treated as an address.
 It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
 
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 638071b7bdd2..000e535b3df2 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2208,6 +2208,9 @@ static struct strfilter *available_func_filter;
 static int filter_available_functions(struct map *map __maybe_unused,
 				      struct symbol *sym)
 {
+	if (available_func_filter == NULL)
+		return 0;
+
 	if (sym->binding == STB_GLOBAL &&
 	    strfilter__compare(available_func_filter, sym->name))
 		return 0;
@@ -2281,9 +2284,10 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
 	struct perf_probe_point *pp = &pev->point;
 	struct symbol *sym;
 	struct map *map = NULL;
-	char *function = NULL, *name = NULL;
+	char *function = NULL, *name = NULL, *endptr;
 	int ret = -EINVAL;
 	unsigned long long vaddr = 0;
+	unsigned long fcn_addr = 0;
 
 	if (!pp->function) {
 		pr_warning("No function specified for uprobes");
@@ -2297,6 +2301,13 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
 		goto out;
 	}
 
+	/* perhaps an address was given instead of a function name */
+	if (strncmp(function, "0x", 2) == 0) {
+		fcn_addr = strtoul(function, &endptr, 0);
+		if (endptr && *endptr != '\0')
+			fcn_addr = 0;
+	}
+
 	name = realpath(exec, NULL);
 	if (!name) {
 		pr_warning("Cannot find realpath for %s.\n", exec);
@@ -2307,22 +2318,30 @@ static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
 		pr_warning("Cannot find appropriate DSO for %s.\n", exec);
 		goto out;
 	}
-	available_func_filter = strfilter__new(function, NULL);
+
+	if (fcn_addr == 0)
+		available_func_filter = strfilter__new(function, NULL);
+
 	if (map__load(map, filter_available_functions)) {
 		pr_err("Failed to find requested function in %s. Perhaps it is a local variable?\n",
 		       name);
 		goto out;
 	}
 
-	sym = map__find_symbol_by_name(map, function, NULL);
-	if (!sym) {
-		pr_warning("Cannot find %s in DSO %s\n", function, exec);
-		goto out;
+	if (fcn_addr) {
+		vaddr = fcn_addr + pp->offset + map->pgoff;
+	} else {
+		sym = map__find_symbol_by_name(map, function, NULL);
+		if (!sym) {
+			pr_warning("Cannot find %s in DSO %s\n", function, exec);
+			goto out;
+		}
+
+		if (map->start > sym->start)
+			vaddr = map->start;
+		vaddr += sym->start + pp->offset + map->pgoff;
 	}
 
-	if (map->start > sym->start)
-		vaddr = map->start;
-	vaddr += sym->start + pp->offset + map->pgoff;
 	pp->offset = 0;
 
 	if (!pev->event) {
-- 
1.8.3.4 (Apple Git-47)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists