diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 5d68f68797a9..65be284823d5 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -137,7 +137,8 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) | |||
137 | return kmap->ref_reloc_sym; | 137 | return kmap->ref_reloc_sym; |
138 | } | 138 | } |
139 | 139 | ||
140 | static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc) | 140 | static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, |
141 | bool reloc, bool reladdr) | ||
141 | { | 142 | { |
142 | struct ref_reloc_sym *reloc_sym; | 143 | struct ref_reloc_sym *reloc_sym; |
143 | struct symbol *sym; | 144 | struct symbol *sym; |
@@ -146,12 +147,14 @@ static u64 kernel_get_symbol_address_by_name(const char *name, bool reloc) | |||
146 | /* ref_reloc_sym is just a label. Need a special fix*/ | 147 | /* ref_reloc_sym is just a label. Need a special fix*/ |
147 | reloc_sym = kernel_get_ref_reloc_sym(); | 148 | reloc_sym = kernel_get_ref_reloc_sym(); |
148 | if (reloc_sym && strcmp(name, reloc_sym->name) == 0) | 149 | if (reloc_sym && strcmp(name, reloc_sym->name) == 0) |
149 | return (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; | 150 | *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; |
150 | else { | 151 | else { |
151 | sym = __find_kernel_function_by_name(name, &map); | 152 | sym = __find_kernel_function_by_name(name, &map); |
152 | if (sym) | 153 | if (!sym) |
153 | return map->unmap_ip(map, sym->start) - | 154 | return -ENOENT; |
154 | ((reloc) ? 0 : map->reloc); | 155 | *addr = map->unmap_ip(map, sym->start) - |
156 | ((reloc) ? 0 : map->reloc) - | ||
157 | ((reladdr) ? map->start : 0); | ||
155 | } | 158 | } |
156 | return 0; | 159 | return 0; |
157 | } | 160 | } |
@@ -245,12 +248,14 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) | |||
245 | static bool kprobe_blacklist__listed(unsigned long address); | 248 | static bool kprobe_blacklist__listed(unsigned long address); |
246 | static bool kprobe_warn_out_range(const char *symbol, unsigned long address) | 249 | static bool kprobe_warn_out_range(const char *symbol, unsigned long address) |
247 | { | 250 | { |
248 | u64 etext_addr; | 251 | u64 etext_addr = 0; |
252 | int ret; | ||
249 | 253 | ||
250 | /* Get the address of _etext for checking non-probable text symbol */ | 254 | /* Get the address of _etext for checking non-probable text symbol */ |
251 | etext_addr = kernel_get_symbol_address_by_name("_etext", false); | 255 | ret = kernel_get_symbol_address_by_name("_etext", &etext_addr, |
256 | false, false); | ||
252 | 257 | ||
253 | if (etext_addr != 0 && etext_addr < address) | 258 | if (ret == 0 && etext_addr < address) |
254 | pr_warning("%s is out of .text, skip it.\n", symbol); | 259 | pr_warning("%s is out of .text, skip it.\n", symbol); |
255 | else if (kprobe_blacklist__listed(address)) | 260 | else if (kprobe_blacklist__listed(address)) |
256 | pr_warning("%s is blacklisted function, skip it.\n", symbol); | 261 | pr_warning("%s is blacklisted function, skip it.\n", symbol); |
@@ -517,8 +522,10 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, | |||
517 | goto error; | 522 | goto error; |
518 | addr += stext; | 523 | addr += stext; |
519 | } else if (tp->symbol) { | 524 | } else if (tp->symbol) { |
520 | addr = kernel_get_symbol_address_by_name(tp->symbol, false); | 525 | /* If the module is given, this returns relative address */ |
521 | if (addr == 0) | 526 | ret = kernel_get_symbol_address_by_name(tp->symbol, &addr, |
527 | false, !!tp->module); | ||
528 | if (ret != 0) | ||
522 | goto error; | 529 | goto error; |
523 | addr += tp->offset; | 530 | addr += tp->offset; |
524 | } | 531 | } |
@@ -1884,8 +1891,12 @@ static int find_perf_probe_point_from_map(struct probe_trace_point *tp, | |||
1884 | goto out; | 1891 | goto out; |
1885 | sym = map__find_symbol(map, addr, NULL); | 1892 | sym = map__find_symbol(map, addr, NULL); |
1886 | } else { | 1893 | } else { |
1887 | if (tp->symbol) | 1894 | if (tp->symbol && !addr) { |
1888 | addr = kernel_get_symbol_address_by_name(tp->symbol, true); | 1895 | ret = kernel_get_symbol_address_by_name(tp->symbol, |
1896 | &addr, true, false); | ||
1897 | if (ret < 0) | ||
1898 | goto out; | ||
1899 | } | ||
1889 | if (addr) { | 1900 | if (addr) { |
1890 | addr += tp->offset; | 1901 | addr += tp->offset; |
1891 | sym = __find_kernel_function(addr, &map); | 1902 | sym = __find_kernel_function(addr, &map); |