~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/probe-event.c

Version: ~ [ linux-5.1-rc5 ] ~ [ linux-5.0.7 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.34 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.111 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.168 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.178 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.138 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.65 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * probe-event.c : perf-probe definition to probe_events format converter
  3  *
  4  * Written by Masami Hiramatsu <mhiramat@redhat.com>
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License as published by
  8  * the Free Software Foundation; either version 2 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * This program is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with this program; if not, write to the Free Software
 18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 19  *
 20  */
 21 
 22 #include <inttypes.h>
 23 #include <sys/utsname.h>
 24 #include <sys/types.h>
 25 #include <sys/stat.h>
 26 #include <fcntl.h>
 27 #include <errno.h>
 28 #include <stdio.h>
 29 #include <unistd.h>
 30 #include <stdlib.h>
 31 #include <string.h>
 32 #include <stdarg.h>
 33 #include <limits.h>
 34 #include <elf.h>
 35 
 36 #include "util.h"
 37 #include "event.h"
 38 #include "namespaces.h"
 39 #include "strlist.h"
 40 #include "strfilter.h"
 41 #include "debug.h"
 42 #include "cache.h"
 43 #include "color.h"
 44 #include "map.h"
 45 #include "map_groups.h"
 46 #include "symbol.h"
 47 #include "thread.h"
 48 #include <api/fs/fs.h>
 49 #include "trace-event.h"        /* For __maybe_unused */
 50 #include "probe-event.h"
 51 #include "probe-finder.h"
 52 #include "probe-file.h"
 53 #include "session.h"
 54 #include "string2.h"
 55 
 56 #include "sane_ctype.h"
 57 
 58 #define PERFPROBE_GROUP "probe"
 59 
 60 bool probe_event_dry_run;       /* Dry run flag */
 61 struct probe_conf probe_conf;
 62 
 63 #define semantic_error(msg ...) pr_err("Semantic error :" msg)
 64 
 65 int e_snprintf(char *str, size_t size, const char *format, ...)
 66 {
 67         int ret;
 68         va_list ap;
 69         va_start(ap, format);
 70         ret = vsnprintf(str, size, format, ap);
 71         va_end(ap);
 72         if (ret >= (int)size)
 73                 ret = -E2BIG;
 74         return ret;
 75 }
 76 
 77 static struct machine *host_machine;
 78 
 79 /* Initialize symbol maps and path of vmlinux/modules */
 80 int init_probe_symbol_maps(bool user_only)
 81 {
 82         int ret;
 83 
 84         symbol_conf.sort_by_name = true;
 85         symbol_conf.allow_aliases = true;
 86         ret = symbol__init(NULL);
 87         if (ret < 0) {
 88                 pr_debug("Failed to init symbol map.\n");
 89                 goto out;
 90         }
 91 
 92         if (host_machine || user_only)  /* already initialized */
 93                 return 0;
 94 
 95         if (symbol_conf.vmlinux_name)
 96                 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
 97 
 98         host_machine = machine__new_host();
 99         if (!host_machine) {
100                 pr_debug("machine__new_host() failed.\n");
101                 symbol__exit();
102                 ret = -1;
103         }
104 out:
105         if (ret < 0)
106                 pr_warning("Failed to init vmlinux path.\n");
107         return ret;
108 }
109 
110 void exit_probe_symbol_maps(void)
111 {
112         machine__delete(host_machine);
113         host_machine = NULL;
114         symbol__exit();
115 }
116 
117 static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void)
118 {
119         /* kmap->ref_reloc_sym should be set if host_machine is initialized */
120         struct kmap *kmap;
121         struct map *map = machine__kernel_map(host_machine);
122 
123         if (map__load(map) < 0)
124                 return NULL;
125 
126         kmap = map__kmap(map);
127         if (!kmap)
128                 return NULL;
129         return kmap->ref_reloc_sym;
130 }
131 
132 static int kernel_get_symbol_address_by_name(const char *name, u64 *addr,
133                                              bool reloc, bool reladdr)
134 {
135         struct ref_reloc_sym *reloc_sym;
136         struct symbol *sym;
137         struct map *map;
138 
139         /* ref_reloc_sym is just a label. Need a special fix*/
140         reloc_sym = kernel_get_ref_reloc_sym();
141         if (reloc_sym && strcmp(name, reloc_sym->name) == 0)
142                 *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr;
143         else {
144                 sym = machine__find_kernel_symbol_by_name(host_machine, name, &map);
145                 if (!sym)
146                         return -ENOENT;
147                 *addr = map->unmap_ip(map, sym->start) -
148                         ((reloc) ? 0 : map->reloc) -
149                         ((reladdr) ? map->start : 0);
150         }
151         return 0;
152 }
153 
154 static struct map *kernel_get_module_map(const char *module)
155 {
156         struct maps *maps = machine__kernel_maps(host_machine);
157         struct map *pos;
158 
159         /* A file path -- this is an offline module */
160         if (module && strchr(module, '/'))
161                 return dso__new_map(module);
162 
163         if (!module) {
164                 pos = machine__kernel_map(host_machine);
165                 return map__get(pos);
166         }
167 
168         for (pos = maps__first(maps); pos; pos = map__next(pos)) {
169                 /* short_name is "[module]" */
170                 if (strncmp(pos->dso->short_name + 1, module,
171                             pos->dso->short_name_len - 2) == 0 &&
172                     module[pos->dso->short_name_len - 2] == '\0') {
173                         return map__get(pos);
174                 }
175         }
176         return NULL;
177 }
178 
179 struct map *get_target_map(const char *target, struct nsinfo *nsi, bool user)
180 {
181         /* Init maps of given executable or kernel */
182         if (user) {
183                 struct map *map;
184 
185                 map = dso__new_map(target);
186                 if (map && map->dso)
187                         map->dso->nsinfo = nsinfo__get(nsi);
188                 return map;
189         } else {
190                 return kernel_get_module_map(target);
191         }
192 }
193 
194 static int convert_exec_to_group(const char *exec, char **result)
195 {
196         char *ptr1, *ptr2, *exec_copy;
197         char buf[64];
198         int ret;
199 
200         exec_copy = strdup(exec);
201         if (!exec_copy)
202                 return -ENOMEM;
203 
204         ptr1 = basename(exec_copy);
205         if (!ptr1) {
206                 ret = -EINVAL;
207                 goto out;
208         }
209 
210         for (ptr2 = ptr1; *ptr2 != '\0'; ptr2++) {
211                 if (!isalnum(*ptr2) && *ptr2 != '_') {
212                         *ptr2 = '\0';
213                         break;
214                 }
215         }
216 
217         ret = e_snprintf(buf, 64, "%s_%s", PERFPROBE_GROUP, ptr1);
218         if (ret < 0)
219                 goto out;
220 
221         *result = strdup(buf);
222         ret = *result ? 0 : -ENOMEM;
223 
224 out:
225         free(exec_copy);
226         return ret;
227 }
228 
229 static void clear_perf_probe_point(struct perf_probe_point *pp)
230 {
231         free(pp->file);
232         free(pp->function);
233         free(pp->lazy_line);
234 }
235 
236 static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs)
237 {
238         int i;
239 
240         for (i = 0; i < ntevs; i++)
241                 clear_probe_trace_event(tevs + i);
242 }
243 
244 static bool kprobe_blacklist__listed(unsigned long address);
245 static bool kprobe_warn_out_range(const char *symbol, unsigned long address)
246 {
247         u64 etext_addr = 0;
248         int ret;
249 
250         /* Get the address of _etext for checking non-probable text symbol */
251         ret = kernel_get_symbol_address_by_name("_etext", &etext_addr,
252                                                 false, false);
253 
254         if (ret == 0 && etext_addr < address)
255                 pr_warning("%s is out of .text, skip it.\n", symbol);
256         else if (kprobe_blacklist__listed(address))
257                 pr_warning("%s is blacklisted function, skip it.\n", symbol);
258         else
259                 return false;
260 
261         return true;
262 }
263 
264 /*
265  * @module can be module name of module file path. In case of path,
266  * inspect elf and find out what is actual module name.
267  * Caller has to free mod_name after using it.
268  */
269 static char *find_module_name(const char *module)
270 {
271         int fd;
272         Elf *elf;
273         GElf_Ehdr ehdr;
274         GElf_Shdr shdr;
275         Elf_Data *data;
276         Elf_Scn *sec;
277         char *mod_name = NULL;
278         int name_offset;
279 
280         fd = open(module, O_RDONLY);
281         if (fd < 0)
282                 return NULL;
283 
284         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
285         if (elf == NULL)
286                 goto elf_err;
287 
288         if (gelf_getehdr(elf, &ehdr) == NULL)
289                 goto ret_err;
290 
291         sec = elf_section_by_name(elf, &ehdr, &shdr,
292                         ".gnu.linkonce.this_module", NULL);
293         if (!sec)
294                 goto ret_err;
295 
296         data = elf_getdata(sec, NULL);
297         if (!data || !data->d_buf)
298                 goto ret_err;
299 
300         /*
301          * NOTE:
302          * '.gnu.linkonce.this_module' section of kernel module elf directly
303          * maps to 'struct module' from linux/module.h. This section contains
304          * actual module name which will be used by kernel after loading it.
305          * But, we cannot use 'struct module' here since linux/module.h is not
306          * exposed to user-space. Offset of 'name' has remained same from long
307          * time, so hardcoding it here.
308          */
309         if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
310                 name_offset = 12;
311         else    /* expect ELFCLASS64 by default */
312                 name_offset = 24;
313 
314         mod_name = strdup((char *)data->d_buf + name_offset);
315 
316 ret_err:
317         elf_end(elf);
318 elf_err:
319         close(fd);
320         return mod_name;
321 }
322 
323 #ifdef HAVE_DWARF_SUPPORT
324 
325 static int kernel_get_module_dso(const char *module, struct dso **pdso)
326 {
327         struct dso *dso;
328         struct map *map;
329         const char *vmlinux_name;
330         int ret = 0;
331 
332         if (module) {
333                 char module_name[128];
334 
335                 snprintf(module_name, sizeof(module_name), "[%s]", module);
336                 map = map_groups__find_by_name(&host_machine->kmaps, module_name);
337                 if (map) {
338                         dso = map->dso;
339                         goto found;
340                 }
341                 pr_debug("Failed to find module %s.\n", module);
342                 return -ENOENT;
343         }
344 
345         map = machine__kernel_map(host_machine);
346         dso = map->dso;
347 
348         vmlinux_name = symbol_conf.vmlinux_name;
349         dso->load_errno = 0;
350         if (vmlinux_name)
351                 ret = dso__load_vmlinux(dso, map, vmlinux_name, false);
352         else
353                 ret = dso__load_vmlinux_path(dso, map);
354 found:
355         *pdso = dso;
356         return ret;
357 }
358 
359 /*
360  * Some binaries like glibc have special symbols which are on the symbol
361  * table, but not in the debuginfo. If we can find the address of the
362  * symbol from map, we can translate the address back to the probe point.
363  */
364 static int find_alternative_probe_point(struct debuginfo *dinfo,
365                                         struct perf_probe_point *pp,
366                                         struct perf_probe_point *result,
367                                         const char *target, struct nsinfo *nsi,
368                                         bool uprobes)
369 {
370         struct map *map = NULL;
371         struct symbol *sym;
372         u64 address = 0;
373         int ret = -ENOENT;
374 
375         /* This can work only for function-name based one */
376         if (!pp->function || pp->file)
377                 return -ENOTSUP;
378 
379         map = get_target_map(target, nsi, uprobes);
380         if (!map)
381                 return -EINVAL;
382 
383         /* Find the address of given function */
384         map__for_each_symbol_by_name(map, pp->function, sym) {
385                 if (uprobes)
386                         address = sym->start;
387                 else
388                         address = map->unmap_ip(map, sym->start) - map->reloc;
389                 break;
390         }
391         if (!address) {
392                 ret = -ENOENT;
393                 goto out;
394         }
395         pr_debug("Symbol %s address found : %" PRIx64 "\n",
396                         pp->function, address);
397 
398         ret = debuginfo__find_probe_point(dinfo, (unsigned long)address,
399                                           result);
400         if (ret <= 0)
401                 ret = (!ret) ? -ENOENT : ret;
402         else {
403                 result->offset += pp->offset;
404                 result->line += pp->line;
405                 result->retprobe = pp->retprobe;
406                 ret = 0;
407         }
408 
409 out:
410         map__put(map);
411         return ret;
412 
413 }
414 
415 static int get_alternative_probe_event(struct debuginfo *dinfo,
416                                        struct perf_probe_event *pev,
417                                        struct perf_probe_point *tmp)
418 {
419         int ret;
420 
421         memcpy(tmp, &pev->point, sizeof(*tmp));
422         memset(&pev->point, 0, sizeof(pev->point));
423         ret = find_alternative_probe_point(dinfo, tmp, &pev->point, pev->target,
424                                            pev->nsi, pev->uprobes);
425         if (ret < 0)
426                 memcpy(&pev->point, tmp, sizeof(*tmp));
427 
428         return ret;
429 }
430 
431 static int get_alternative_line_range(struct debuginfo *dinfo,
432                                       struct line_range *lr,
433                                       const char *target, bool user)
434 {
435         struct perf_probe_point pp = { .function = lr->function,
436                                        .file = lr->file,
437                                        .line = lr->start };
438         struct perf_probe_point result;
439         int ret, len = 0;
440 
441         memset(&result, 0, sizeof(result));
442 
443         if (lr->end != INT_MAX)
444                 len = lr->end - lr->start;
445         ret = find_alternative_probe_point(dinfo, &pp, &result,
446                                            target, NULL, user);
447         if (!ret) {
448                 lr->function = result.function;
449                 lr->file = result.file;
450                 lr->start = result.line;
451                 if (lr->end != INT_MAX)
452                         lr->end = lr->start + len;
453                 clear_perf_probe_point(&pp);
454         }
455         return ret;
456 }
457 
458 /* Open new debuginfo of given module */
459 static struct debuginfo *open_debuginfo(const char *module, struct nsinfo *nsi,
460                                         bool silent)
461 {
462         const char *path = module;
463         char reason[STRERR_BUFSIZE];
464         struct debuginfo *ret = NULL;
465         struct dso *dso = NULL;
466         struct nscookie nsc;
467         int err;
468 
469         if (!module || !strchr(module, '/')) {
470                 err = kernel_get_module_dso(module, &dso);
471                 if (err < 0) {
472                         if (!dso || dso->load_errno == 0) {
473                                 if (!str_error_r(-err, reason, STRERR_BUFSIZE))
474                                         strcpy(reason, "(unknown)");
475                         } else
476                                 dso__strerror_load(dso, reason, STRERR_BUFSIZE);
477                         if (!silent) {
478                                 if (module)
479                                         pr_err("Module %s is not loaded, please specify its full path name.\n", module);
480                                 else
481                                         pr_err("Failed to find the path for the kernel: %s\n", reason);
482                         }
483                         return NULL;
484                 }
485                 path = dso->long_name;
486         }
487         nsinfo__mountns_enter(nsi, &nsc);
488         ret = debuginfo__new(path);
489         if (!ret && !silent) {
490                 pr_warning("The %s file has no debug information.\n", path);
491                 if (!module || !strtailcmp(path, ".ko"))
492                         pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, ");
493                 else
494                         pr_warning("Rebuild with -g, ");
495                 pr_warning("or install an appropriate debuginfo package.\n");
496         }
497         nsinfo__mountns_exit(&nsc);
498         return ret;
499 }
500 
501 /* For caching the last debuginfo */
502 static struct debuginfo *debuginfo_cache;
503 static char *debuginfo_cache_path;
504 
505 static struct debuginfo *debuginfo_cache__open(const char *module, bool silent)
506 {
507         const char *path = module;
508 
509         /* If the module is NULL, it should be the kernel. */
510         if (!module)
511                 path = "kernel";
512 
513         if (debuginfo_cache_path && !strcmp(debuginfo_cache_path, path))
514                 goto out;
515 
516         /* Copy module path */
517         free(debuginfo_cache_path);
518         debuginfo_cache_path = strdup(path);
519         if (!debuginfo_cache_path) {
520                 debuginfo__delete(debuginfo_cache);
521                 debuginfo_cache = NULL;
522                 goto out;
523         }
524 
525         debuginfo_cache = open_debuginfo(module, NULL, silent);
526         if (!debuginfo_cache)
527                 zfree(&debuginfo_cache_path);
528 out:
529         return debuginfo_cache;
530 }
531 
532 static void debuginfo_cache__exit(void)
533 {
534         debuginfo__delete(debuginfo_cache);
535         debuginfo_cache = NULL;
536         zfree(&debuginfo_cache_path);
537 }
538 
539 
540 static int get_text_start_address(const char *exec, unsigned long *address,
541                                   struct nsinfo *nsi)
542 {
543         Elf *elf;
544         GElf_Ehdr ehdr;
545         GElf_Shdr shdr;
546         int fd, ret = -ENOENT;
547         struct nscookie nsc;
548 
549         nsinfo__mountns_enter(nsi, &nsc);
550         fd = open(exec, O_RDONLY);
551         nsinfo__mountns_exit(&nsc);
552         if (fd < 0)
553                 return -errno;
554 
555         elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
556         if (elf == NULL) {
557                 ret = -EINVAL;
558                 goto out_close;
559         }
560 
561         if (gelf_getehdr(elf, &ehdr) == NULL)
562                 goto out;
563 
564         if (!elf_section_by_name(elf, &ehdr, &shdr, ".text", NULL))
565                 goto out;
566 
567         *address = shdr.sh_addr - shdr.sh_offset;
568         ret = 0;
569 out:
570         elf_end(elf);
571 out_close:
572         close(fd);
573 
574         return ret;
575 }
576 
577 /*
578  * Convert trace point to probe point with debuginfo
579  */
580 static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp,
581                                             struct perf_probe_point *pp,
582                                             bool is_kprobe)
583 {
584         struct debuginfo *dinfo = NULL;
585         unsigned long stext = 0;
586         u64 addr = tp->address;
587         int ret = -ENOENT;
588 
589         /* convert the address to dwarf address */
590         if (!is_kprobe) {
591                 if (!addr) {
592                         ret = -EINVAL;
593                         goto error;
594                 }
595                 ret = get_text_start_address(tp->module, &stext, NULL);
596                 if (ret < 0)
597                         goto error;
598                 addr += stext;
599         } else if (tp->symbol) {
600                 /* If the module is given, this returns relative address */
601                 ret = kernel_get_symbol_address_by_name(tp->symbol, &addr,
602                                                         false, !!tp->module);
603                 if (ret != 0)
604                         goto error;
605                 addr += tp->offset;
606         }
607 
608         pr_debug("try to find information at %" PRIx64 " in %s\n", addr,
609                  tp->module ? : "kernel");
610 
611         dinfo = debuginfo_cache__open(tp->module, verbose <= 0);
612         if (dinfo)
613                 ret = debuginfo__find_probe_point(dinfo,
614                                                  (unsigned long)addr, pp);
615         else
616                 ret = -ENOENT;
617 
618         if (ret > 0) {
619                 pp->retprobe = tp->retprobe;
620                 return 0;
621         }
622 error:
623         pr_debug("Failed to find corresponding probes from debuginfo.\n");
624         return ret ? : -ENOENT;
625 }
626 
627 /* Adjust symbol name and address */
628 static int post_process_probe_trace_point(struct probe_trace_point *tp,
629                                            struct map *map, unsigned long offs)
630 {
631         struct symbol *sym;
632         u64 addr = tp->address - offs;
633 
634         sym = map__find_symbol(map, addr);
635         if (!sym)
636                 return -ENOENT;
637 
638         if (strcmp(sym->name, tp->symbol)) {
639                 /* If we have no realname, use symbol for it */
640                 if (!tp->realname)
641                         tp->realname = tp->symbol;
642                 else
643                         free(tp->symbol);
644                 tp->symbol = strdup(sym->name);
645                 if (!tp->symbol)
646                         return -ENOMEM;
647         }
648         tp->offset = addr - sym->start;
649         tp->address -= offs;
650 
651         return 0;
652 }
653 
654 /*
655  * Rename DWARF symbols to ELF symbols -- gcc sometimes optimizes functions
656  * and generate new symbols with suffixes such as .constprop.N or .isra.N
657  * etc. Since those symbols are not recorded in DWARF, we have to find
658  * correct generated symbols from offline ELF binary.
659  * For online kernel or uprobes we don't need this because those are
660  * rebased on _text, or already a section relative address.
661  */
662 static int
663 post_process_offline_probe_trace_events(struct probe_trace_event *tevs,
664                                         int ntevs, const char *pathname)
665 {
666         struct map *map;
667         unsigned long stext = 0;
668         int i, ret = 0;
669 
670         /* Prepare a map for offline binary */
671         map = dso__new_map(pathname);
672         if (!map || get_text_start_address(pathname, &stext, NULL) < 0) {
673                 pr_warning("Failed to get ELF symbols for %s\n", pathname);
674                 return -EINVAL;
675         }
676 
677         for (i = 0; i < ntevs; i++) {
678                 ret = post_process_probe_trace_point(&tevs[i].point,
679                                                      map, stext);
680                 if (ret < 0)
681                         break;
682         }
683         map__put(map);
684 
685         return ret;
686 }
687 
688 static int add_exec_to_probe_trace_events(struct probe_trace_event *tevs,
689                                           int ntevs, const char *exec,
690                                           struct nsinfo *nsi)
691 {
692         int i, ret = 0;
693         unsigned long stext = 0;
694 
695         if (!exec)
696                 return 0;
697 
698         ret = get_text_start_address(exec, &stext, nsi);
699         if (ret < 0)
700                 return ret;
701 
702         for (i = 0; i < ntevs && ret >= 0; i++) {
703                 /* point.address is the address of point.symbol + point.offset */
704                 tevs[i].point.address -= stext;
705                 tevs[i].point.module = strdup(exec);
706                 if (!tevs[i].point.module) {
707                         ret = -ENOMEM;
708                         break;
709                 }
710                 tevs[i].uprobes = true;
711         }
712 
713         return ret;
714 }
715 
716 static int
717 post_process_module_probe_trace_events(struct probe_trace_event *tevs,
718                                        int ntevs, const char *module,
719                                        struct debuginfo *dinfo)
720 {
721         Dwarf_Addr text_offs = 0;
722         int i, ret = 0;
723         char *mod_name = NULL;
724         struct map *map;
725 
726         if (!module)
727                 return 0;
728 
729         map = get_target_map(module, NULL, false);
730         if (!map || debuginfo__get_text_offset(dinfo, &text_offs, true) < 0) {
731                 pr_warning("Failed to get ELF symbols for %s\n", module);
732                 return -EINVAL;
733         }
734 
735         mod_name = find_module_name(module);
736         for (i = 0; i < ntevs; i++) {
737                 ret = post_process_probe_trace_point(&tevs[i].point,
738                                                 map, (unsigned long)text_offs);
739                 if (ret < 0)
740                         break;
741                 tevs[i].point.module =
742                         strdup(mod_name ? mod_name : module);
743                 if (!tevs[i].point.module) {
744                         ret = -ENOMEM;
745                         break;
746                 }
747         }
748 
749         free(mod_name);
750         map__put(map);
751 
752         return ret;
753 }
754 
755 static int
756 post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
757                                        int ntevs)
758 {
759         struct ref_reloc_sym *reloc_sym;
760         char *tmp;
761         int i, skipped = 0;
762 
763         /* Skip post process if the target is an offline kernel */
764         if (symbol_conf.ignore_vmlinux_buildid)
765                 return post_process_offline_probe_trace_events(tevs, ntevs,
766                                                 symbol_conf.vmlinux_name);
767 
768         reloc_sym = kernel_get_ref_reloc_sym();
769         if (!reloc_sym) {
770                 pr_warning("Relocated base symbol is not found!\n");
771                 return -EINVAL;
772         }
773 
774         for (i = 0; i < ntevs; i++) {
775                 if (!tevs[i].point.address)
776                         continue;
777                 if (tevs[i].point.retprobe && !kretprobe_offset_is_supported())
778                         continue;
779                 /* If we found a wrong one, mark it by NULL symbol */
780                 if (kprobe_warn_out_range(tevs[i].point.symbol,
781                                           tevs[i].point.address)) {
782                         tmp = NULL;
783                         skipped++;
784                 } else {
785                         tmp = strdup(reloc_sym->name);
786                         if (!tmp)
787                                 return -ENOMEM;
788                 }
789                 /* If we have no realname, use symbol for it */
790                 if (!tevs[i].point.realname)
791                         tevs[i].point.realname = tevs[i].point.symbol;
792                 else
793                         free(tevs[i].point.symbol);
794                 tevs[i].point.symbol = tmp;
795                 tevs[i].point.offset = tevs[i].point.address -
796                                        reloc_sym->unrelocated_addr;
797         }
798         return skipped;
799 }
800 
801 void __weak
802 arch__post_process_probe_trace_events(struct perf_probe_event *pev __maybe_unused,
803                                       int ntevs __maybe_unused)
804 {
805 }
806 
807 /* Post processing the probe events */
808 static int post_process_probe_trace_events(struct perf_probe_event *pev,
809                                            struct probe_trace_event *tevs,
810                                            int ntevs, const char *module,
811                                            bool uprobe, struct debuginfo *dinfo)
812 {
813         int ret;
814 
815         if (uprobe)
816                 ret = add_exec_to_probe_trace_events(tevs, ntevs, module,
817                                                      pev->nsi);
818         else if (module)
819                 /* Currently ref_reloc_sym based probe is not for drivers */
820                 ret = post_process_module_probe_trace_events(tevs, ntevs,
821                                                              module, dinfo);
822         else
823                 ret = post_process_kernel_probe_trace_events(tevs, ntevs);
824 
825         if (ret >= 0)
826                 arch__post_process_probe_trace_events(pev, ntevs);
827 
828         return ret;
829 }
830 
831 /* Try to find perf_probe_event with debuginfo */
832 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
833                                           struct probe_trace_event **tevs)
834 {
835         bool need_dwarf = perf_probe_event_need_dwarf(pev);
836         struct perf_probe_point tmp;
837         struct debuginfo *dinfo;
838         int ntevs, ret = 0;
839 
840         dinfo = open_debuginfo(pev->target, pev->nsi, !need_dwarf);
841         if (!dinfo) {
842                 if (need_dwarf)
843                         return -ENOENT;
844                 pr_debug("Could not open debuginfo. Try to use symbols.\n");
845                 return 0;
846         }
847 
848         pr_debug("Try to find probe point from debuginfo.\n");
849         /* Searching trace events corresponding to a probe event */
850         ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);
851 
852         if (ntevs == 0) {  /* Not found, retry with an alternative */
853                 ret = get_alternative_probe_event(dinfo, pev, &tmp);
854                 if (!ret) {
855                         ntevs = debuginfo__find_trace_events(dinfo, pev, tevs);
856                         /*
857                          * Write back to the original probe_event for
858                          * setting appropriate (user given) event name
859                          */
860                         clear_perf_probe_point(&pev->point);
861                         memcpy(&pev->point, &tmp, sizeof(tmp));
862                 }
863         }
864 
865         if (ntevs > 0) {        /* Succeeded to find trace events */
866                 pr_debug("Found %d probe_trace_events.\n", ntevs);
867                 ret = post_process_probe_trace_events(pev, *tevs, ntevs,
868                                         pev->target, pev->uprobes, dinfo);
869                 if (ret < 0 || ret == ntevs) {
870                         pr_debug("Post processing failed or all events are skipped. (%d)\n", ret);
871                         clear_probe_trace_events(*tevs, ntevs);
872                         zfree(tevs);
873                         ntevs = 0;
874                 }
875         }
876 
877         debuginfo__delete(dinfo);
878 
879         if (ntevs == 0) {       /* No error but failed to find probe point. */
880                 pr_warning("Probe point '%s' not found.\n",
881                            synthesize_perf_probe_point(&pev->point));
882                 return -ENOENT;
883         } else if (ntevs < 0) {
884                 /* Error path : ntevs < 0 */
885                 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
886                 if (ntevs == -EBADF)
887                         pr_warning("Warning: No dwarf info found in the vmlinux - "
888                                 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
889                 if (!need_dwarf) {
890                         pr_debug("Trying to use symbols.\n");
891                         return 0;
892                 }
893         }
894         return ntevs;
895 }
896 
897 #define LINEBUF_SIZE 256
898 #define NR_ADDITIONAL_LINES 2
899 
900 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
901 {
902         char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE];
903         const char *color = show_num ? "" : PERF_COLOR_BLUE;
904         const char *prefix = NULL;
905 
906         do {
907                 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
908                         goto error;
909                 if (skip)
910                         continue;
911                 if (!prefix) {
912                         prefix = show_num ? "%7d  " : "         ";
913                         color_fprintf(stdout, color, prefix, l);
914                 }
915                 color_fprintf(stdout, color, "%s", buf);
916 
917         } while (strchr(buf, '\n') == NULL);
918 
919         return 1;
920 error:
921         if (ferror(fp)) {
922                 pr_warning("File read error: %s\n",
923                            str_error_r(errno, sbuf, sizeof(sbuf)));
924                 return -1;
925         }
926         return 0;
927 }
928 
929 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
930 {
931         int rv = __show_one_line(fp, l, skip, show_num);
932         if (rv == 0) {
933                 pr_warning("Source file is shorter than expected.\n");
934                 rv = -1;
935         }
936         return rv;
937 }
938 
939 #define show_one_line_with_num(f,l)     _show_one_line(f,l,false,true)
940 #define show_one_line(f,l)              _show_one_line(f,l,false,false)
941 #define skip_one_line(f,l)              _show_one_line(f,l,true,false)
942 #define show_one_line_or_eof(f,l)       __show_one_line(f,l,false,false)
943 
944 /*
945  * Show line-range always requires debuginfo to find source file and
946  * line number.
947  */
948 static int __show_line_range(struct line_range *lr, const char *module,
949                              bool user)
950 {
951         int l = 1;
952         struct int_node *ln;
953         struct debuginfo *dinfo;
954         FILE *fp;
955         int ret;
956         char *tmp;
957         char sbuf[STRERR_BUFSIZE];
958 
959         /* Search a line range */
960         dinfo = open_debuginfo(module, NULL, false);
961         if (!dinfo)
962                 return -ENOENT;
963 
964         ret = debuginfo__find_line_range(dinfo, lr);
965         if (!ret) {     /* Not found, retry with an alternative */
966                 ret = get_alternative_line_range(dinfo, lr, module, user);
967                 if (!ret)
968                         ret = debuginfo__find_line_range(dinfo, lr);
969         }
970         debuginfo__delete(dinfo);
971         if (ret == 0 || ret == -ENOENT) {
972                 pr_warning("Specified source line is not found.\n");
973                 return -ENOENT;
974         } else if (ret < 0) {
975                 pr_warning("Debuginfo analysis failed.\n");
976                 return ret;
977         }
978 
979         /* Convert source file path */
980         tmp = lr->path;
981         ret = get_real_path(tmp, lr->comp_dir, &lr->path);
982 
983         /* Free old path when new path is assigned */
984         if (tmp != lr->path)
985                 free(tmp);
986 
987         if (ret < 0) {
988                 pr_warning("Failed to find source file path.\n");
989                 return ret;
990         }
991 
992         setup_pager();
993 
994         if (lr->function)
995                 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path,
996                         lr->start - lr->offset);
997         else
998                 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
999 
1000         fp = fopen(lr->path, "r");
1001         if (fp == NULL) {
1002                 pr_warning("Failed to open %s: %s\n", lr->path,
1003                            str_error_r(errno, sbuf, sizeof(sbuf)));
1004                 return -errno;
1005         }
1006         /* Skip to starting line number */
1007         while (l < lr->start) {
1008                 ret = skip_one_line(fp, l++);
1009                 if (ret < 0)
1010                         goto end;
1011         }
1012 
1013         intlist__for_each_entry(ln, lr->line_list) {
1014                 for (; ln->i > l; l++) {
1015                         ret = show_one_line(fp, l - lr->offset);
1016                         if (ret < 0)
1017                                 goto end;
1018                 }
1019                 ret = show_one_line_with_num(fp, l++ - lr->offset);
1020                 if (ret < 0)
1021                         goto end;
1022         }
1023 
1024         if (lr->end == INT_MAX)
1025                 lr->end = l + NR_ADDITIONAL_LINES;
1026         while (l <= lr->end) {
1027                 ret = show_one_line_or_eof(fp, l++ - lr->offset);
1028                 if (ret <= 0)
1029                         break;
1030         }
1031 end:
1032         fclose(fp);
1033         return ret;
1034 }
1035 
1036 int show_line_range(struct line_range *lr, const char *module,
1037                     struct nsinfo *nsi, bool user)
1038 {
1039         int ret;
1040         struct nscookie nsc;
1041 
1042         ret = init_probe_symbol_maps(user);
1043         if (ret < 0)
1044                 return ret;
1045         nsinfo__mountns_enter(nsi, &nsc);
1046         ret = __show_line_range(lr, module, user);
1047         nsinfo__mountns_exit(&nsc);
1048         exit_probe_symbol_maps();
1049 
1050         return ret;
1051 }
1052 
1053 static int show_available_vars_at(struct debuginfo *dinfo,
1054                                   struct perf_probe_event *pev,
1055                                   struct strfilter *_filter)
1056 {
1057         char *buf;
1058         int ret, i, nvars;
1059         struct str_node *node;
1060         struct variable_list *vls = NULL, *vl;
1061         struct perf_probe_point tmp;
1062         const char *var;
1063 
1064         buf = synthesize_perf_probe_point(&pev->point);
1065         if (!buf)
1066                 return -EINVAL;
1067         pr_debug("Searching variables at %s\n", buf);
1068 
1069         ret = debuginfo__find_available_vars_at(dinfo, pev, &vls);
1070         if (!ret) {  /* Not found, retry with an alternative */
1071                 ret = get_alternative_probe_event(dinfo, pev, &tmp);
1072                 if (!ret) {
1073                         ret = debuginfo__find_available_vars_at(dinfo, pev,
1074                                                                 &vls);
1075                         /* Release the old probe_point */
1076                         clear_perf_probe_point(&tmp);
1077                 }
1078         }
1079         if (ret <= 0) {
1080                 if (ret == 0 || ret == -ENOENT) {
1081                         pr_err("Failed to find the address of %s\n", buf);
1082                         ret = -ENOENT;
1083                 } else
1084                         pr_warning("Debuginfo analysis failed.\n");
1085                 goto end;
1086         }
1087 
1088         /* Some variables are found */
1089         fprintf(stdout, "Available variables at %s\n", buf);
1090         for (i = 0; i < ret; i++) {
1091                 vl = &vls[i];
1092                 /*
1093                  * A probe point might be converted to
1094                  * several trace points.
1095                  */
1096                 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
1097                         vl->point.offset);
1098                 zfree(&vl->point.symbol);
1099                 nvars = 0;
1100                 if (vl->vars) {
1101                         strlist__for_each_entry(node, vl->vars) {
1102                                 var = strchr(node->s, '\t') + 1;
1103                                 if (strfilter__compare(_filter, var)) {
1104                                         fprintf(stdout, "\t\t%s\n", node->s);
1105                                         nvars++;
1106                                 }
1107                         }
1108                         strlist__delete(vl->vars);
1109                 }
1110                 if (nvars == 0)
1111                         fprintf(stdout, "\t\t(No matched variables)\n");
1112         }
1113         free(vls);
1114 end:
1115         free(buf);
1116         return ret;
1117 }
1118 
1119 /* Show available variables on given probe point */
1120 int show_available_vars(struct perf_probe_event *pevs, int npevs,
1121                         struct strfilter *_filter)
1122 {
1123         int i, ret = 0;
1124         struct debuginfo *dinfo;
1125 
1126         ret = init_probe_symbol_maps(pevs->uprobes);
1127         if (ret < 0)
1128                 return ret;
1129 
1130         dinfo = open_debuginfo(pevs->target, pevs->nsi, false);
1131         if (!dinfo) {
1132                 ret = -ENOENT;
1133                 goto out;
1134         }
1135 
1136         setup_pager();
1137 
1138         for (i = 0; i < npevs && ret >= 0; i++)
1139                 ret = show_available_vars_at(dinfo, &pevs[i], _filter);
1140 
1141         debuginfo__delete(dinfo);
1142 out:
1143         exit_probe_symbol_maps();
1144         return ret;
1145 }
1146 
1147 #else   /* !HAVE_DWARF_SUPPORT */
1148 
1149 static void debuginfo_cache__exit(void)
1150 {
1151 }
1152 
1153 static int
1154 find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
1155                                  struct perf_probe_point *pp __maybe_unused,
1156                                  bool is_kprobe __maybe_unused)
1157 {
1158         return -ENOSYS;
1159 }
1160 
1161 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
1162                                 struct probe_trace_event **tevs __maybe_unused)
1163 {
1164         if (perf_probe_event_need_dwarf(pev)) {
1165                 pr_warning("Debuginfo-analysis is not supported.\n");
1166                 return -ENOSYS;
1167         }
1168 
1169         return 0;
1170 }
1171 
1172 int show_line_range(struct line_range *lr __maybe_unused,
1173                     const char *module __maybe_unused,
1174                     struct nsinfo *nsi __maybe_unused,
1175                     bool user __maybe_unused)
1176 {
1177         pr_warning("Debuginfo-analysis is not supported.\n");
1178         return -ENOSYS;
1179 }
1180 
1181 int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
1182                         int npevs __maybe_unused,
1183                         struct strfilter *filter __maybe_unused)
1184 {
1185         pr_warning("Debuginfo-analysis is not supported.\n");
1186         return -ENOSYS;
1187 }
1188 #endif
1189 
1190 void line_range__clear(struct line_range *lr)
1191 {
1192         free(lr->function);
1193         free(lr->file);
1194         free(lr->path);
1195         free(lr->comp_dir);
1196         intlist__delete(lr->line_list);
1197         memset(lr, 0, sizeof(*lr));
1198 }
1199 
1200 int line_range__init(struct line_range *lr)
1201 {
1202         memset(lr, 0, sizeof(*lr));
1203         lr->line_list = intlist__new(NULL);
1204         if (!lr->line_list)
1205                 return -ENOMEM;
1206         else
1207                 return 0;
1208 }
1209 
1210 static int parse_line_num(char **ptr, int *val, const char *what)
1211 {
1212         const char *start = *ptr;
1213 
1214         errno = 0;
1215         *val = strtol(*ptr, ptr, 0);
1216         if (errno || *ptr == start) {
1217                 semantic_error("'%s' is not a valid number.\n", what);
1218                 return -EINVAL;
1219         }
1220         return 0;
1221 }
1222 
1223 /* Check the name is good for event, group or function */
1224 static bool is_c_func_name(const char *name)
1225 {
1226         if (!isalpha(*name) && *name != '_')
1227                 return false;
1228         while (*++name != '\0') {
1229                 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
1230                         return false;
1231         }
1232         return true;
1233 }
1234 
1235 /*
1236  * Stuff 'lr' according to the line range described by 'arg'.
1237  * The line range syntax is described by:
1238  *
1239  *         SRC[:SLN[+NUM|-ELN]]
1240  *         FNC[@SRC][:SLN[+NUM|-ELN]]
1241  */
1242 int parse_line_range_desc(const char *arg, struct line_range *lr)
1243 {
1244         char *range, *file, *name = strdup(arg);
1245         int err;
1246 
1247         if (!name)
1248                 return -ENOMEM;
1249 
1250         lr->start = 0;
1251         lr->end = INT_MAX;
1252 
1253         range = strchr(name, ':');
1254         if (range) {
1255                 *range++ = '\0';
1256 
1257                 err = parse_line_num(&range, &lr->start, "start line");
1258                 if (err)
1259                         goto err;
1260 
1261                 if (*range == '+' || *range == '-') {
1262                         const char c = *range++;
1263 
1264                         err = parse_line_num(&range, &lr->end, "end line");
1265                         if (err)
1266                                 goto err;
1267 
1268                         if (c == '+') {
1269                                 lr->end += lr->start;
1270                                 /*
1271                                  * Adjust the number of lines here.
1272                                  * If the number of lines == 1, the
1273                                  * the end of line should be equal to
1274                                  * the start of line.
1275                                  */
1276                                 lr->end--;
1277                         }
1278                 }
1279 
1280                 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
1281 
1282                 err = -EINVAL;
1283                 if (lr->start > lr->end) {
1284                         semantic_error("Start line must be smaller"
1285                                        " than end line.\n");
1286                         goto err;
1287                 }
1288                 if (*range != '\0') {
1289                         semantic_error("Tailing with invalid str '%s'.\n", range);
1290                         goto err;
1291                 }
1292         }
1293 
1294         file = strchr(name, '@');
1295         if (file) {
1296                 *file = '\0';
1297                 lr->file = strdup(++file);
1298                 if (lr->file == NULL) {
1299                         err = -ENOMEM;
1300                         goto err;
1301                 }
1302                 lr->function = name;
1303         } else if (strchr(name, '/') || strchr(name, '.'))
1304                 lr->file = name;
1305         else if (is_c_func_name(name))/* We reuse it for checking funcname */
1306                 lr->function = name;
1307         else {  /* Invalid name */
1308                 semantic_error("'%s' is not a valid function name.\n", name);
1309                 err = -EINVAL;
1310                 goto err;
1311         }
1312 
1313         return 0;
1314 err:
1315         free(name);
1316         return err;
1317 }
1318 
1319 static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
1320 {
1321         char *ptr;
1322 
1323         ptr = strpbrk_esc(*arg, ":");
1324         if (ptr) {
1325                 *ptr = '\0';
1326                 if (!pev->sdt && !is_c_func_name(*arg))
1327                         goto ng_name;
1328                 pev->group = strdup_esc(*arg);
1329                 if (!pev->group)
1330                         return -ENOMEM;
1331                 *arg = ptr + 1;
1332         } else
1333                 pev->group = NULL;
1334 
1335         pev->event = strdup_esc(*arg);
1336         if (pev->event == NULL)
1337                 return -ENOMEM;
1338 
1339         if (!pev->sdt && !is_c_func_name(pev->event)) {
1340                 zfree(&pev->event);
1341 ng_name:
1342                 zfree(&pev->group);
1343                 semantic_error("%s is bad for event name -it must "
1344                                "follow C symbol-naming rule.\n", *arg);
1345                 return -EINVAL;
1346         }
1347         return 0;
1348 }
1349 
1350 /* Parse probepoint definition. */
1351 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1352 {
1353         struct perf_probe_point *pp = &pev->point;
1354         char *ptr, *tmp;
1355         char c, nc = 0;
1356         bool file_spec = false;
1357         int ret;
1358 
1359         /*
1360          * <Syntax>
1361          * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
1362          * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
1363          * perf probe %[GRP:]SDT_EVENT
1364          */
1365         if (!arg)
1366                 return -EINVAL;
1367 
1368         if (is_sdt_event(arg)) {
1369                 pev->sdt = true;
1370                 if (arg[0] == '%')
1371                         arg++;
1372         }
1373 
1374         ptr = strpbrk_esc(arg, ";=@+%");
1375         if (pev->sdt) {
1376                 if (ptr) {
1377                         if (*ptr != '@') {
1378                                 semantic_error("%s must be an SDT name.\n",
1379                                                arg);
1380                                 return -EINVAL;
1381                         }
1382                         /* This must be a target file name or build id */
1383                         tmp = build_id_cache__complement(ptr + 1);
1384                         if (tmp) {
1385                                 pev->target = build_id_cache__origname(tmp);
1386                                 free(tmp);
1387                         } else
1388                                 pev->target = strdup_esc(ptr + 1);
1389                         if (!pev->target)
1390                                 return -ENOMEM;
1391                         *ptr = '\0';
1392                 }
1393                 ret = parse_perf_probe_event_name(&arg, pev);
1394                 if (ret == 0) {
1395                         if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
1396                                 ret = -errno;
1397                 }
1398                 return ret;
1399         }
1400 
1401         if (ptr && *ptr == '=') {       /* Event name */
1402                 *ptr = '\0';
1403                 tmp = ptr + 1;
1404                 ret = parse_perf_probe_event_name(&arg, pev);
1405                 if (ret < 0)
1406                         return ret;
1407 
1408                 arg = tmp;
1409         }
1410 
1411         /*
1412          * Check arg is function or file name and copy it.
1413          *
1414          * We consider arg to be a file spec if and only if it satisfies
1415          * all of the below criteria::
1416          * - it does not include any of "+@%",
1417          * - it includes one of ":;", and
1418          * - it has a period '.' in the name.
1419          *
1420          * Otherwise, we consider arg to be a function specification.
1421          */
1422         if (!strpbrk_esc(arg, "+@%")) {
1423                 ptr = strpbrk_esc(arg, ";:");
1424                 /* This is a file spec if it includes a '.' before ; or : */
1425                 if (ptr && memchr(arg, '.', ptr - arg))
1426                         file_spec = true;
1427         }
1428 
1429         ptr = strpbrk_esc(arg, ";:+@%");
1430         if (ptr) {
1431                 nc = *ptr;
1432                 *ptr++ = '\0';
1433         }
1434 
1435         if (arg[0] == '\0')
1436                 tmp = NULL;
1437         else {
1438                 tmp = strdup_esc(arg);
1439                 if (tmp == NULL)
1440                         return -ENOMEM;
1441         }
1442 
1443         if (file_spec)
1444                 pp->file = tmp;
1445         else {
1446                 pp->function = tmp;
1447 
1448                 /*
1449                  * Keep pp->function even if this is absolute address,
1450                  * so it can mark whether abs_address is valid.
1451                  * Which make 'perf probe lib.bin 0x0' possible.
1452                  *
1453                  * Note that checking length of tmp is not needed
1454                  * because when we access tmp[1] we know tmp[0] is '',
1455                  * so tmp[1] should always valid (but could be '\0').
1456                  */
1457                 if (tmp && !strncmp(tmp, "0x", 2)) {
1458                         pp->abs_address = strtoul(pp->function, &tmp, 0);
1459                         if (*tmp != '\0') {
1460                                 semantic_error("Invalid absolute address.\n");
1461                                 return -EINVAL;
1462                         }
1463                 }
1464         }
1465 
1466         /* Parse other options */
1467         while (ptr) {
1468                 arg = ptr;
1469                 c = nc;
1470                 if (c == ';') { /* Lazy pattern must be the last part */
1471                         pp->lazy_line = strdup(arg); /* let leave escapes */
1472                         if (pp->lazy_line == NULL)
1473                                 return -ENOMEM;
1474                         break;
1475                 }
1476                 ptr = strpbrk_esc(arg, ";:+@%");
1477                 if (ptr) {
1478                         nc = *ptr;
1479                         *ptr++ = '\0';
1480                 }
1481                 switch (c) {
1482                 case ':':       /* Line number */
1483                         pp->line = strtoul(arg, &tmp, 0);
1484                         if (*tmp != '\0') {
1485                                 semantic_error("There is non-digit char"
1486                                                " in line number.\n");
1487                                 return -EINVAL;
1488                         }
1489                         break;
1490                 case '+':       /* Byte offset from a symbol */
1491                         pp->offset = strtoul(arg, &tmp, 0);
1492                         if (*tmp != '\0') {
1493                                 semantic_error("There is non-digit character"
1494                                                 " in offset.\n");
1495                                 return -EINVAL;
1496                         }
1497                         break;
1498                 case '@':       /* File name */
1499                         if (pp->file) {
1500                                 semantic_error("SRC@SRC is not allowed.\n");
1501                                 return -EINVAL;
1502                         }
1503                         pp->file = strdup_esc(arg);
1504                         if (pp->file == NULL)
1505                                 return -ENOMEM;
1506                         break;
1507                 case '%':       /* Probe places */
1508                         if (strcmp(arg, "return") == 0) {
1509                                 pp->retprobe = 1;
1510                         } else {        /* Others not supported yet */
1511                                 semantic_error("%%%s is not supported.\n", arg);
1512                                 return -ENOTSUP;
1513                         }
1514                         break;
1515                 default:        /* Buggy case */
1516                         pr_err("This program has a bug at %s:%d.\n",
1517                                 __FILE__, __LINE__);
1518                         return -ENOTSUP;
1519                         break;
1520                 }
1521         }
1522 
1523         /* Exclusion check */
1524         if (pp->lazy_line && pp->line) {
1525                 semantic_error("Lazy pattern can't be used with"
1526                                " line number.\n");
1527                 return -EINVAL;
1528         }
1529 
1530         if (pp->lazy_line && pp->offset) {
1531                 semantic_error("Lazy pattern can't be used with offset.\n");
1532                 return -EINVAL;
1533         }
1534 
1535         if (pp->line && pp->offset) {
1536                 semantic_error("Offset can't be used with line number.\n");
1537                 return -EINVAL;
1538         }
1539 
1540         if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
1541                 semantic_error("File always requires line number or "
1542                                "lazy pattern.\n");
1543                 return -EINVAL;
1544         }
1545 
1546         if (pp->offset && !pp->function) {
1547                 semantic_error("Offset requires an entry function.\n");
1548                 return -EINVAL;
1549         }
1550 
1551         if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
1552                 semantic_error("Offset/Line/Lazy pattern can't be used with "
1553                                "return probe.\n");
1554                 return -EINVAL;
1555         }
1556 
1557         pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
1558                  pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
1559                  pp->lazy_line);
1560         return 0;
1561 }
1562 
1563 /* Parse perf-probe event argument */
1564 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
1565 {
1566         char *tmp, *goodname;
1567         struct perf_probe_arg_field **fieldp;
1568 
1569         pr_debug("parsing arg: %s into ", str);
1570 
1571         tmp = strchr(str, '=');
1572         if (tmp) {
1573                 arg->name = strndup(str, tmp - str);
1574                 if (arg->name == NULL)
1575                         return -ENOMEM;
1576                 pr_debug("name:%s ", arg->name);
1577                 str = tmp + 1;
1578         }
1579 
1580         tmp = strchr(str, ':');
1581         if (tmp) {      /* Type setting */
1582                 *tmp = '\0';
1583                 arg->type = strdup(tmp + 1);
1584                 if (arg->type == NULL)
1585                         return -ENOMEM;
1586                 pr_debug("type:%s ", arg->type);
1587         }
1588 
1589         tmp = strpbrk(str, "-.[");
1590         if (!is_c_varname(str) || !tmp) {
1591                 /* A variable, register, symbol or special value */
1592                 arg->var = strdup(str);
1593                 if (arg->var == NULL)
1594                         return -ENOMEM;
1595                 pr_debug("%s\n", arg->var);
1596                 return 0;
1597         }
1598 
1599         /* Structure fields or array element */
1600         arg->var = strndup(str, tmp - str);
1601         if (arg->var == NULL)
1602                 return -ENOMEM;
1603         goodname = arg->var;
1604         pr_debug("%s, ", arg->var);
1605         fieldp = &arg->field;
1606 
1607         do {
1608                 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
1609                 if (*fieldp == NULL)
1610                         return -ENOMEM;
1611                 if (*tmp == '[') {      /* Array */
1612                         str = tmp;
1613                         (*fieldp)->index = strtol(str + 1, &tmp, 0);
1614                         (*fieldp)->ref = true;
1615                         if (*tmp != ']' || tmp == str + 1) {
1616                                 semantic_error("Array index must be a"
1617                                                 " number.\n");
1618                                 return -EINVAL;
1619                         }
1620                         tmp++;
1621                         if (*tmp == '\0')
1622                                 tmp = NULL;
1623                 } else {                /* Structure */
1624                         if (*tmp == '.') {
1625                                 str = tmp + 1;
1626                                 (*fieldp)->ref = false;
1627                         } else if (tmp[1] == '>') {
1628                                 str = tmp + 2;
1629                                 (*fieldp)->ref = true;
1630                         } else {
1631                                 semantic_error("Argument parse error: %s\n",
1632                                                str);
1633                                 return -EINVAL;
1634                         }
1635                         tmp = strpbrk(str, "-.[");
1636                 }
1637                 if (tmp) {
1638                         (*fieldp)->name = strndup(str, tmp - str);
1639                         if ((*fieldp)->name == NULL)
1640                                 return -ENOMEM;
1641                         if (*str != '[')
1642                                 goodname = (*fieldp)->name;
1643                         pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
1644                         fieldp = &(*fieldp)->next;
1645                 }
1646         } while (tmp);
1647         (*fieldp)->name = strdup(str);
1648         if ((*fieldp)->name == NULL)
1649                 return -ENOMEM;
1650         if (*str != '[')
1651                 goodname = (*fieldp)->name;
1652         pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
1653 
1654         /* If no name is specified, set the last field name (not array index)*/
1655         if (!arg->name) {
1656                 arg->name = strdup(goodname);
1657                 if (arg->name == NULL)
1658                         return -ENOMEM;
1659         }
1660         return 0;
1661 }
1662 
1663 /* Parse perf-probe event command */
1664 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
1665 {
1666         char **argv;
1667         int argc, i, ret = 0;
1668 
1669         argv = argv_split(cmd, &argc);
1670         if (!argv) {
1671                 pr_debug("Failed to split arguments.\n");
1672                 return -ENOMEM;
1673         }
1674         if (argc - 1 > MAX_PROBE_ARGS) {
1675                 semantic_error("Too many probe arguments (%d).\n", argc - 1);
1676                 ret = -ERANGE;
1677                 goto out;
1678         }
1679         /* Parse probe point */
1680         ret = parse_perf_probe_point(argv[0], pev);
1681         if (ret < 0)
1682                 goto out;
1683 
1684         /* Copy arguments and ensure return probe has no C argument */
1685         pev->nargs = argc - 1;
1686         pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1687         if (pev->args == NULL) {
1688                 ret = -ENOMEM;
1689                 goto out;
1690         }
1691         for (i = 0; i < pev->nargs && ret >= 0; i++) {
1692                 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
1693                 if (ret >= 0 &&
1694                     is_c_varname(pev->args[i].var) && pev->point.retprobe) {
1695                         semantic_error("You can't specify local variable for"
1696                                        " kretprobe.\n");
1697                         ret = -EINVAL;
1698                 }
1699         }
1700 out:
1701         argv_free(argv);
1702 
1703         return ret;
1704 }
1705 
1706 /* Returns true if *any* ARG is either C variable, $params or $vars. */
1707 bool perf_probe_with_var(struct perf_probe_event *pev)
1708 {
1709         int i = 0;
1710 
1711         for (i = 0; i < pev->nargs; i++)
1712                 if (is_c_varname(pev->args[i].var)              ||
1713                     !strcmp(pev->args[i].var, PROBE_ARG_PARAMS) ||
1714                     !strcmp(pev->args[i].var, PROBE_ARG_VARS))
1715                         return true;
1716         return false;
1717 }
1718 
1719 /* Return true if this perf_probe_event requires debuginfo */
1720 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1721 {
1722         if (pev->point.file || pev->point.line || pev->point.lazy_line)
1723                 return true;
1724 
1725         if (perf_probe_with_var(pev))
1726                 return true;
1727 
1728         return false;
1729 }
1730 
1731 /* Parse probe_events event into struct probe_point */
1732 int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
1733 {
1734         struct probe_trace_point *tp = &tev->point;
1735         char pr;
1736         char *p;
1737         char *argv0_str = NULL, *fmt, *fmt1_str, *fmt2_str, *fmt3_str;
1738         int ret, i, argc;
1739         char **argv;
1740 
1741         pr_debug("Parsing probe_events: %s\n", cmd);
1742         argv = argv_split(cmd, &argc);
1743         if (!argv) {
1744                 pr_debug("Failed to split arguments.\n");
1745                 return -ENOMEM;
1746         }
1747         if (argc < 2) {
1748                 semantic_error("Too few probe arguments.\n");
1749                 ret = -ERANGE;
1750                 goto out;
1751         }
1752 
1753         /* Scan event and group name. */
1754         argv0_str = strdup(argv[0]);
1755         if (argv0_str == NULL) {
1756                 ret = -ENOMEM;
1757                 goto out;
1758         }
1759         fmt1_str = strtok_r(argv0_str, ":", &fmt);
1760         fmt2_str = strtok_r(NULL, "/", &fmt);
1761         fmt3_str = strtok_r(NULL, " \t", &fmt);
1762         if (fmt1_str == NULL || strlen(fmt1_str) != 1 || fmt2_str == NULL
1763             || fmt3_str == NULL) {
1764                 semantic_error("Failed to parse event name: %s\n", argv[0]);
1765                 ret = -EINVAL;
1766                 goto out;
1767         }
1768         pr = fmt1_str[0];
1769         tev->group = strdup(fmt2_str);
1770         tev->event = strdup(fmt3_str);
1771         if (tev->group == NULL || tev->event == NULL) {
1772                 ret = -ENOMEM;
1773                 goto out;
1774         }
1775         pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1776 
1777         tp->retprobe = (pr == 'r');
1778 
1779         /* Scan module name(if there), function name and offset */
1780         p = strchr(argv[1], ':');
1781         if (p) {
1782                 tp->module = strndup(argv[1], p - argv[1]);
1783                 if (!tp->module) {
1784                         ret = -ENOMEM;
1785                         goto out;
1786                 }
1787                 tev->uprobes = (tp->module[0] == '/');
1788                 p++;
1789         } else
1790                 p = argv[1];
1791         fmt1_str = strtok_r(p, "+", &fmt);
1792         /* only the address started with 0x */
1793         if (fmt1_str[0] == '') {
1794                 /*
1795                  * Fix a special case:
1796                  * if address == 0, kernel reports something like:
1797                  * p:probe_libc/abs_0 /lib/libc-2.18.so:0x          (null) arg1=%ax
1798                  * Newer kernel may fix that, but we want to
1799                  * support old kernel also.
1800                  */
1801                 if (strcmp(fmt1_str, "0x") == 0) {
1802                         if (!argv[2] || strcmp(argv[2], "(null)")) {
1803                                 ret = -EINVAL;
1804                                 goto out;
1805                         }
1806                         tp->address = 0;
1807 
1808                         free(argv[2]);
1809                         for (i = 2; argv[i + 1] != NULL; i++)
1810                                 argv[i] = argv[i + 1];
1811 
1812                         argv[i] = NULL;
1813                         argc -= 1;
1814                 } else
1815                         tp->address = strtoul(fmt1_str, NULL, 0);
1816         } else {
1817                 /* Only the symbol-based probe has offset */
1818                 tp->symbol = strdup(fmt1_str);
1819                 if (tp->symbol == NULL) {
1820                         ret = -ENOMEM;
1821                         goto out;
1822                 }
1823                 fmt2_str = strtok_r(NULL, "", &fmt);
1824                 if (fmt2_str == NULL)
1825                         tp->offset = 0;
1826                 else
1827                         tp->offset = strtoul(fmt2_str, NULL, 10);
1828         }
1829 
1830         if (tev->uprobes) {
1831                 fmt2_str = strchr(p, '(');
1832                 if (fmt2_str)
1833                         tp->ref_ctr_offset = strtoul(fmt2_str + 1, NULL, 0);
1834         }
1835 
1836         tev->nargs = argc - 2;
1837         tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1838         if (tev->args == NULL) {
1839                 ret = -ENOMEM;
1840                 goto out;
1841         }
1842         for (i = 0; i < tev->nargs; i++) {
1843                 p = strchr(argv[i + 2], '=');
1844                 if (p)  /* We don't need which register is assigned. */
1845                         *p++ = '\0';
1846                 else
1847                         p = argv[i + 2];
1848                 tev->args[i].name = strdup(argv[i + 2]);
1849                 /* TODO: parse regs and offset */
1850                 tev->args[i].value = strdup(p);
1851                 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
1852                         ret = -ENOMEM;
1853                         goto out;
1854                 }
1855         }
1856         ret = 0;
1857 out:
1858         free(argv0_str);
1859         argv_free(argv);
1860         return ret;
1861 }
1862 
1863 /* Compose only probe arg */
1864 char *synthesize_perf_probe_arg(struct perf_probe_arg *pa)
1865 {
1866         struct perf_probe_arg_field *field = pa->field;
1867         struct strbuf buf;
1868         char *ret = NULL;
1869         int err;
1870 
1871         if (strbuf_init(&buf, 64) < 0)
1872                 return NULL;
1873 
1874         if (pa->name && pa->var)
1875                 err = strbuf_addf(&buf, "%s=%s", pa->name, pa->var);
1876         else
1877                 err = strbuf_addstr(&buf, pa->name ?: pa->var);
1878         if (err)
1879                 goto out;
1880 
1881         while (field) {
1882                 if (field->name[0] == '[')
1883                         err = strbuf_addstr(&buf, field->name);
1884                 else
1885                         err = strbuf_addf(&buf, "%s%s", field->ref ? "->" : ".",
1886                                           field->name);
1887                 field = field->next;
1888                 if (err)
1889                         goto out;
1890         }
1891 
1892         if (pa->type)
1893                 if (strbuf_addf(&buf, ":%s", pa->type) < 0)
1894                         goto out;
1895 
1896         ret = strbuf_detach(&buf, NULL);
1897 out:
1898         strbuf_release(&buf);
1899         return ret;
1900 }
1901 
1902 /* Compose only probe point (not argument) */
1903 char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1904 {
1905         struct strbuf buf;
1906         char *tmp, *ret = NULL;
1907         int len, err = 0;
1908 
1909         if (strbuf_init(&buf, 64) < 0)
1910                 return NULL;
1911 
1912         if (pp->function) {
1913                 if (strbuf_addstr(&buf, pp->function) < 0)
1914                         goto out;
1915                 if (pp->offset)
1916                         err = strbuf_addf(&buf, "+%lu", pp->offset);
1917                 else if (pp->line)
1918                         err = strbuf_addf(&buf, ":%d", pp->line);
1919                 else if (pp->retprobe)
1920                         err = strbuf_addstr(&buf, "%return");
1921                 if (err)
1922                         goto out;
1923         }
1924         if (pp->file) {
1925                 tmp = pp->file;
1926                 len = strlen(tmp);
1927                 if (len > 30) {
1928                         tmp = strchr(pp->file + len - 30, '/');
1929                         tmp = tmp ? tmp + 1 : pp->file + len - 30;
1930                 }
1931                 err = strbuf_addf(&buf, "@%s", tmp);
1932                 if (!err && !pp->function && pp->line)
1933                         err = strbuf_addf(&buf, ":%d", pp->line);
1934         }
1935         if (!err)
1936                 ret = strbuf_detach(&buf, NULL);
1937 out:
1938         strbuf_release(&buf);
1939         return ret;
1940 }
1941 
1942 char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1943 {
1944         struct strbuf buf;
1945         char *tmp, *ret = NULL;
1946         int i;
1947 
1948         if (strbuf_init(&buf, 64))
1949                 return NULL;
1950         if (pev->event)
1951                 if (strbuf_addf(&buf, "%s:%s=", pev->group ?: PERFPROBE_GROUP,
1952                                 pev->event) < 0)
1953                         goto out;
1954 
1955         tmp = synthesize_perf_probe_point(&pev->point);
1956         if (!tmp || strbuf_addstr(&buf, tmp) < 0)
1957                 goto out;
1958         free(tmp);
1959 
1960         for (i = 0; i < pev->nargs; i++) {
1961                 tmp = synthesize_perf_probe_arg(pev->args + i);
1962                 if (!tmp || strbuf_addf(&buf, " %s", tmp) < 0)
1963                         goto out;
1964                 free(tmp);
1965         }
1966 
1967         ret = strbuf_detach(&buf, NULL);
1968 out:
1969         strbuf_release(&buf);
1970         return ret;
1971 }
1972 
1973 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1974                                             struct strbuf *buf, int depth)
1975 {
1976         int err;
1977         if (ref->next) {
1978                 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1979                                                          depth + 1);
1980                 if (depth < 0)
1981                         return depth;
1982         }
1983         err = strbuf_addf(buf, "%+ld(", ref->offset);
1984         return (err < 0) ? err : depth;
1985 }
1986 
1987 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1988                                       struct strbuf *buf)
1989 {
1990         struct probe_trace_arg_ref *ref = arg->ref;
1991         int depth = 0, err;
1992 
1993         /* Argument name or separator */
1994         if (arg->name)
1995                 err = strbuf_addf(buf, " %s=", arg->name);
1996         else
1997                 err = strbuf_addch(buf, ' ');
1998         if (err)
1999                 return err;
2000 
2001         /* Special case: @XXX */
2002         if (arg->value[0] == '@' && arg->ref)
2003                         ref = ref->next;
2004 
2005         /* Dereferencing arguments */
2006         if (ref) {
2007                 depth = __synthesize_probe_trace_arg_ref(ref, buf, 1);
2008                 if (depth < 0)
2009                         return depth;
2010         }
2011 
2012         /* Print argument value */
2013         if (arg->value[0] == '@' && arg->ref)
2014                 err = strbuf_addf(buf, "%s%+ld", arg->value, arg->ref->offset);
2015         else
2016                 err = strbuf_addstr(buf, arg->value);
2017 
2018         /* Closing */
2019         while (!err && depth--)
2020                 err = strbuf_addch(buf, ')');
2021 
2022         /* Print argument type */
2023         if (!err && arg->type)
2024                 err = strbuf_addf(buf, ":%s", arg->type);
2025 
2026         return err;
2027 }
2028 
2029 static int
2030 synthesize_uprobe_trace_def(struct probe_trace_event *tev, struct strbuf *buf)
2031 {
2032         struct probe_trace_point *tp = &tev->point;
2033         int err;
2034 
2035         err = strbuf_addf(buf, "%s:0x%lx", tp->module, tp->address);
2036 
2037         if (err >= 0 && tp->ref_ctr_offset) {
2038                 if (!uprobe_ref_ctr_is_supported())
2039                         return -1;
2040                 err = strbuf_addf(buf, "(0x%lx)", tp->ref_ctr_offset);
2041         }
2042         return err >= 0 ? 0 : -1;
2043 }
2044 
2045 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
2046 {
2047         struct probe_trace_point *tp = &tev->point;
2048         struct strbuf buf;
2049         char *ret = NULL;
2050         int i, err;
2051 
2052         /* Uprobes must have tp->module */
2053         if (tev->uprobes && !tp->module)
2054                 return NULL;
2055 
2056         if (strbuf_init(&buf, 32) < 0)
2057                 return NULL;
2058 
2059         if (strbuf_addf(&buf, "%c:%s/%s ", tp->retprobe ? 'r' : 'p',
2060                         tev->group, tev->event) < 0)
2061                 goto error;
2062         /*
2063          * If tp->address == 0, then this point must be a
2064          * absolute address uprobe.
2065          * try_to_find_absolute_address() should have made
2066          * tp->symbol to "0x0".
2067          */
2068         if (tev->uprobes && !tp->address) {
2069                 if (!tp->symbol || strcmp(tp->symbol, "0x0"))
2070                         goto error;
2071         }
2072 
2073         /* Use the tp->address for uprobes */
2074         if (tev->uprobes) {
2075                 err = synthesize_uprobe_trace_def(tev, &buf);
2076         } else if (!strncmp(tp->symbol, "0x", 2)) {
2077                 /* Absolute address. See try_to_find_absolute_address() */
2078                 err = strbuf_addf(&buf, "%s%s0x%lx", tp->module ?: "",
2079                                   tp->module ? ":" : "", tp->address);
2080         } else {
2081                 err = strbuf_addf(&buf, "%s%s%s+%lu", tp->module ?: "",
2082                                 tp->module ? ":" : "", tp->symbol, tp->offset);
2083         }
2084 
2085         if (err)
2086                 goto error;
2087 
2088         for (i = 0; i < tev->nargs; i++)
2089                 if (synthesize_probe_trace_arg(&tev->args[i], &buf) < 0)
2090                         goto error;
2091 
2092         ret = strbuf_detach(&buf, NULL);
2093 error:
2094         strbuf_release(&buf);
2095         return ret;
2096 }
2097 
2098 static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
2099                                           struct perf_probe_point *pp,
2100                                           bool is_kprobe)
2101 {
2102         struct symbol *sym = NULL;
2103         struct map *map = NULL;
2104         u64 addr = tp->address;
2105         int ret = -ENOENT;
2106 
2107         if (!is_kprobe) {
2108                 map = dso__new_map(tp->module);
2109                 if (!map)
2110                         goto out;
2111                 sym = map__find_symbol(map, addr);
2112         } else {
2113                 if (tp->symbol && !addr) {
2114                         if (kernel_get_symbol_address_by_name(tp->symbol,
2115                                                 &addr, true, false) < 0)
2116                                 goto out;
2117                 }
2118                 if (addr) {
2119                         addr += tp->offset;
2120                         sym = machine__find_kernel_symbol(host_machine, addr, &map);
2121                 }
2122         }
2123 
2124         if (!sym)
2125                 goto out;
2126 
2127         pp->retprobe = tp->retprobe;
2128         pp->offset = addr - map->unmap_ip(map, sym->start);
2129         pp->function = strdup(sym->name);
2130         ret = pp->function ? 0 : -ENOMEM;
2131 
2132 out:
2133         if (map && !is_kprobe) {
2134                 map__put(map);
2135         }
2136 
2137         return ret;
2138 }
2139 
2140 static int convert_to_perf_probe_point(struct probe_trace_point *tp,
2141                                        struct perf_probe_point *pp,
2142                                        bool is_kprobe)
2143 {
2144         char buf[128];
2145         int ret;
2146 
2147         ret = find_perf_probe_point_from_dwarf(tp, pp, is_kprobe);
2148         if (!ret)
2149                 return 0;
2150         ret = find_perf_probe_point_from_map(tp, pp, is_kprobe);
2151         if (!ret)
2152                 return 0;
2153 
2154         pr_debug("Failed to find probe point from both of dwarf and map.\n");
2155 
2156         if (tp->symbol) {
2157                 pp->function = strdup(tp->symbol);
2158                 pp->offset = tp->offset;
2159         } else {
2160                 ret = e_snprintf(buf, 128, "0x%" PRIx64, (u64)tp->address);
2161                 if (ret < 0)
2162                         return ret;
2163                 pp->function = strdup(buf);
2164                 pp->offset = 0;
2165         }
2166         if (pp->function == NULL)
2167                 return -ENOMEM;
2168 
2169         pp->retprobe = tp->retprobe;
2170 
2171         return 0;
2172 }
2173 
2174 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
2175                                struct perf_probe_event *pev, bool is_kprobe)
2176 {
2177         struct strbuf buf = STRBUF_INIT;
2178         int i, ret;
2179 
2180         /* Convert event/group name */
2181         pev->event = strdup(tev->event);
2182         pev->group = strdup(tev->group);
2183         if (pev->event == NULL || pev->group == NULL)
2184                 return -ENOMEM;
2185 
2186         /* Convert trace_point to probe_point */
2187         ret = convert_to_perf_probe_point(&tev->point, &pev->point, is_kprobe);
2188         if (ret < 0)
2189                 return ret;
2190 
2191         /* Convert trace_arg to probe_arg */
2192         pev->nargs = tev->nargs;
2193         pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
2194         if (pev->args == NULL)
2195                 return -ENOMEM;
2196         for (i = 0; i < tev->nargs && ret >= 0; i++) {
2197                 if (tev->args[i].name)
2198                         pev->args[i].name = strdup(tev->args[i].name);
2199                 else {
2200                         if ((ret = strbuf_init(&buf, 32)) < 0)
2201                                 goto error;
2202                         ret = synthesize_probe_trace_arg(&tev->args[i], &buf);
2203                         pev->args[i].name = strbuf_detach(&buf, NULL);
2204                 }
2205                 if (pev->args[i].name == NULL && ret >= 0)
2206                         ret = -ENOMEM;
2207         }
2208 error:
2209         if (ret < 0)
2210                 clear_perf_probe_event(pev);
2211 
2212         return ret;
2213 }
2214 
2215 void clear_perf_probe_event(struct perf_probe_event *pev)
2216 {
2217         struct perf_probe_arg_field *field, *next;
2218         int i;
2219 
2220         free(pev->event);
2221         free(pev->group);
2222         free(pev->target);
2223         clear_perf_probe_point(&pev->point);
2224 
2225         for (i = 0; i < pev->nargs; i++) {
2226                 free(pev->args[i].name);
2227                 free(pev->args[i].var);
2228                 free(pev->args[i].type);
2229                 field = pev->args[i].field;
2230                 while (field) {
2231                         next = field->next;
2232                         zfree(&field->name);
2233                         free(field);
2234                         field = next;
2235                 }
2236         }
2237         free(pev->args);
2238         memset(pev, 0, sizeof(*pev));
2239 }
2240 
2241 #define strdup_or_goto(str, label)      \
2242 ({ char *__p = NULL; if (str && !(__p = strdup(str))) goto label; __p; })
2243 
2244 static int perf_probe_point__copy(struct perf_probe_point *dst,
2245                                   struct perf_probe_point *src)
2246 {
2247         dst->file = strdup_or_goto(src->file, out_err);
2248         dst->function = strdup_or_goto(src->function, out_err);
2249         dst->lazy_line = strdup_or_goto(src->lazy_line, out_err);
2250         dst->line = src->line;
2251         dst->retprobe = src->retprobe;
2252         dst->offset = src->offset;
2253         return 0;
2254 
2255 out_err:
2256         clear_perf_probe_point(dst);
2257         return -ENOMEM;
2258 }
2259 
2260 static int perf_probe_arg__copy(struct perf_probe_arg *dst,
2261                                 struct perf_probe_arg *src)
2262 {
2263         struct perf_probe_arg_field *field, **ppfield;
2264 
2265         dst->name = strdup_or_goto(src->name, out_err);
2266         dst->var = strdup_or_goto(src->var, out_err);
2267         dst->type = strdup_or_goto(src->type, out_err);
2268 
2269         field = src->field;
2270         ppfield = &(dst->field);
2271         while (field) {
2272                 *ppfield = zalloc(sizeof(*field));
2273                 if (!*ppfield)
2274                         goto out_err;
2275                 (*ppfield)->name = strdup_or_goto(field->name, out_err);
2276                 (*ppfield)->index = field->index;
2277                 (*ppfield)->ref = field->ref;
2278                 field = field->next;
2279                 ppfield = &((*ppfield)->next);
2280         }
2281         return 0;
2282 out_err:
2283         return -ENOMEM;
2284 }
2285 
2286 int perf_probe_event__copy(struct perf_probe_event *dst,
2287                            struct perf_probe_event *src)
2288 {
2289         int i;
2290 
2291         dst->event = strdup_or_goto(src->event, out_err);
2292         dst->group = strdup_or_goto(src->group, out_err);
2293         dst->target = strdup_or_goto(src->target, out_err);
2294         dst->uprobes = src->uprobes;
2295 
2296         if (perf_probe_point__copy(&dst->point, &src->point) < 0)
2297                 goto out_err;
2298 
2299         dst->args = zalloc(sizeof(struct perf_probe_arg) * src->nargs);
2300         if (!dst->args)
2301                 goto out_err;
2302         dst->nargs = src->nargs;
2303 
2304         for (i = 0; i < src->nargs; i++)
2305                 if (perf_probe_arg__copy(&dst->args[i], &src->args[i]) < 0)
2306                         goto out_err;
2307         return 0;
2308 
2309 out_err:
2310         clear_perf_probe_event(dst);
2311         return -ENOMEM;
2312 }
2313 
2314 void clear_probe_trace_event(struct probe_trace_event *tev)
2315 {
2316         struct probe_trace_arg_ref *ref, *next;
2317         int i;
2318 
2319         free(tev->event);
2320         free(tev->group);
2321         free(tev->point.symbol);
2322         free(tev->point.realname);
2323         free(tev->point.module);
2324         for (i = 0; i < tev->nargs; i++) {
2325                 free(tev->args[i].name);
2326                 free(tev->args[i].value);
2327                 free(tev->args[i].type);
2328                 ref = tev->args[i].ref;
2329                 while (ref) {
2330                         next = ref->next;
2331                         free(ref);
2332                         ref = next;
2333                 }
2334         }
2335         free(tev->args);
2336         memset(tev, 0, sizeof(*tev));
2337 }
2338 
2339 struct kprobe_blacklist_node {
2340         struct list_head list;
2341         unsigned long start;
2342         unsigned long end;
2343         char *symbol;
2344 };
2345 
2346 static void kprobe_blacklist__delete(struct list_head *blacklist)
2347 {
2348         struct kprobe_blacklist_node *node;
2349 
2350         while (!list_empty(blacklist)) {
2351                 node = list_first_entry(blacklist,
2352                                         struct kprobe_blacklist_node, list);
2353                 list_del(&node->list);
2354                 free(node->symbol);
2355                 free(node);
2356         }
2357 }
2358 
2359 static int kprobe_blacklist__load(struct list_head *blacklist)
2360 {
2361         struct kprobe_blacklist_node *node;
2362         const char *__debugfs = debugfs__mountpoint();
2363         char buf[PATH_MAX], *p;
2364         FILE *fp;
2365         int ret;
2366 
2367         if (__debugfs == NULL)
2368                 return -ENOTSUP;
2369 
2370         ret = e_snprintf(buf, PATH_MAX, "%s/kprobes/blacklist", __debugfs);
2371         if (ret < 0)
2372                 return ret;
2373 
2374         fp = fopen(buf, "r");
2375         if (!fp)
2376                 return -errno;
2377 
2378         ret = 0;
2379         while (fgets(buf, PATH_MAX, fp)) {
2380                 node = zalloc(sizeof(*node));
2381                 if (!node) {
2382                         ret = -ENOMEM;
2383                         break;
2384                 }
2385                 INIT_LIST_HEAD(&node->list);
2386                 list_add_tail(&node->list, blacklist);
2387                 if (sscanf(buf, "0x%lx-0x%lx", &node->start, &node->end) != 2) {
2388                         ret = -EINVAL;
2389                         break;
2390                 }
2391                 p = strchr(buf, '\t');
2392                 if (p) {
2393                         p++;
2394                         if (p[strlen(p) - 1] == '\n')
2395                                 p[strlen(p) - 1] = '\0';
2396                 } else
2397                         p = (char *)"unknown";
2398                 node->symbol = strdup(p);
2399                 if (!node->symbol) {
2400                         ret = -ENOMEM;
2401                         break;
2402                 }
2403                 pr_debug2("Blacklist: 0x%lx-0x%lx, %s\n",
2404                           node->start, node->end, node->symbol);
2405                 ret++;
2406         }
2407         if (ret < 0)
2408                 kprobe_blacklist__delete(blacklist);
2409         fclose(fp);
2410 
2411         return ret;
2412 }
2413 
2414 static struct kprobe_blacklist_node *
2415 kprobe_blacklist__find_by_address(struct list_head *blacklist,
2416                                   unsigned long address)
2417 {
2418         struct kprobe_blacklist_node *node;
2419 
2420         list_for_each_entry(node, blacklist, list) {
2421                 if (node->start <= address && address < node->end)
2422                         return node;
2423         }
2424 
2425         return NULL;
2426 }
2427 
2428 static LIST_HEAD(kprobe_blacklist);
2429 
2430 static void kprobe_blacklist__init(void)
2431 {
2432         if (!list_empty(&kprobe_blacklist))
2433                 return;
2434 
2435         if (kprobe_blacklist__load(&kprobe_blacklist) < 0)
2436                 pr_debug("No kprobe blacklist support, ignored\n");
2437 }
2438 
2439 static void kprobe_blacklist__release(void)
2440 {
2441         kprobe_blacklist__delete(&kprobe_blacklist);
2442 }
2443 
2444 static bool kprobe_blacklist__listed(unsigned long address)
2445 {
2446         return !!kprobe_blacklist__find_by_address(&kprobe_blacklist, address);
2447 }
2448 
2449 static int perf_probe_event__sprintf(const char *group, const char *event,
2450                                      struct perf_probe_event *pev,
2451                                      const char *module,
2452                                      struct strbuf *result)
2453 {
2454         int i, ret;
2455         char *buf;
2456 
2457         if (asprintf(&buf, "%s:%s", group, event) < 0)
2458                 return -errno;
2459         ret = strbuf_addf(result, "  %-20s (on ", buf);
2460         free(buf);
2461         if (ret)
2462                 return ret;
2463 
2464         /* Synthesize only event probe point */
2465         buf = synthesize_perf_probe_point(&pev->point);
2466         if (!buf)
2467                 return -ENOMEM;
2468         ret = strbuf_addstr(result, buf);
2469         free(buf);
2470 
2471         if (!ret && module)
2472                 ret = strbuf_addf(result, " in %s", module);
2473 
2474         if (!ret && pev->nargs > 0) {
2475                 ret = strbuf_add(result, " with", 5);
2476                 for (i = 0; !ret && i < pev->nargs; i++) {
2477                         buf = synthesize_perf_probe_arg(&pev->args[i]);
2478                         if (!buf)
2479                                 return -ENOMEM;
2480                         ret = strbuf_addf(result, " %s", buf);
2481                         free(buf);
2482                 }
2483         }
2484         if (!ret)
2485                 ret = strbuf_addch(result, ')');
2486 
2487         return ret;
2488 }
2489 
2490 /* Show an event */
2491 int show_perf_probe_event(const char *group, const char *event,
2492                           struct perf_probe_event *pev,
2493                           const char *module, bool use_stdout)
2494 {
2495         struct strbuf buf = STRBUF_INIT;
2496         int ret;
2497 
2498         ret = perf_probe_event__sprintf(group, event, pev, module, &buf);
2499         if (ret >= 0) {
2500                 if (use_stdout)
2501                         printf("%s\n", buf.buf);
2502                 else
2503                         pr_info("%s\n", buf.buf);
2504         }
2505         strbuf_release(&buf);
2506 
2507         return ret;
2508 }
2509 
2510 static bool filter_probe_trace_event(struct probe_trace_event *tev,
2511                                      struct strfilter *filter)
2512 {
2513         char tmp[128];
2514 
2515         /* At first, check the event name itself */
2516         if (strfilter__compare(filter, tev->event))
2517                 return true;
2518 
2519         /* Next, check the combination of name and group */
2520         if (e_snprintf(tmp, 128, "%s:%s", tev->group, tev->event) < 0)
2521                 return false;
2522         return strfilter__compare(filter, tmp);
2523 }
2524 
2525 static int __show_perf_probe_events(int fd, bool is_kprobe,
2526                                     struct strfilter *filter)
2527 {
2528         int ret = 0;
2529         struct probe_trace_event tev;
2530         struct perf_probe_event pev;
2531         struct strlist *rawlist;
2532         struct str_node *ent;
2533 
2534         memset(&tev, 0, sizeof(tev));
2535         memset(&pev, 0, sizeof(pev));
2536 
2537         rawlist = probe_file__get_rawlist(fd);
2538         if (!rawlist)
2539                 return -ENOMEM;
2540 
2541         strlist__for_each_entry(ent, rawlist) {
2542                 ret = parse_probe_trace_command(ent->s, &tev);
2543                 if (ret >= 0) {
2544                         if (!filter_probe_trace_event(&tev, filter))
2545                                 goto next;
2546                         ret = convert_to_perf_probe_event(&tev, &pev,
2547                                                                 is_kprobe);
2548                         if (ret < 0)
2549                                 goto next;
2550                         ret = show_perf_probe_event(pev.group, pev.event,
2551                                                     &pev, tev.point.module,
2552                                                     true);
2553                 }
2554 next:
2555                 clear_perf_probe_event(&pev);
2556                 clear_probe_trace_event(&tev);
2557                 if (ret < 0)
2558                         break;
2559         }
2560         strlist__delete(rawlist);
2561         /* Cleanup cached debuginfo if needed */
2562         debuginfo_cache__exit();
2563 
2564         return ret;
2565 }
2566 
2567 /* List up current perf-probe events */
2568 int show_perf_probe_events(struct strfilter *filter)
2569 {
2570         int kp_fd, up_fd, ret;
2571 
2572         setup_pager();
2573 
2574         if (probe_conf.cache)
2575                 return probe_cache__show_all_caches(filter);
2576 
2577         ret = init_probe_symbol_maps(false);
2578         if (ret < 0)
2579                 return ret;
2580 
2581         ret = probe_file__open_both(&kp_fd, &up_fd, 0);
2582         if (ret < 0)
2583                 return ret;
2584 
2585         if (kp_fd >= 0)
2586                 ret = __show_perf_probe_events(kp_fd, true, filter);
2587         if (up_fd >= 0 && ret >= 0)
2588                 ret = __show_perf_probe_events(up_fd, false, filter);
2589         if (kp_fd > 0)
2590                 close(kp_fd);
2591         if (up_fd > 0)
2592                 close(up_fd);
2593         exit_probe_symbol_maps();
2594 
2595         return ret;
2596 }
2597 
2598 static int get_new_event_name(char *buf, size_t len, const char *base,
2599                               struct strlist *namelist, bool ret_event,
2600                               bool allow_suffix)
2601 {
2602         int i, ret;
2603         char *p, *nbase;
2604 
2605         if (*base == '.')
2606                 base++;
2607         nbase = strdup(base);
2608         if (!nbase)
2609                 return -ENOMEM;
2610 
2611         /* Cut off the dot suffixes (e.g. .const, .isra) and version suffixes */
2612         p = strpbrk(nbase, ".@");
2613         if (p && p != nbase)
2614                 *p = '\0';
2615 
2616         /* Try no suffix number */
2617         ret = e_snprintf(buf, len, "%s%s", nbase, ret_event ? "__return" : "");
2618         if (ret < 0) {
2619                 pr_debug("snprintf() failed: %d\n", ret);
2620                 goto out;
2621         }
2622         if (!strlist__has_entry(namelist, buf))
2623                 goto out;
2624 
2625         if (!allow_suffix) {
2626                 pr_warning("Error: event \"%s\" already exists.\n"
2627                            " Hint: Remove existing event by 'perf probe -d'\n"
2628                            "       or force duplicates by 'perf probe -f'\n"
2629                            "       or set 'force=yes' in BPF source.\n",
2630                            buf);
2631                 ret = -EEXIST;
2632                 goto out;
2633         }
2634 
2635         /* Try to add suffix */
2636         for (i = 1; i < MAX_EVENT_INDEX; i++) {
2637                 ret = e_snprintf(buf, len, "%s_%d", nbase, i);
2638                 if (ret < 0) {
2639                         pr_debug("snprintf() failed: %d\n", ret);
2640                         goto out;
2641                 }
2642                 if (!strlist__has_entry(namelist, buf))
2643                         break;
2644         }
2645         if (i == MAX_EVENT_INDEX) {
2646                 pr_warning("Too many events are on the same function.\n");
2647                 ret = -ERANGE;
2648         }
2649 
2650 out:
2651         free(nbase);
2652 
2653         /* Final validation */
2654         if (ret >= 0 && !is_c_func_name(buf)) {
2655                 pr_warning("Internal error: \"%s\" is an invalid event name.\n",
2656                            buf);
2657                 ret = -EINVAL;
2658         }
2659 
2660         return ret;
2661 }
2662 
2663 /* Warn if the current kernel's uprobe implementation is old */
2664 static void warn_uprobe_event_compat(struct probe_trace_event *tev)
2665 {
2666         int i;
2667         char *buf = synthesize_probe_trace_command(tev);
2668         struct probe_trace_point *tp = &tev->point;
2669 
2670         if (tp->ref_ctr_offset && !uprobe_ref_ctr_is_supported()) {
2671                 pr_warning("A semaphore is associated with %s:%s and "
2672                            "seems your kernel doesn't support it.\n",
2673                            tev->group, tev->event);
2674         }
2675 
2676         /* Old uprobe event doesn't support memory dereference */
2677         if (!tev->uprobes || tev->nargs == 0 || !buf)
2678                 goto out;
2679 
2680         for (i = 0; i < tev->nargs; i++)
2681                 if (strglobmatch(tev->args[i].value, "[$@+-]*")) {
2682                         pr_warning("Please upgrade your kernel to at least "
2683                                    "3.14 to have access to feature %s\n",
2684                                    tev->args[i].value);
2685                         break;
2686                 }
2687 out:
2688         free(buf);
2689 }
2690 
2691 /* Set new name from original perf_probe_event and namelist */
2692 static int probe_trace_event__set_name(struct probe_trace_event *tev,
2693                                        struct perf_probe_event *pev,
2694                                        struct strlist *namelist,
2695                                        bool allow_suffix)
2696 {
2697         const char *event, *group;
2698         char buf[64];
2699         int ret;
2700 
2701         /* If probe_event or trace_event already have the name, reuse it */
2702         if (pev->event && !pev->sdt)
2703                 event = pev->event;
2704         else if (tev->event)
2705                 event = tev->event;
2706         else {
2707                 /* Or generate new one from probe point */
2708                 if (pev->point.function &&
2709                         (strncmp(pev->point.function, "0x", 2) != 0) &&
2710                         !strisglob(pev->point.function))
2711                         event = pev->point.function;
2712                 else
2713                         event = tev->point.realname;
2714         }
2715         if (pev->group && !pev->sdt)
2716                 group = pev->group;
2717         else if (tev->group)
2718                 group = tev->group;
2719         else
2720                 group = PERFPROBE_GROUP;
2721 
2722         /* Get an unused new event name */
2723         ret = get_new_event_name(buf, 64, event, namelist,
2724                                  tev->point.retprobe, allow_suffix);
2725         if (ret < 0)
2726                 return ret;
2727 
2728         event = buf;
2729 
2730         tev->event = strdup(event);
2731         tev->group = strdup(group);
2732         if (tev->event == NULL || tev->group == NULL)
2733                 return -ENOMEM;
2734 
2735         /* Add added event name to namelist */
2736         strlist__add(namelist, event);
2737         return 0;
2738 }
2739 
2740 static int __open_probe_file_and_namelist(bool uprobe,
2741                                           struct strlist **namelist)
2742 {
2743         int fd;
2744 
2745         fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
2746         if (fd < 0)
2747                 return fd;
2748 
2749         /* Get current event names */
2750         *namelist = probe_file__get_namelist(fd);
2751         if (!(*namelist)) {
2752                 pr_debug("Failed to get current event list.\n");
2753                 close(fd);
2754                 return -ENOMEM;
2755         }
2756         return fd;
2757 }
2758 
2759 static int __add_probe_trace_events(struct perf_probe_event *pev,
2760                                      struct probe_trace_event *tevs,
2761                                      int ntevs, bool allow_suffix)
2762 {
2763         int i, fd[2] = {-1, -1}, up, ret;
2764         struct probe_trace_event *tev = NULL;
2765         struct probe_cache *cache = NULL;
2766         struct strlist *namelist[2] = {NULL, NULL};
2767         struct nscookie nsc;
2768 
2769         up = pev->uprobes ? 1 : 0;
2770         fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
2771         if (fd[up] < 0)
2772                 return fd[up];
2773 
2774         ret = 0;
2775         for (i = 0; i < ntevs; i++) {
2776                 tev = &tevs[i];
2777                 up = tev->uprobes ? 1 : 0;
2778                 if (fd[up] == -1) {     /* Open the kprobe/uprobe_events */
2779                         fd[up] = __open_probe_file_and_namelist(up,
2780                                                                 &namelist[up]);
2781                         if (fd[up] < 0)
2782                                 goto close_out;
2783                 }
2784                 /* Skip if the symbol is out of .text or blacklisted */
2785                 if (!tev->point.symbol && !pev->uprobes)
2786                         continue;
2787 
2788                 /* Set new name for tev (and update namelist) */
2789                 ret = probe_trace_event__set_name(tev, pev, namelist[up],
2790                                                   allow_suffix);
2791                 if (ret < 0)
2792                         break;
2793 
2794                 nsinfo__mountns_enter(pev->nsi, &nsc);
2795                 ret = probe_file__add_event(fd[up], tev);
2796                 nsinfo__mountns_exit(&nsc);
2797                 if (ret < 0)
2798                         break;
2799 
2800                 /*
2801                  * Probes after the first probe which comes from same
2802                  * user input are always allowed to add suffix, because
2803                  * there might be several addresses corresponding to
2804                  * one code line.
2805                  */
2806                 allow_suffix = true;
2807         }
2808         if (ret == -EINVAL && pev->uprobes)
2809                 warn_uprobe_event_compat(tev);
2810         if (ret == 0 && probe_conf.cache) {
2811                 cache = probe_cache__new(pev->target, pev->nsi);
2812                 if (!cache ||
2813                     probe_cache__add_entry(cache, pev, tevs, ntevs) < 0 ||
2814                     probe_cache__commit(cache) < 0)
2815                         pr_warning("Failed to add event to probe cache\n");
2816                 probe_cache__delete(cache);
2817         }
2818 
2819 close_out:
2820         for (up = 0; up < 2; up++) {
2821                 strlist__delete(namelist[up]);
2822                 if (fd[up] >= 0)
2823                         close(fd[up]);
2824         }
2825         return ret;
2826 }
2827 
2828 static int find_probe_functions(struct map *map, char *name,
2829                                 struct symbol **syms)
2830 {
2831         int found = 0;
2832         struct symbol *sym;
2833         struct rb_node *tmp;
2834         const char *norm, *ver;
2835         char *buf = NULL;
2836         bool cut_version = true;
2837 
2838         if (map__load(map) < 0)
2839                 return 0;
2840 
2841         /* If user gives a version, don't cut off the version from symbols */
2842         if (strchr(name, '@'))
2843                 cut_version = false;
2844 
2845         map__for_each_symbol(map, sym, tmp) {
2846                 norm = arch__normalize_symbol_name(sym->name);
2847                 if (!norm)
2848                         continue;
2849 
2850                 if (cut_version) {
2851                         /* We don't care about default symbol or not */
2852                         ver = strchr(norm, '@');
2853                         if (ver) {
2854                                 buf = strndup(norm, ver - norm);
2855                                 if (!buf)
2856                                         return -ENOMEM;
2857                                 norm = buf;
2858                         }
2859                 }
2860 
2861                 if (strglobmatch(norm, name)) {
2862                         found++;
2863                         if (syms && found < probe_conf.max_probes)
2864                                 syms[found - 1] = sym;
2865                 }
2866                 if (buf)
2867                         zfree(&buf);
2868         }
2869 
2870         return found;
2871 }
2872 
2873 void __weak arch__fix_tev_from_maps(struct perf_probe_event *pev __maybe_unused,
2874                                 struct probe_trace_event *tev __maybe_unused,
2875                                 struct map *map __maybe_unused,
2876                                 struct symbol *sym __maybe_unused) { }
2877 
2878 /*
2879  * Find probe function addresses from map.
2880  * Return an error or the number of found probe_trace_event
2881  */
2882 static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
2883                                             struct probe_trace_event **tevs)
2884 {
2885         struct map *map = NULL;
2886         struct ref_reloc_sym *reloc_sym = NULL;
2887         struct symbol *sym;
2888         struct symbol **syms = NULL;
2889         struct probe_trace_event *tev;
2890         struct perf_probe_point *pp = &pev->point;
2891         struct probe_trace_point *tp;
2892         int num_matched_functions;
2893         int ret, i, j, skipped = 0;
2894         char *mod_name;
2895 
2896         map = get_target_map(pev->target, pev->nsi, pev->uprobes);
2897         if (!map) {
2898                 ret = -EINVAL;
2899                 goto out;
2900         }
2901 
2902         syms = malloc(sizeof(struct symbol *) * probe_conf.max_probes);
2903         if (!syms) {
2904                 ret = -ENOMEM;
2905                 goto out;
2906         }
2907 
2908         /*
2909          * Load matched symbols: Since the different local symbols may have
2910          * same name but different addresses, this lists all the symbols.
2911          */
2912         num_matched_functions = find_probe_functions(map, pp->function, syms);
2913         if (num_matched_functions <= 0) {
2914                 pr_err("Failed to find symbol %s in %s\n", pp->function,
2915                         pev->target ? : "kernel");
2916                 ret = -ENOENT;
2917                 goto out;
2918         } else if (num_matched_functions > probe_conf.max_probes) {
2919                 pr_err("Too many functions matched in %s\n",
2920                         pev->target ? : "kernel");
2921                 ret = -E2BIG;
2922                 goto out;
2923         }
2924 
2925         /* Note that the symbols in the kmodule are not relocated */
2926         if (!pev->uprobes && !pev->target &&
2927                         (!pp->retprobe || kretprobe_offset_is_supported())) {
2928                 reloc_sym = kernel_get_ref_reloc_sym();
2929                 if (!reloc_sym) {
2930                         pr_warning("Relocated base symbol is not found!\n");
2931                         ret = -EINVAL;
2932                         goto out;
2933                 }
2934         }
2935 
2936         /* Setup result trace-probe-events */
2937         *tevs = zalloc(sizeof(*tev) * num_matched_functions);
2938         if (!*tevs) {
2939                 ret = -ENOMEM;
2940                 goto out;
2941         }
2942 
2943         ret = 0;
2944 
2945         for (j = 0; j < num_matched_functions; j++) {
2946                 sym = syms[j];
2947 
2948                 tev = (*tevs) + ret;
2949                 tp = &tev->point;
2950                 if (ret == num_matched_functions) {
2951                         pr_warning("Too many symbols are listed. Skip it.\n");
2952                         break;
2953                 }
2954                 ret++;
2955 
2956                 if (pp->offset > sym->end - sym->start) {
2957                         pr_warning("Offset %ld is bigger than the size of %s\n",
2958                                    pp->offset, sym->name);
2959                         ret = -ENOENT;
2960                         goto err_out;
2961                 }
2962                 /* Add one probe point */
2963                 tp->address = map->unmap_ip(map, sym->start) + pp->offset;
2964 
2965                 /* Check the kprobe (not in module) is within .text  */
2966                 if (!pev->uprobes && !pev->target &&
2967                     kprobe_warn_out_range(sym->name, tp->address)) {
2968                         tp->symbol = NULL;      /* Skip it */
2969                         skipped++;
2970                 } else if (reloc_sym) {
2971                         tp->symbol = strdup_or_goto(reloc_sym->name, nomem_out);
2972                         tp->offset = tp->address - reloc_sym->addr;
2973                 } else {
2974                         tp->symbol = strdup_or_goto(sym->name, nomem_out);
2975                         tp->offset = pp->offset;
2976                 }
2977                 tp->realname = strdup_or_goto(sym->name, nomem_out);
2978 
2979                 tp->retprobe = pp->retprobe;
2980                 if (pev->target) {
2981                         if (pev->uprobes) {
2982                                 tev->point.module = strdup_or_goto(pev->target,
2983                                                                    nomem_out);
2984                         } else {
2985                                 mod_name = find_module_name(pev->target);
2986                                 tev->point.module =
2987                                         strdup(mod_name ? mod_name : pev->target);
2988                                 free(mod_name);
2989                                 if (!tev->point.module)
2990                                         goto nomem_out;
2991                         }
2992                 }
2993                 tev->uprobes = pev->uprobes;
2994                 tev->nargs = pev->nargs;
2995                 if (tev->nargs) {
2996                         tev->args = zalloc(sizeof(struct probe_trace_arg) *
2997                                            tev->nargs);
2998                         if (tev->args == NULL)
2999                                 goto nomem_out;
3000                 }
3001                 for (i = 0; i < tev->nargs; i++) {
3002                         if (pev->args[i].name)
3003                                 tev->args[i].name =
3004                                         strdup_or_goto(pev->args[i].name,
3005                                                         nomem_out);
3006 
3007                         tev->args[i].value = strdup_or_goto(pev->args[i].var,
3008                                                             nomem_out);
3009                         if (pev->args[i].type)
3010                                 tev->args[i].type =
3011                                         strdup_or_goto(pev->args[i].type,
3012                                                         nomem_out);
3013                 }
3014                 arch__fix_tev_from_maps(pev, tev, map, sym);
3015         }
3016         if (ret == skipped) {
3017                 ret = -ENOENT;
3018                 goto err_out;
3019         }
3020 
3021 out:
3022         map__put(map);
3023         free(syms);
3024         return ret;
3025 
3026 nomem_out:
3027         ret = -ENOMEM;
3028 err_out:
3029         clear_probe_trace_events(*tevs, num_matched_functions);
3030         zfree(tevs);
3031         goto out;
3032 }
3033 
3034 static int try_to_find_absolute_address(struct perf_probe_event *pev,
3035                                         struct probe_trace_event **tevs)
3036 {
3037         struct perf_probe_point *pp = &pev->point;
3038         struct probe_trace_event *tev;
3039         struct probe_trace_point *tp;
3040         int i, err;
3041 
3042         if (!(pev->point.function && !strncmp(pev->point.function, "0x", 2)))
3043                 return -EINVAL;
3044         if (perf_probe_event_need_dwarf(pev))
3045                 return -EINVAL;
3046 
3047         /*
3048          * This is 'perf probe /lib/libc.so 0xabcd'. Try to probe at
3049          * absolute address.
3050          *
3051          * Only one tev can be generated by this.
3052          */
3053         *tevs = zalloc(sizeof(*tev));
3054         if (!*tevs)
3055                 return -ENOMEM;
3056 
3057         tev = *tevs;
3058         tp = &tev->point;
3059 
3060         /*
3061          * Don't use tp->offset, use address directly, because
3062          * in synthesize_probe_trace_command() address cannot be
3063          * zero.
3064          */
3065         tp->address = pev->point.abs_address;
3066         tp->retprobe = pp->retprobe;
3067         tev->uprobes = pev->uprobes;
3068 
3069         err = -ENOMEM;
3070         /*
3071          * Give it a '0x' leading symbol name.
3072          * In __add_probe_trace_events, a NULL symbol is interpreted as
3073          * invalid.
3074          */
3075         if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
3076                 goto errout;
3077 
3078         /* For kprobe, check range */
3079         if ((!tev->uprobes) &&
3080             (kprobe_warn_out_range(tev->point.symbol,
3081                                    tev->point.address))) {
3082                 err = -EACCES;
3083                 goto errout;
3084         }
3085 
3086         if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
3087                 goto errout;
3088 
3089         if (pev->target) {
3090                 tp->module = strdup(pev->target);
3091                 if (!tp->module)
3092                         goto errout;
3093         }
3094 
3095         if (tev->group) {
3096                 tev->group = strdup(pev->group);
3097                 if (!tev->group)
3098                         goto errout;
3099         }
3100 
3101         if (pev->event) {
3102                 tev->event = strdup(pev->event);
3103                 if (!tev->event)
3104                         goto errout;
3105         }
3106 
3107         tev->nargs = pev->nargs;
3108         tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
3109         if (!tev->args)
3110                 goto errout;
3111 
3112         for (i = 0; i < tev->nargs; i++)
3113                 copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
3114 
3115         return 1;
3116 
3117 errout:
3118         clear_probe_trace_events(*tevs, 1);
3119         *tevs = NULL;
3120         return err;
3121 }
3122 
3123 /* Concatinate two arrays */
3124 static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
3125 {
3126         void *ret;
3127 
3128         ret = malloc(sz_a + sz_b);
3129         if (ret) {
3130                 memcpy(ret, a, sz_a);
3131                 memcpy(ret + sz_a, b, sz_b);
3132         }
3133         return ret;
3134 }
3135 
3136 static int
3137 concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
3138                           struct probe_trace_event **tevs2, int ntevs2)
3139 {
3140         struct probe_trace_event *new_tevs;
3141         int ret = 0;
3142 
3143         if (*ntevs == 0) {
3144                 *tevs = *tevs2;
3145                 *ntevs = ntevs2;
3146                 *tevs2 = NULL;
3147                 return 0;
3148         }
3149 
3150         if (*ntevs + ntevs2 > probe_conf.max_probes)
3151                 ret = -E2BIG;
3152         else {
3153                 /* Concatinate the array of probe_trace_event */
3154                 new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
3155                                   *tevs2, ntevs2 * sizeof(**tevs2));
3156                 if (!new_tevs)
3157                         ret = -ENOMEM;
3158                 else {
3159                         free(*tevs);
3160                         *tevs = new_tevs;
3161                         *ntevs += ntevs2;
3162                 }
3163         }
3164         if (ret < 0)
3165                 clear_probe_trace_events(*tevs2, ntevs2);
3166         zfree(tevs2);
3167 
3168         return ret;
3169 }
3170 
3171 /*
3172  * Try to find probe_trace_event from given probe caches. Return the number
3173  * of cached events found, if an error occurs return the error.
3174  */
3175 static int find_cached_events(struct perf_probe_event *pev,
3176                               struct probe_trace_event **tevs,
3177                               const char *target)
3178 {
3179         struct probe_cache *cache;
3180         struct probe_cache_entry *entry;
3181         struct probe_trace_event *tmp_tevs = NULL;
3182         int ntevs = 0;
3183         int ret = 0;
3184 
3185         cache = probe_cache__new(target, pev->nsi);
3186         /* Return 0 ("not found") if the target has no probe cache. */
3187         if (!cache)
3188                 return 0;
3189 
3190         for_each_probe_cache_entry(entry, cache) {
3191                 /* Skip the cache entry which has no name */
3192                 if (!entry->pev.event || !entry->pev.group)
3193                         continue;
3194                 if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
3195                     strglobmatch(entry->pev.event, pev->event)) {
3196                         ret = probe_cache_entry__get_event(entry, &tmp_tevs);
3197                         if (ret > 0)
3198                                 ret = concat_probe_trace_events(tevs, &ntevs,
3199                                                                 &tmp_tevs, ret);
3200                         if (ret < 0)
3201                                 break;
3202                 }
3203         }
3204         probe_cache__delete(cache);
3205         if (ret < 0) {
3206                 clear_probe_trace_events(*tevs, ntevs);
3207                 zfree(tevs);
3208         } else {
3209                 ret = ntevs;
3210                 if (ntevs > 0 && target && target[0] == '/')
3211                         pev->uprobes = true;
3212         }
3213 
3214         return ret;
3215 }
3216 
3217 /* Try to find probe_trace_event from all probe caches */
3218 static int find_cached_events_all(struct perf_probe_event *pev,
3219                                    struct probe_trace_event **tevs)
3220 {
3221         struct probe_trace_event *tmp_tevs = NULL;
3222         struct strlist *bidlist;
3223         struct str_node *nd;
3224         char *pathname;
3225         int ntevs = 0;
3226         int ret;
3227 
3228         /* Get the buildid list of all valid caches */
3229         bidlist = build_id_cache__list_all(true);
3230         if (!bidlist) {
3231                 ret = -errno;
3232                 pr_debug("Failed to get buildids: %d\n", ret);
3233                 return ret;
3234         }
3235 
3236         ret = 0;
3237         strlist__for_each_entry(nd, bidlist) {
3238                 pathname = build_id_cache__origname(nd->s);
3239                 ret = find_cached_events(pev, &tmp_tevs, pathname);
3240                 /* In the case of cnt == 0, we just skip it */
3241                 if (ret > 0)
3242                         ret = concat_probe_trace_events(tevs, &ntevs,
3243                                                         &tmp_tevs, ret);
3244                 free(pathname);
3245                 if (ret < 0)
3246                         break;
3247         }
3248         strlist__delete(bidlist);
3249 
3250         if (ret < 0) {
3251                 clear_probe_trace_events(*tevs, ntevs);
3252                 zfree(tevs);
3253         } else
3254                 ret = ntevs;
3255 
3256         return ret;
3257 }
3258 
3259 static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
3260                                               struct probe_trace_event **tevs)
3261 {
3262         struct probe_cache *cache;
3263         struct probe_cache_entry *entry;
3264         struct probe_trace_event *tev;
3265         struct str_node *node;
3266         int ret, i;
3267 
3268         if (pev->sdt) {
3269                 /* For SDT/cached events, we use special search functions */
3270                 if (!pev->target)
3271                         return find_cached_events_all(pev, tevs);
3272                 else
3273                         return find_cached_events(pev, tevs, pev->target);
3274         }
3275         cache = probe_cache__new(pev->target, pev->nsi);
3276         if (!cache)
3277                 return 0;
3278 
3279         entry = probe_cache__find(cache, pev);
3280         if (!entry) {
3281                 /* SDT must be in the cache */
3282                 ret = pev->sdt ? -ENOENT : 0;
3283                 goto out;
3284         }
3285 
3286         ret = strlist__nr_entries(entry->tevlist);
3287         if (ret > probe_conf.max_probes) {
3288                 pr_debug("Too many entries matched in the cache of %s\n",
3289                          pev->target ? : "kernel");
3290                 ret = -E2BIG;
3291                 goto out;
3292         }
3293 
3294         *tevs = zalloc(ret * sizeof(*tev));
3295         if (!*tevs) {
3296                 ret = -ENOMEM;
3297                 goto out;
3298         }
3299 
3300         i = 0;
3301         strlist__for_each_entry(node, entry->tevlist) {
3302                 tev = &(*tevs)[i++];
3303                 ret = parse_probe_trace_command(node->s, tev);
3304                 if (ret < 0)
3305                         goto out;
3306                 /* Set the uprobes attribute as same as original */
3307                 tev->uprobes = pev->uprobes;
3308         }
3309         ret = i;
3310 
3311 out:
3312         probe_cache__delete(cache);
3313         return ret;
3314 }
3315 
3316 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
3317                                          struct probe_trace_event **tevs)
3318 {
3319         int ret;
3320 
3321         if (!pev->group && !pev->sdt) {
3322                 /* Set group name if not given */
3323                 if (!pev->uprobes) {
3324                         pev->group = strdup(PERFPROBE_GROUP);
3325                         ret = pev->group ? 0 : -ENOMEM;
3326                 } else
3327                         ret = convert_exec_to_group(pev->target, &pev->group);
3328                 if (ret != 0) {
3329                         pr_warning("Failed to make a group name.\n");
3330                         return ret;
3331                 }
3332         }
3333 
3334         ret = try_to_find_absolute_address(pev, tevs);
3335         if (ret > 0)
3336                 return ret;
3337 
3338         /* At first, we need to lookup cache entry */
3339         ret = find_probe_trace_events_from_cache(pev, tevs);
3340         if (ret > 0 || pev->sdt)        /* SDT can be found only in the cache */
3341                 return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
3342 
3343         /* Convert perf_probe_event with debuginfo */
3344         ret = try_to_find_probe_trace_events(pev, tevs);
3345         if (ret != 0)
3346                 return ret;     /* Found in debuginfo or got an error */
3347 
3348         return find_probe_trace_events_from_map(pev, tevs);
3349 }
3350 
3351 int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3352 {
3353         int i, ret;
3354 
3355         /* Loop 1: convert all events */
3356         for (i = 0; i < npevs; i++) {
3357                 /* Init kprobe blacklist if needed */
3358                 if (!pevs[i].uprobes)
3359                         kprobe_blacklist__init();
3360                 /* Convert with or without debuginfo */
3361                 ret  = convert_to_probe_trace_events(&pevs[i], &pevs[i].tevs);
3362                 if (ret < 0)
3363                         return ret;
3364                 pevs[i].ntevs = ret;
3365         }
3366         /* This just release blacklist only if allocated */
3367         kprobe_blacklist__release();
3368 
3369         return 0;
3370 }
3371 
3372 static int show_probe_trace_event(struct probe_trace_event *tev)
3373 {
3374         char *buf = synthesize_probe_trace_command(tev);
3375 
3376         if (!buf) {
3377                 pr_debug("Failed to synthesize probe trace event.\n");
3378                 return -EINVAL;
3379         }
3380 
3381         /* Showing definition always go stdout */
3382         printf("%s\n", buf);
3383         free(buf);
3384 
3385         return 0;
3386 }
3387 
3388 int show_probe_trace_events(struct perf_probe_event *pevs, int npevs)
3389 {
3390         struct strlist *namelist = strlist__new(NULL, NULL);
3391         struct probe_trace_event *tev;
3392         struct perf_probe_event *pev;
3393         int i, j, ret = 0;
3394 
3395         if (!namelist)
3396                 return -ENOMEM;
3397 
3398         for (j = 0; j < npevs && !ret; j++) {
3399                 pev = &pevs[j];
3400                 for (i = 0; i < pev->ntevs && !ret; i++) {
3401                         tev = &pev->tevs[i];
3402                         /* Skip if the symbol is out of .text or blacklisted */
3403                         if (!tev->point.symbol && !pev->uprobes)
3404                                 continue;
3405 
3406                         /* Set new name for tev (and update namelist) */
3407                         ret = probe_trace_event__set_name(tev, pev,
3408                                                           namelist, true);
3409                         if (!ret)
3410                                 ret = show_probe_trace_event(tev);
3411                 }
3412         }
3413         strlist__delete(namelist);
3414 
3415         return ret;
3416 }
3417 
3418 int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3419 {
3420         int i, ret = 0;
3421 
3422         /* Loop 2: add all events */
3423         for (i = 0; i < npevs; i++) {
3424                 ret = __add_probe_trace_events(&pevs[i], pevs[i].tevs,
3425                                                pevs[i].ntevs,
3426                                                probe_conf.force_add);
3427                 if (ret < 0)
3428                         break;
3429         }
3430         return ret;
3431 }
3432 
3433 void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3434 {
3435         int i, j;
3436         struct perf_probe_event *pev;
3437 
3438         /* Loop 3: cleanup and free trace events  */
3439         for (i = 0; i < npevs; i++) {
3440                 pev = &pevs[i];
3441                 for (j = 0; j < pevs[i].ntevs; j++)
3442                         clear_probe_trace_event(&pevs[i].tevs[j]);
3443                 zfree(&pevs[i].tevs);
3444                 pevs[i].ntevs = 0;
3445                 nsinfo__zput(pev->nsi);
3446                 clear_perf_probe_event(&pevs[i]);
3447         }
3448 }
3449 
3450 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs)
3451 {
3452         int ret;
3453 
3454         ret = init_probe_symbol_maps(pevs->uprobes);
3455         if (ret < 0)
3456                 return ret;
3457 
3458         ret = convert_perf_probe_events(pevs, npevs);
3459         if (ret == 0)
3460                 ret = apply_perf_probe_events(pevs, npevs);
3461 
3462         cleanup_perf_probe_events(pevs, npevs);
3463 
3464         exit_probe_symbol_maps();
3465         return ret;
3466 }
3467 
3468 int del_perf_probe_events(struct strfilter *filter)
3469 {
3470         int ret, ret2, ufd = -1, kfd = -1;
3471         char *str = strfilter__string(filter);
3472 
3473         if (!str)
3474                 return -EINVAL;
3475 
3476         /* Get current event names */
3477         ret = probe_file__open_both(&kfd, &ufd, PF_FL_RW);
3478         if (ret < 0)
3479                 goto out;
3480 
3481         ret = probe_file__del_events(kfd, filter);
3482         if (ret < 0 && ret != -ENOENT)
3483                 goto error;
3484 
3485         ret2 = probe_file__del_events(ufd, filter);
3486         if (ret2 < 0 && ret2 != -ENOENT) {
3487                 ret = ret2;
3488                 goto error;
3489         }
3490         ret = 0;
3491 
3492 error:
3493         if (kfd >= 0)
3494                 close(kfd);
3495         if (ufd >= 0)
3496                 close(ufd);
3497 out:
3498         free(str);
3499 
3500         return ret;
3501 }
3502 
3503 int show_available_funcs(const char *target, struct nsinfo *nsi,
3504                          struct strfilter *_filter, bool user)
3505 {
3506         struct rb_node *nd;
3507         struct map *map;
3508         int ret;
3509 
3510         ret = init_probe_symbol_maps(user);
3511         if (ret < 0)
3512                 return ret;
3513 
3514         /* Get a symbol map */
3515         map = get_target_map(target, nsi, user);
3516         if (!map) {
3517                 pr_err("Failed to get a map for %s\n", (target) ? : "kernel");
3518                 return -EINVAL;
3519         }
3520 
3521         ret = map__load(map);
3522         if (ret) {
3523                 if (ret == -2) {
3524                         char *str = strfilter__string(_filter);
3525                         pr_err("Failed to find symbols matched to \"%s\"\n",
3526                                str);
3527                         free(str);
3528                 } else
3529                         pr_err("Failed to load symbols in %s\n",
3530                                (target) ? : "kernel");
3531                 goto end;
3532         }
3533         if (!dso__sorted_by_name(map->dso))
3534                 dso__sort_by_name(map->dso);
3535 
3536         /* Show all (filtered) symbols */
3537         setup_pager();
3538 
3539         for (nd = rb_first_cached(&map->dso->symbol_names); nd;
3540              nd = rb_next(nd)) {
3541                 struct symbol_name_rb_node *pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
3542 
3543                 if (strfilter__compare(_filter, pos->sym.name))
3544                         printf("%s\n", pos->sym.name);
3545         }
3546 end:
3547         map__put(map);
3548         exit_probe_symbol_maps();
3549 
3550         return ret;
3551 }
3552 
3553 int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
3554                             struct perf_probe_arg *pvar)
3555 {
3556         tvar->value = strdup(pvar->var);
3557         if (tvar->value == NULL)
3558                 return -ENOMEM;
3559         if (pvar->type) {
3560                 tvar->type = strdup(pvar->type);
3561                 if (tvar->type == NULL)
3562                         return -ENOMEM;
3563         }
3564         if (pvar->name) {
3565                 tvar->name = strdup(pvar->name);
3566                 if (tvar->name == NULL)
3567                         return -ENOMEM;
3568         } else
3569                 tvar->name = NULL;
3570         return 0;
3571 }
3572 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp