Lines Matching +full:g +full:- +full:link

1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
25 /* libbpf's USDT support consists of BPF-side state/code and user-space
26 * state/code working together in concert. BPF-side parts are defined in
27 * usdt.bpf.h header library. User-space state is encapsulated by struct
31 * and IP-to-spec-ID map, which is auxiliary map necessary for kernels that
39 * USDT-related until the very first call to bpf_program__attach_usdt(), which
43 * store it in bpf_object. USDT manager is per-BPF object construct, as each
45 * the expected USDT-related state. There is no coordination between two
47 * existence and libbpf is just oblivious, dealing with bpf_object-specific
52 * From user-space application's point of view, USDT is essentially just
54 * is being traced by some external entity (e.g, BPF-based tool). Here's how
57 * #include <sys/sdt.h> // provided by systemtap-sdt-devel package
62 * USDT is identified by it's <provider-name>:<probe-name> pair of names. Each
70 * `readelf -n <binary>`:
76 …* Arguments: -4@-1204(%rbp) -4@%edi -8@-1216(%rbp) -8@%r8 -4@$5 -8@%r9 8@%rdx 8@%r10 -4@$-9 -2@%…
84 * Semaphore above is and optional feature. It records an address of a 2-byte
90 * Recent enough kernel has built-in support for automatically managing this
99 * The part after @ sign is assembly-like definition of argument location
103 * 1) immediate constant, see 5th and 9th args above (-4@$5 and -4@-9);
104 * 2) register value, e.g., 8@%rdx, which means "unsigned 8-byte integer
106 * 3) memory dereference addressed by register, e.g., -4@-1204(%rbp), which
107 * specifies signed 32-bit integer stored at offset -1204 bytes from
113 * prepares `struct usdt_spec` (USDT spec), which is then provided to BPF-side
115 * actual value at runtime using a simple BPF-side code.
129 * macro invocations can end up being inlined many-many times, depending on
145 * about. This state has to be maintained per-BPF object and coordinate
152 * support BPF cookie, through IP-to-spec-ID map that libbpf maintains in such
156 * calculate absolute IP addresses for IP-to-spec-ID map, and thus such mode
162 * user-provided value that can be associated with USDT attachment. Note that
176 * on-the-fly deduplication during a single USDT attachment to only allocate
227 /* USDT args specification string, e.g.:
228 * "-4@%esi -4@-24(%rbp) -4@%ecx 2@%ax 8@%rdx"
267 return ERR_PTR(-ESRCH); in usdt_manager_new()
272 return ERR_PTR(-ENOMEM); in usdt_manager_new()
274 man->specs_map = specs_map; in usdt_manager_new()
275 man->ip_to_spec_id_map = ip_to_spec_id_map; in usdt_manager_new()
278 * We don't need IP-to-ID mapping if we can use BPF cookies. in usdt_manager_new()
281 man->has_bpf_cookie = kernel_supports(obj, FEAT_BPF_COOKIE); in usdt_manager_new()
285 * Added in: a6ca88b241d5 ("trace_uprobe: support reference counter in fd-based uprobe") in usdt_manager_new()
287 man->has_sema_refcnt = faccessat(AT_FDCWD, ref_ctr_sysfs_path, F_OK, AT_EACCESS) == 0; in usdt_manager_new()
290 * Detect kernel support for uprobe multi link to be used for attaching in usdt_manager_new()
293 man->has_uprobe_multi = kernel_supports(obj, FEAT_UPROBE_MULTI_LINK); in usdt_manager_new()
302 free(man->free_spec_ids); in usdt_manager_free()
313 return -EBADF; in sanity_check_usdt_elf()
319 pr_warn("usdt: attaching to 64-bit ELF binary '%s' is not supported\n", path); in sanity_check_usdt_elf()
320 return -EBADF; in sanity_check_usdt_elf()
325 pr_warn("usdt: attaching to 32-bit ELF binary '%s' is not supported\n", path); in sanity_check_usdt_elf()
326 return -EBADF; in sanity_check_usdt_elf()
331 return -EBADF; in sanity_check_usdt_elf()
335 return -EINVAL; in sanity_check_usdt_elf()
340 return -EBADF; in sanity_check_usdt_elf()
352 return -EBADF; in sanity_check_usdt_elf()
364 return -EINVAL; in find_elf_sec_by_name()
368 return -EINVAL; in find_elf_sec_by_name()
374 return -EINVAL; in find_elf_sec_by_name()
376 name = elf_strptr(elf, shstrndx, shdr->sh_name); in find_elf_sec_by_name()
383 return -ENOENT; in find_elf_sec_by_name()
398 return a->start < b->start ? -1 : 1; in cmp_elf_segs()
412 err = -errno; in parse_elf_segs()
418 err = -errno; in parse_elf_segs()
430 return -ENOMEM; in parse_elf_segs()
436 seg->start = phdr.p_vaddr; in parse_elf_segs()
437 seg->end = phdr.p_vaddr + phdr.p_memsz; in parse_elf_segs()
438 seg->offset = phdr.p_offset; in parse_elf_segs()
439 seg->is_exec = phdr.p_flags & PF_X; in parse_elf_segs()
444 return -ESRCH; in parse_elf_segs()
470 lib_path, errstr(-errno)); in parse_vma_segs()
478 err = -errno; in parse_vma_segs()
486 * 7f5c6f5d1000-7f5c6f5d3000 rw-p 001c7000 08:04 21238613 /usr/lib64/libc-2.17.so in parse_vma_segs()
487 * 7f5c6f5d3000-7f5c6f5d8000 rw-p 00000000 00:00 0 in parse_vma_segs()
488 …* 7f5c6f5d8000-7f5c6f5d9000 r-xp 00000000 103:01 362990598 /data/users/andriin/linux/tools/bpf/… in parse_vma_segs()
490 while (fscanf(f, "%zx-%zx %s %zx %*s %*d%[^\n]\n", in parse_vma_segs()
504 pr_debug("usdt: discovered segment for lib '%s': addrs %zx-%zx mode %s offset %zx\n", in parse_vma_segs()
507 /* ignore non-executable sections for shared libs */ in parse_vma_segs()
513 err = -ENOMEM; in parse_vma_segs()
521 seg->start = seg_start; in parse_vma_segs()
522 seg->end = seg_end; in parse_vma_segs()
523 seg->offset = seg_off; in parse_vma_segs()
524 seg->is_exec = true; in parse_vma_segs()
530 err = -ESRCH; in parse_vma_segs()
551 if (seg->start <= virtaddr && virtaddr < seg->end) in find_elf_seg()
564 * offset-based range of [offset_start, offset_end) in find_vma_seg()
567 if (seg->offset <= offset && offset < seg->offset + (seg->end - seg->start)) in find_vma_seg()
605 return -EINVAL; in collect_usdt_targets()
629 err = parse_usdt_note(elf, path, &nhdr, data->d_buf, name_off, desc_off, &note); in collect_usdt_targets()
639 * Each SDT probe also expands into a non-allocated ELF note. You can in collect_usdt_targets()
641 * see below for details. Because the note is non-allocated, it means in collect_usdt_targets()
648 * will only ever have one of these sections in a final link and it in collect_usdt_targets()
653 * Each probe note records the link-time address of the .stapsdt.base in collect_usdt_targets()
665 usdt_abs_ip += base_addr - note.base_addr; in collect_usdt_targets()
674 err = -ESRCH; in collect_usdt_targets()
679 if (!seg->is_exec) { in collect_usdt_targets()
680 err = -ESRCH; in collect_usdt_targets()
682 path, seg->start, seg->end, usdt_provider, usdt_name, in collect_usdt_targets()
687 usdt_rel_ip = usdt_abs_ip - seg->start + seg->offset; in collect_usdt_targets()
689 if (ehdr.e_type == ET_DYN && !man->has_bpf_cookie) { in collect_usdt_targets()
705 err = -ENOTSUP; in collect_usdt_targets()
721 err = -ESRCH; in collect_usdt_targets()
727 usdt_abs_ip = seg->start - seg->offset + usdt_rel_ip; in collect_usdt_targets()
733 seg ? seg->start : 0, seg ? seg->end : 0, seg ? seg->offset : 0); in collect_usdt_targets()
737 if (!man->has_sema_refcnt) { in collect_usdt_targets()
740 err = -ENOTSUP; in collect_usdt_targets()
746 err = -ESRCH; in collect_usdt_targets()
751 if (seg->is_exec) { in collect_usdt_targets()
752 err = -ESRCH; in collect_usdt_targets()
754 path, seg->start, seg->end, usdt_provider, usdt_name, in collect_usdt_targets()
759 usdt_sema_off = note.sema_addr - seg->start + seg->offset; in collect_usdt_targets()
764 seg->start, seg->end, seg->offset); in collect_usdt_targets()
770 err = -ENOMEM; in collect_usdt_targets()
778 target->abs_ip = usdt_abs_ip; in collect_usdt_targets()
779 target->rel_ip = usdt_rel_ip; in collect_usdt_targets()
780 target->sema_off = usdt_sema_off; in collect_usdt_targets()
785 target->spec_str = note.args; in collect_usdt_targets()
787 err = parse_usdt_spec(&target->spec, &note, usdt_cookie); in collect_usdt_targets()
807 struct bpf_link link; member
817 struct bpf_link *link; member
823 static int bpf_link_usdt_detach(struct bpf_link *link) in bpf_link_usdt_detach() argument
825 struct bpf_link_usdt *usdt_link = container_of(link, struct bpf_link_usdt, link); in bpf_link_usdt_detach()
826 struct usdt_manager *man = usdt_link->usdt_man; in bpf_link_usdt_detach()
829 bpf_link__destroy(usdt_link->multi_link); in bpf_link_usdt_detach()
832 for (i = 0; i < usdt_link->uprobe_cnt; i++) { in bpf_link_usdt_detach()
833 /* detach underlying uprobe link */ in bpf_link_usdt_detach()
834 bpf_link__destroy(usdt_link->uprobes[i].link); in bpf_link_usdt_detach()
841 if (!man->has_bpf_cookie) { in bpf_link_usdt_detach()
843 (void)bpf_map_delete_elem(bpf_map__fd(man->ip_to_spec_id_map), in bpf_link_usdt_detach()
844 &usdt_link->uprobes[i].abs_ip); in bpf_link_usdt_detach()
851 if (!man->free_spec_ids) { in bpf_link_usdt_detach()
853 man->free_spec_ids = usdt_link->spec_ids; in bpf_link_usdt_detach()
854 man->free_spec_cnt = usdt_link->spec_cnt; in bpf_link_usdt_detach()
855 usdt_link->spec_ids = NULL; in bpf_link_usdt_detach()
858 size_t new_cnt = man->free_spec_cnt + usdt_link->spec_cnt; in bpf_link_usdt_detach()
861 new_free_ids = libbpf_reallocarray(man->free_spec_ids, new_cnt, in bpf_link_usdt_detach()
873 memcpy(new_free_ids + man->free_spec_cnt, usdt_link->spec_ids, in bpf_link_usdt_detach()
874 usdt_link->spec_cnt * sizeof(*usdt_link->spec_ids)); in bpf_link_usdt_detach()
875 man->free_spec_ids = new_free_ids; in bpf_link_usdt_detach()
876 man->free_spec_cnt = new_cnt; in bpf_link_usdt_detach()
883 static void bpf_link_usdt_dealloc(struct bpf_link *link) in bpf_link_usdt_dealloc() argument
885 struct bpf_link_usdt *usdt_link = container_of(link, struct bpf_link_usdt, link); in bpf_link_usdt_dealloc()
887 free(usdt_link->spec_ids); in bpf_link_usdt_dealloc()
888 free(usdt_link->uprobes); in bpf_link_usdt_dealloc()
903 struct bpf_link_usdt *link, struct usdt_target *target, in allocate_spec_id() argument
911 if (hashmap__find(specs_hash, target->spec_str, &tmp)) { in allocate_spec_id()
918 * returned back to usdt_manager when USDT link is detached in allocate_spec_id()
920 new_ids = libbpf_reallocarray(link->spec_ids, link->spec_cnt + 1, sizeof(*link->spec_ids)); in allocate_spec_id()
922 return -ENOMEM; in allocate_spec_id()
923 link->spec_ids = new_ids; in allocate_spec_id()
926 if (man->free_spec_cnt) { in allocate_spec_id()
927 *spec_id = man->free_spec_ids[man->free_spec_cnt - 1]; in allocate_spec_id()
930 err = hashmap__add(specs_hash, target->spec_str, *spec_id); in allocate_spec_id()
934 man->free_spec_cnt--; in allocate_spec_id()
937 if (man->next_free_spec_id >= bpf_map__max_entries(man->specs_map)) in allocate_spec_id()
938 return -E2BIG; in allocate_spec_id()
940 *spec_id = man->next_free_spec_id; in allocate_spec_id()
943 err = hashmap__add(specs_hash, target->spec_str, *spec_id); in allocate_spec_id()
947 man->next_free_spec_id++; in allocate_spec_id()
950 /* remember new spec ID in the link for later return back to free list on detach */ in allocate_spec_id()
951 link->spec_ids[link->spec_cnt] = *spec_id; in allocate_spec_id()
952 link->spec_cnt++; in allocate_spec_id()
966 struct bpf_link_usdt *link = NULL; in usdt_manager_attach_usdt() local
972 spec_map_fd = bpf_map__fd(man->specs_map); in usdt_manager_attach_usdt()
973 ip_map_fd = bpf_map__fd(man->ip_to_spec_id_map); in usdt_manager_attach_usdt()
985 pid = -1; in usdt_manager_attach_usdt()
995 err = (err == 0) ? -ENOENT : err; in usdt_manager_attach_usdt()
1005 link = calloc(1, sizeof(*link)); in usdt_manager_attach_usdt()
1006 if (!link) { in usdt_manager_attach_usdt()
1007 err = -ENOMEM; in usdt_manager_attach_usdt()
1011 link->usdt_man = man; in usdt_manager_attach_usdt()
1012 link->link.detach = &bpf_link_usdt_detach; in usdt_manager_attach_usdt()
1013 link->link.dealloc = &bpf_link_usdt_dealloc; in usdt_manager_attach_usdt()
1015 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1021 err = -ENOMEM; in usdt_manager_attach_usdt()
1025 link->uprobes = calloc(target_cnt, sizeof(*link->uprobes)); in usdt_manager_attach_usdt()
1026 if (!link->uprobes) { in usdt_manager_attach_usdt()
1027 err = -ENOMEM; in usdt_manager_attach_usdt()
1046 err = allocate_spec_id(man, specs_hash, link, target, &spec_id, &is_new); in usdt_manager_attach_usdt()
1050 if (is_new && bpf_map_update_elem(spec_map_fd, &spec_id, &target->spec, BPF_ANY)) { in usdt_manager_attach_usdt()
1051 err = -errno; in usdt_manager_attach_usdt()
1056 if (!man->has_bpf_cookie && in usdt_manager_attach_usdt()
1057 bpf_map_update_elem(ip_map_fd, &target->abs_ip, &spec_id, BPF_NOEXIST)) { in usdt_manager_attach_usdt()
1058 err = -errno; in usdt_manager_attach_usdt()
1059 if (err == -EEXIST) { in usdt_manager_attach_usdt()
1064 target->abs_ip, spec_id, usdt_provider, usdt_name, in usdt_manager_attach_usdt()
1070 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1071 offsets[i] = target->rel_ip; in usdt_manager_attach_usdt()
1072 ref_ctr_offsets[i] = target->sema_off; in usdt_manager_attach_usdt()
1075 opts.ref_ctr_offset = target->sema_off; in usdt_manager_attach_usdt()
1076 opts.bpf_cookie = man->has_bpf_cookie ? spec_id : 0; in usdt_manager_attach_usdt()
1078 target->rel_ip, &opts); in usdt_manager_attach_usdt()
1086 link->uprobes[i].link = uprobe_link; in usdt_manager_attach_usdt()
1087 link->uprobes[i].abs_ip = target->abs_ip; in usdt_manager_attach_usdt()
1088 link->uprobe_cnt++; in usdt_manager_attach_usdt()
1092 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1100 link->multi_link = bpf_program__attach_uprobe_multi(prog, pid, path, in usdt_manager_attach_usdt()
1102 if (!link->multi_link) { in usdt_manager_attach_usdt()
1103 err = -errno; in usdt_manager_attach_usdt()
1117 return &link->link; in usdt_manager_attach_usdt()
1124 if (link) in usdt_manager_attach_usdt()
1125 bpf_link__destroy(&link->link); in usdt_manager_attach_usdt()
1144 if (strncmp(data + name_off, USDT_NOTE_NAME, nhdr->n_namesz) != 0) in parse_usdt_note()
1145 return -EINVAL; in parse_usdt_note()
1146 if (nhdr->n_type != USDT_NOTE_TYPE) in parse_usdt_note()
1147 return -EINVAL; in parse_usdt_note()
1150 len = nhdr->n_descsz; in parse_usdt_note()
1155 return -EINVAL; in parse_usdt_note()
1163 name = (const char *)memchr(provider, '\0', data + len - provider); in parse_usdt_note()
1164 if (!name) /* non-zero-terminated provider */ in parse_usdt_note()
1165 return -EINVAL; in parse_usdt_note()
1168 return -EINVAL; in parse_usdt_note()
1170 args = memchr(name, '\0', data + len - name); in parse_usdt_note()
1171 if (!args) /* non-zero-terminated name */ in parse_usdt_note()
1172 return -EINVAL; in parse_usdt_note()
1175 return -EINVAL; in parse_usdt_note()
1177 note->provider = provider; in parse_usdt_note()
1178 note->name = name; in parse_usdt_note()
1180 note->args = ""; in parse_usdt_note()
1182 note->args = args; in parse_usdt_note()
1183 note->loc_addr = addrs[0]; in parse_usdt_note()
1184 note->base_addr = addrs[1]; in parse_usdt_note()
1185 note->sema_addr = addrs[2]; in parse_usdt_note()
1198 spec->usdt_cookie = usdt_cookie; in parse_usdt_spec()
1199 spec->arg_cnt = 0; in parse_usdt_spec()
1201 s = note->args; in parse_usdt_spec()
1203 if (spec->arg_cnt >= USDT_MAX_ARG_CNT) { in parse_usdt_spec()
1205 USDT_MAX_ARG_CNT, note->provider, note->name, note->args); in parse_usdt_spec()
1206 return -E2BIG; in parse_usdt_spec()
1209 arg = &spec->args[spec->arg_cnt]; in parse_usdt_spec()
1210 len = parse_usdt_arg(s, spec->arg_cnt, arg, &arg_sz); in parse_usdt_spec()
1214 arg->arg_signed = arg_sz < 0; in parse_usdt_spec()
1216 arg_sz = -arg_sz; in parse_usdt_spec()
1220 arg->arg_bitshift = 64 - arg_sz * 8; in parse_usdt_spec()
1224 spec->arg_cnt, s, arg_sz); in parse_usdt_spec()
1225 return -EINVAL; in parse_usdt_spec()
1229 spec->arg_cnt++; in parse_usdt_spec()
1235 /* Architecture-specific logic for parsing USDT argument location specs */
1281 return -ENOENT; in calc_pt_regs_off()
1291 /* Memory dereference case, e.g., -4@-20(%rbp) */ in parse_usdt_arg()
1292 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1293 arg->val_off = off; in parse_usdt_arg()
1297 arg->reg_off = reg_off; in parse_usdt_arg()
1299 /* Memory dereference case without offset, e.g., 8@(%rsp) */ in parse_usdt_arg()
1300 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1301 arg->val_off = 0; in parse_usdt_arg()
1305 arg->reg_off = reg_off; in parse_usdt_arg()
1307 /* Register read case, e.g., -4@%eax */ in parse_usdt_arg()
1308 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1309 arg->val_off = 0; in parse_usdt_arg()
1314 arg->reg_off = reg_off; in parse_usdt_arg()
1316 /* Constant value case, e.g., 4@$71 */ in parse_usdt_arg()
1317 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1318 arg->val_off = off; in parse_usdt_arg()
1319 arg->reg_off = 0; in parse_usdt_arg()
1322 return -EINVAL; in parse_usdt_arg()
1330 /* Do not support __s390__ for now, since user_pt_regs is broken with -m31. */
1339 /* Memory dereference case, e.g., -2@-28(%r15) */ in parse_usdt_arg()
1340 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1341 arg->val_off = off; in parse_usdt_arg()
1344 return -EINVAL; in parse_usdt_arg()
1346 arg->reg_off = offsetof(user_pt_regs, gprs[reg]); in parse_usdt_arg()
1348 /* Register read case, e.g., -8@%r0 */ in parse_usdt_arg()
1349 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1350 arg->val_off = 0; in parse_usdt_arg()
1353 return -EINVAL; in parse_usdt_arg()
1355 arg->reg_off = offsetof(user_pt_regs, gprs[reg]); in parse_usdt_arg()
1357 /* Constant value case, e.g., 4@71 */ in parse_usdt_arg()
1358 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1359 arg->val_off = off; in parse_usdt_arg()
1360 arg->reg_off = 0; in parse_usdt_arg()
1363 return -EINVAL; in parse_usdt_arg()
1382 return -ENOENT; in calc_pt_regs_off()
1391 if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] , %ld ] %n", arg_sz, reg_name, &off, &len) == 3) { in parse_usdt_arg()
1392 /* Memory dereference case, e.g., -4@[sp, 96] */ in parse_usdt_arg()
1393 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1394 arg->val_off = off; in parse_usdt_arg()
1398 arg->reg_off = reg_off; in parse_usdt_arg()
1399 } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1400 /* Memory dereference case, e.g., -4@[sp] */ in parse_usdt_arg()
1401 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1402 arg->val_off = 0; in parse_usdt_arg()
1406 arg->reg_off = reg_off; in parse_usdt_arg()
1408 /* Constant value case, e.g., 4@5 */ in parse_usdt_arg()
1409 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1410 arg->val_off = off; in parse_usdt_arg()
1411 arg->reg_off = 0; in parse_usdt_arg()
1412 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1413 /* Register read case, e.g., -8@x4 */ in parse_usdt_arg()
1414 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1415 arg->val_off = 0; in parse_usdt_arg()
1419 arg->reg_off = reg_off; in parse_usdt_arg()
1422 return -EINVAL; in parse_usdt_arg()
1476 return -ENOENT; in calc_pt_regs_off()
1485 if (sscanf(arg_str, " %d @ %ld ( %15[a-z0-9] ) %n", arg_sz, &off, reg_name, &len) == 3) { in parse_usdt_arg()
1486 /* Memory dereference case, e.g., -8@-88(s0) */ in parse_usdt_arg()
1487 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1488 arg->val_off = off; in parse_usdt_arg()
1492 arg->reg_off = reg_off; in parse_usdt_arg()
1494 /* Constant value case, e.g., 4@5 */ in parse_usdt_arg()
1495 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1496 arg->val_off = off; in parse_usdt_arg()
1497 arg->reg_off = 0; in parse_usdt_arg()
1498 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1499 /* Register read case, e.g., -8@a1 */ in parse_usdt_arg()
1500 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1501 arg->val_off = 0; in parse_usdt_arg()
1505 arg->reg_off = reg_off; in parse_usdt_arg()
1508 return -EINVAL; in parse_usdt_arg()
1547 return -ENOENT; in calc_pt_regs_off()
1556 if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] , #%ld ] %n", in parse_usdt_arg()
1558 /* Memory dereference case, e.g., -4@[fp, #96] */ in parse_usdt_arg()
1559 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1560 arg->val_off = off; in parse_usdt_arg()
1564 arg->reg_off = reg_off; in parse_usdt_arg()
1565 } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1566 /* Memory dereference case, e.g., -4@[sp] */ in parse_usdt_arg()
1567 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1568 arg->val_off = 0; in parse_usdt_arg()
1572 arg->reg_off = reg_off; in parse_usdt_arg()
1574 /* Constant value case, e.g., 4@#5 */ in parse_usdt_arg()
1575 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1576 arg->val_off = off; in parse_usdt_arg()
1577 arg->reg_off = 0; in parse_usdt_arg()
1578 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1579 /* Register read case, e.g., -8@r4 */ in parse_usdt_arg()
1580 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1581 arg->val_off = 0; in parse_usdt_arg()
1585 arg->reg_off = reg_off; in parse_usdt_arg()
1588 return -EINVAL; in parse_usdt_arg()
1599 return -ENOTSUP; in parse_usdt_arg()