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

1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
24 /* libbpf's USDT support consists of BPF-side state/code and user-space
25 * state/code working together in concert. BPF-side parts are defined in
26 * usdt.bpf.h header library. User-space state is encapsulated by struct
30 * and IP-to-spec-ID map, which is auxiliary map necessary for kernels that
38 * USDT-related until the very first call to bpf_program__attach_usdt(), which
42 * store it in bpf_object. USDT manager is per-BPF object construct, as each
44 * the expected USDT-related state. There is no coordination between two
46 * existence and libbpf is just oblivious, dealing with bpf_object-specific
51 * From user-space application's point of view, USDT is essentially just
53 * is being traced by some external entity (e.g, BPF-based tool). Here's how
56 * #include <sys/sdt.h> // provided by systemtap-sdt-devel package
61 * USDT is identified by it's <provider-name>:<probe-name> pair of names. Each
69 * `readelf -n <binary>`:
75 …* Arguments: -4@-1204(%rbp) -4@%edi -8@-1216(%rbp) -8@%r8 -4@$5 -8@%r9 8@%rdx 8@%r10 -4@$-9 -2@%…
83 * Semaphore above is and optional feature. It records an address of a 2-byte
89 * Recent enough kernel has built-in support for automatically managing this
98 * The part after @ sign is assembly-like definition of argument location
102 * 1) immediate constant, see 5th and 9th args above (-4@$5 and -4@-9);
103 * 2) register value, e.g., 8@%rdx, which means "unsigned 8-byte integer
105 * 3) memory dereference addressed by register, e.g., -4@-1204(%rbp), which
106 * specifies signed 32-bit integer stored at offset -1204 bytes from
112 * prepares `struct usdt_spec` (USDT spec), which is then provided to BPF-side
114 * actual value at runtime using a simple BPF-side code.
128 * macro invocations can end up being inlined many-many times, depending on
144 * about. This state has to be maintained per-BPF object and coordinate
151 * support BPF cookie, through IP-to-spec-ID map that libbpf maintains in such
155 * calculate absolute IP addresses for IP-to-spec-ID map, and thus such mode
161 * user-provided value that can be associated with USDT attachment. Note that
175 * on-the-fly deduplication during a single USDT attachment to only allocate
226 /* USDT args specification string, e.g.:
227 * "-4@%esi -4@-24(%rbp) -4@%ecx 2@%ax 8@%rdx"
266 return ERR_PTR(-ESRCH); in usdt_manager_new()
271 return ERR_PTR(-ENOMEM); in usdt_manager_new()
273 man->specs_map = specs_map; in usdt_manager_new()
274 man->ip_to_spec_id_map = ip_to_spec_id_map; in usdt_manager_new()
277 * We don't need IP-to-ID mapping if we can use BPF cookies. in usdt_manager_new()
280 man->has_bpf_cookie = kernel_supports(obj, FEAT_BPF_COOKIE); in usdt_manager_new()
284 * Added in: a6ca88b241d5 ("trace_uprobe: support reference counter in fd-based uprobe") in usdt_manager_new()
286 man->has_sema_refcnt = faccessat(AT_FDCWD, ref_ctr_sysfs_path, F_OK, AT_EACCESS) == 0; in usdt_manager_new()
289 * Detect kernel support for uprobe multi link to be used for attaching in usdt_manager_new()
292 man->has_uprobe_multi = kernel_supports(obj, FEAT_UPROBE_MULTI_LINK); in usdt_manager_new()
301 free(man->free_spec_ids); in usdt_manager_free()
312 return -EBADF; in sanity_check_usdt_elf()
318 pr_warn("usdt: attaching to 64-bit ELF binary '%s' is not supported\n", path); in sanity_check_usdt_elf()
319 return -EBADF; in sanity_check_usdt_elf()
324 pr_warn("usdt: attaching to 32-bit ELF binary '%s' is not supported\n", path); in sanity_check_usdt_elf()
325 return -EBADF; in sanity_check_usdt_elf()
330 return -EBADF; in sanity_check_usdt_elf()
334 return -EINVAL; in sanity_check_usdt_elf()
339 return -EBADF; in sanity_check_usdt_elf()
351 return -EBADF; in sanity_check_usdt_elf()
363 return -EINVAL; in find_elf_sec_by_name()
367 return -EINVAL; in find_elf_sec_by_name()
373 return -EINVAL; in find_elf_sec_by_name()
375 name = elf_strptr(elf, shstrndx, shdr->sh_name); in find_elf_sec_by_name()
382 return -ENOENT; in find_elf_sec_by_name()
397 return a->start < b->start ? -1 : 1; in cmp_elf_segs()
411 err = -errno; in parse_elf_segs()
417 err = -errno; in parse_elf_segs()
429 return -ENOMEM; in parse_elf_segs()
435 seg->start = phdr.p_vaddr; in parse_elf_segs()
436 seg->end = phdr.p_vaddr + phdr.p_memsz; in parse_elf_segs()
437 seg->offset = phdr.p_offset; in parse_elf_segs()
438 seg->is_exec = phdr.p_flags & PF_X; in parse_elf_segs()
443 return -ESRCH; in parse_elf_segs()
469 lib_path, -errno); in parse_vma_segs()
477 err = -errno; in parse_vma_segs()
485 * 7f5c6f5d1000-7f5c6f5d3000 rw-p 001c7000 08:04 21238613 /usr/lib64/libc-2.17.so in parse_vma_segs()
486 * 7f5c6f5d3000-7f5c6f5d8000 rw-p 00000000 00:00 0 in parse_vma_segs()
487 …* 7f5c6f5d8000-7f5c6f5d9000 r-xp 00000000 103:01 362990598 /data/users/andriin/linux/tools/bpf/… in parse_vma_segs()
489 while (fscanf(f, "%zx-%zx %s %zx %*s %*d%[^\n]\n", in parse_vma_segs()
503 pr_debug("usdt: discovered segment for lib '%s': addrs %zx-%zx mode %s offset %zx\n", in parse_vma_segs()
506 /* ignore non-executable sections for shared libs */ in parse_vma_segs()
512 err = -ENOMEM; in parse_vma_segs()
520 seg->start = seg_start; in parse_vma_segs()
521 seg->end = seg_end; in parse_vma_segs()
522 seg->offset = seg_off; in parse_vma_segs()
523 seg->is_exec = true; in parse_vma_segs()
529 err = -ESRCH; in parse_vma_segs()
550 if (seg->start <= virtaddr && virtaddr < seg->end) in find_elf_seg()
563 * offset-based range of [offset_start, offset_end) in find_vma_seg()
566 if (seg->offset <= offset && offset < seg->offset + (seg->end - seg->start)) in find_vma_seg()
604 return -EINVAL; in collect_usdt_targets()
627 err = parse_usdt_note(elf, path, &nhdr, data->d_buf, name_off, desc_off, &note); in collect_usdt_targets()
637 * Each SDT probe also expands into a non-allocated ELF note. You can in collect_usdt_targets()
639 * see below for details. Because the note is non-allocated, it means in collect_usdt_targets()
646 * will only ever have one of these sections in a final link and it in collect_usdt_targets()
651 * Each probe note records the link-time address of the .stapsdt.base in collect_usdt_targets()
663 usdt_abs_ip += base_addr - note.base_addr; in collect_usdt_targets()
672 err = -ESRCH; in collect_usdt_targets()
677 if (!seg->is_exec) { in collect_usdt_targets()
678 err = -ESRCH; in collect_usdt_targets()
680 path, seg->start, seg->end, usdt_provider, usdt_name, in collect_usdt_targets()
685 usdt_rel_ip = usdt_abs_ip - seg->start + seg->offset; in collect_usdt_targets()
687 if (ehdr.e_type == ET_DYN && !man->has_bpf_cookie) { in collect_usdt_targets()
703 err = -ENOTSUP; in collect_usdt_targets()
719 err = -ESRCH; in collect_usdt_targets()
725 usdt_abs_ip = seg->start - seg->offset + usdt_rel_ip; in collect_usdt_targets()
731 seg ? seg->start : 0, seg ? seg->end : 0, seg ? seg->offset : 0); in collect_usdt_targets()
735 if (!man->has_sema_refcnt) { in collect_usdt_targets()
738 err = -ENOTSUP; in collect_usdt_targets()
744 err = -ESRCH; in collect_usdt_targets()
749 if (seg->is_exec) { in collect_usdt_targets()
750 err = -ESRCH; in collect_usdt_targets()
752 path, seg->start, seg->end, usdt_provider, usdt_name, in collect_usdt_targets()
757 usdt_sema_off = note.sema_addr - seg->start + seg->offset; in collect_usdt_targets()
762 seg->start, seg->end, seg->offset); in collect_usdt_targets()
768 err = -ENOMEM; in collect_usdt_targets()
776 target->abs_ip = usdt_abs_ip; in collect_usdt_targets()
777 target->rel_ip = usdt_rel_ip; in collect_usdt_targets()
778 target->sema_off = usdt_sema_off; in collect_usdt_targets()
783 target->spec_str = note.args; in collect_usdt_targets()
785 err = parse_usdt_spec(&target->spec, &note, usdt_cookie); in collect_usdt_targets()
805 struct bpf_link link; member
815 struct bpf_link *link; member
821 static int bpf_link_usdt_detach(struct bpf_link *link) in bpf_link_usdt_detach() argument
823 struct bpf_link_usdt *usdt_link = container_of(link, struct bpf_link_usdt, link); in bpf_link_usdt_detach()
824 struct usdt_manager *man = usdt_link->usdt_man; in bpf_link_usdt_detach()
827 bpf_link__destroy(usdt_link->multi_link); in bpf_link_usdt_detach()
830 for (i = 0; i < usdt_link->uprobe_cnt; i++) { in bpf_link_usdt_detach()
831 /* detach underlying uprobe link */ in bpf_link_usdt_detach()
832 bpf_link__destroy(usdt_link->uprobes[i].link); in bpf_link_usdt_detach()
839 if (!man->has_bpf_cookie) { in bpf_link_usdt_detach()
841 (void)bpf_map_delete_elem(bpf_map__fd(man->ip_to_spec_id_map), in bpf_link_usdt_detach()
842 &usdt_link->uprobes[i].abs_ip); in bpf_link_usdt_detach()
849 if (!man->free_spec_ids) { in bpf_link_usdt_detach()
851 man->free_spec_ids = usdt_link->spec_ids; in bpf_link_usdt_detach()
852 man->free_spec_cnt = usdt_link->spec_cnt; in bpf_link_usdt_detach()
853 usdt_link->spec_ids = NULL; in bpf_link_usdt_detach()
856 size_t new_cnt = man->free_spec_cnt + usdt_link->spec_cnt; in bpf_link_usdt_detach()
859 new_free_ids = libbpf_reallocarray(man->free_spec_ids, new_cnt, in bpf_link_usdt_detach()
871 memcpy(new_free_ids + man->free_spec_cnt, usdt_link->spec_ids, in bpf_link_usdt_detach()
872 usdt_link->spec_cnt * sizeof(*usdt_link->spec_ids)); in bpf_link_usdt_detach()
873 man->free_spec_ids = new_free_ids; in bpf_link_usdt_detach()
874 man->free_spec_cnt = new_cnt; in bpf_link_usdt_detach()
881 static void bpf_link_usdt_dealloc(struct bpf_link *link) in bpf_link_usdt_dealloc() argument
883 struct bpf_link_usdt *usdt_link = container_of(link, struct bpf_link_usdt, link); in bpf_link_usdt_dealloc()
885 free(usdt_link->spec_ids); in bpf_link_usdt_dealloc()
886 free(usdt_link->uprobes); in bpf_link_usdt_dealloc()
901 struct bpf_link_usdt *link, struct usdt_target *target, in allocate_spec_id() argument
909 if (hashmap__find(specs_hash, target->spec_str, &tmp)) { in allocate_spec_id()
916 * returned back to usdt_manager when USDT link is detached in allocate_spec_id()
918 new_ids = libbpf_reallocarray(link->spec_ids, link->spec_cnt + 1, sizeof(*link->spec_ids)); in allocate_spec_id()
920 return -ENOMEM; in allocate_spec_id()
921 link->spec_ids = new_ids; in allocate_spec_id()
924 if (man->free_spec_cnt) { in allocate_spec_id()
925 *spec_id = man->free_spec_ids[man->free_spec_cnt - 1]; in allocate_spec_id()
928 err = hashmap__add(specs_hash, target->spec_str, *spec_id); in allocate_spec_id()
932 man->free_spec_cnt--; in allocate_spec_id()
935 if (man->next_free_spec_id >= bpf_map__max_entries(man->specs_map)) in allocate_spec_id()
936 return -E2BIG; in allocate_spec_id()
938 *spec_id = man->next_free_spec_id; in allocate_spec_id()
941 err = hashmap__add(specs_hash, target->spec_str, *spec_id); in allocate_spec_id()
945 man->next_free_spec_id++; in allocate_spec_id()
948 /* remember new spec ID in the link for later return back to free list on detach */ in allocate_spec_id()
949 link->spec_ids[link->spec_cnt] = *spec_id; in allocate_spec_id()
950 link->spec_cnt++; in allocate_spec_id()
964 struct bpf_link_usdt *link = NULL; in usdt_manager_attach_usdt() local
970 spec_map_fd = bpf_map__fd(man->specs_map); in usdt_manager_attach_usdt()
971 ip_map_fd = bpf_map__fd(man->ip_to_spec_id_map); in usdt_manager_attach_usdt()
983 pid = -1; in usdt_manager_attach_usdt()
993 err = (err == 0) ? -ENOENT : err; in usdt_manager_attach_usdt()
1003 link = calloc(1, sizeof(*link)); in usdt_manager_attach_usdt()
1004 if (!link) { in usdt_manager_attach_usdt()
1005 err = -ENOMEM; in usdt_manager_attach_usdt()
1009 link->usdt_man = man; in usdt_manager_attach_usdt()
1010 link->link.detach = &bpf_link_usdt_detach; in usdt_manager_attach_usdt()
1011 link->link.dealloc = &bpf_link_usdt_dealloc; in usdt_manager_attach_usdt()
1013 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1019 err = -ENOMEM; in usdt_manager_attach_usdt()
1023 link->uprobes = calloc(target_cnt, sizeof(*link->uprobes)); in usdt_manager_attach_usdt()
1024 if (!link->uprobes) { in usdt_manager_attach_usdt()
1025 err = -ENOMEM; in usdt_manager_attach_usdt()
1044 err = allocate_spec_id(man, specs_hash, link, target, &spec_id, &is_new); in usdt_manager_attach_usdt()
1048 if (is_new && bpf_map_update_elem(spec_map_fd, &spec_id, &target->spec, BPF_ANY)) { in usdt_manager_attach_usdt()
1049 err = -errno; in usdt_manager_attach_usdt()
1054 if (!man->has_bpf_cookie && in usdt_manager_attach_usdt()
1055 bpf_map_update_elem(ip_map_fd, &target->abs_ip, &spec_id, BPF_NOEXIST)) { in usdt_manager_attach_usdt()
1056 err = -errno; in usdt_manager_attach_usdt()
1057 if (err == -EEXIST) { in usdt_manager_attach_usdt()
1062 target->abs_ip, spec_id, usdt_provider, usdt_name, in usdt_manager_attach_usdt()
1068 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1069 offsets[i] = target->rel_ip; in usdt_manager_attach_usdt()
1070 ref_ctr_offsets[i] = target->sema_off; in usdt_manager_attach_usdt()
1073 opts.ref_ctr_offset = target->sema_off; in usdt_manager_attach_usdt()
1074 opts.bpf_cookie = man->has_bpf_cookie ? spec_id : 0; in usdt_manager_attach_usdt()
1076 target->rel_ip, &opts); in usdt_manager_attach_usdt()
1084 link->uprobes[i].link = uprobe_link; in usdt_manager_attach_usdt()
1085 link->uprobes[i].abs_ip = target->abs_ip; in usdt_manager_attach_usdt()
1086 link->uprobe_cnt++; in usdt_manager_attach_usdt()
1090 if (man->has_uprobe_multi) { in usdt_manager_attach_usdt()
1098 link->multi_link = bpf_program__attach_uprobe_multi(prog, pid, path, in usdt_manager_attach_usdt()
1100 if (!link->multi_link) { in usdt_manager_attach_usdt()
1101 err = -errno; in usdt_manager_attach_usdt()
1115 return &link->link; in usdt_manager_attach_usdt()
1122 if (link) in usdt_manager_attach_usdt()
1123 bpf_link__destroy(&link->link); in usdt_manager_attach_usdt()
1142 if (strncmp(data + name_off, USDT_NOTE_NAME, nhdr->n_namesz) != 0) in parse_usdt_note()
1143 return -EINVAL; in parse_usdt_note()
1144 if (nhdr->n_type != USDT_NOTE_TYPE) in parse_usdt_note()
1145 return -EINVAL; in parse_usdt_note()
1148 len = nhdr->n_descsz; in parse_usdt_note()
1153 return -EINVAL; in parse_usdt_note()
1161 name = (const char *)memchr(provider, '\0', data + len - provider); in parse_usdt_note()
1162 if (!name) /* non-zero-terminated provider */ in parse_usdt_note()
1163 return -EINVAL; in parse_usdt_note()
1166 return -EINVAL; in parse_usdt_note()
1168 args = memchr(name, '\0', data + len - name); in parse_usdt_note()
1169 if (!args) /* non-zero-terminated name */ in parse_usdt_note()
1170 return -EINVAL; in parse_usdt_note()
1173 return -EINVAL; in parse_usdt_note()
1175 note->provider = provider; in parse_usdt_note()
1176 note->name = name; in parse_usdt_note()
1178 note->args = ""; in parse_usdt_note()
1180 note->args = args; in parse_usdt_note()
1181 note->loc_addr = addrs[0]; in parse_usdt_note()
1182 note->base_addr = addrs[1]; in parse_usdt_note()
1183 note->sema_addr = addrs[2]; in parse_usdt_note()
1196 spec->usdt_cookie = usdt_cookie; in parse_usdt_spec()
1197 spec->arg_cnt = 0; in parse_usdt_spec()
1199 s = note->args; in parse_usdt_spec()
1201 if (spec->arg_cnt >= USDT_MAX_ARG_CNT) { in parse_usdt_spec()
1203 USDT_MAX_ARG_CNT, note->provider, note->name, note->args); in parse_usdt_spec()
1204 return -E2BIG; in parse_usdt_spec()
1207 arg = &spec->args[spec->arg_cnt]; in parse_usdt_spec()
1208 len = parse_usdt_arg(s, spec->arg_cnt, arg, &arg_sz); in parse_usdt_spec()
1212 arg->arg_signed = arg_sz < 0; in parse_usdt_spec()
1214 arg_sz = -arg_sz; in parse_usdt_spec()
1218 arg->arg_bitshift = 64 - arg_sz * 8; in parse_usdt_spec()
1222 spec->arg_cnt, s, arg_sz); in parse_usdt_spec()
1223 return -EINVAL; in parse_usdt_spec()
1227 spec->arg_cnt++; in parse_usdt_spec()
1233 /* Architecture-specific logic for parsing USDT argument location specs */
1279 return -ENOENT; in calc_pt_regs_off()
1289 /* Memory dereference case, e.g., -4@-20(%rbp) */ in parse_usdt_arg()
1290 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1291 arg->val_off = off; in parse_usdt_arg()
1295 arg->reg_off = reg_off; in parse_usdt_arg()
1297 /* Memory dereference case without offset, e.g., 8@(%rsp) */ in parse_usdt_arg()
1298 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1299 arg->val_off = 0; in parse_usdt_arg()
1303 arg->reg_off = reg_off; in parse_usdt_arg()
1305 /* Register read case, e.g., -4@%eax */ in parse_usdt_arg()
1306 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1307 arg->val_off = 0; in parse_usdt_arg()
1312 arg->reg_off = reg_off; in parse_usdt_arg()
1314 /* Constant value case, e.g., 4@$71 */ in parse_usdt_arg()
1315 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1316 arg->val_off = off; in parse_usdt_arg()
1317 arg->reg_off = 0; in parse_usdt_arg()
1320 return -EINVAL; in parse_usdt_arg()
1328 /* Do not support __s390__ for now, since user_pt_regs is broken with -m31. */
1337 /* Memory dereference case, e.g., -2@-28(%r15) */ in parse_usdt_arg()
1338 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1339 arg->val_off = off; in parse_usdt_arg()
1342 return -EINVAL; in parse_usdt_arg()
1344 arg->reg_off = offsetof(user_pt_regs, gprs[reg]); in parse_usdt_arg()
1346 /* Register read case, e.g., -8@%r0 */ in parse_usdt_arg()
1347 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1348 arg->val_off = 0; in parse_usdt_arg()
1351 return -EINVAL; in parse_usdt_arg()
1353 arg->reg_off = offsetof(user_pt_regs, gprs[reg]); in parse_usdt_arg()
1355 /* Constant value case, e.g., 4@71 */ in parse_usdt_arg()
1356 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1357 arg->val_off = off; in parse_usdt_arg()
1358 arg->reg_off = 0; in parse_usdt_arg()
1361 return -EINVAL; in parse_usdt_arg()
1380 return -ENOENT; in calc_pt_regs_off()
1389 if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] , %ld ] %n", arg_sz, reg_name, &off, &len) == 3) { in parse_usdt_arg()
1390 /* Memory dereference case, e.g., -4@[sp, 96] */ in parse_usdt_arg()
1391 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1392 arg->val_off = off; in parse_usdt_arg()
1396 arg->reg_off = reg_off; in parse_usdt_arg()
1397 } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1398 /* Memory dereference case, e.g., -4@[sp] */ in parse_usdt_arg()
1399 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1400 arg->val_off = 0; in parse_usdt_arg()
1404 arg->reg_off = reg_off; in parse_usdt_arg()
1406 /* Constant value case, e.g., 4@5 */ in parse_usdt_arg()
1407 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1408 arg->val_off = off; in parse_usdt_arg()
1409 arg->reg_off = 0; in parse_usdt_arg()
1410 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1411 /* Register read case, e.g., -8@x4 */ in parse_usdt_arg()
1412 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1413 arg->val_off = 0; in parse_usdt_arg()
1417 arg->reg_off = reg_off; in parse_usdt_arg()
1420 return -EINVAL; in parse_usdt_arg()
1474 return -ENOENT; in calc_pt_regs_off()
1483 if (sscanf(arg_str, " %d @ %ld ( %15[a-z0-9] ) %n", arg_sz, &off, reg_name, &len) == 3) { in parse_usdt_arg()
1484 /* Memory dereference case, e.g., -8@-88(s0) */ in parse_usdt_arg()
1485 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1486 arg->val_off = off; in parse_usdt_arg()
1490 arg->reg_off = reg_off; in parse_usdt_arg()
1492 /* Constant value case, e.g., 4@5 */ in parse_usdt_arg()
1493 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1494 arg->val_off = off; in parse_usdt_arg()
1495 arg->reg_off = 0; in parse_usdt_arg()
1496 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1497 /* Register read case, e.g., -8@a1 */ in parse_usdt_arg()
1498 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1499 arg->val_off = 0; in parse_usdt_arg()
1503 arg->reg_off = reg_off; in parse_usdt_arg()
1506 return -EINVAL; in parse_usdt_arg()
1545 return -ENOENT; in calc_pt_regs_off()
1554 if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] , #%ld ] %n", in parse_usdt_arg()
1556 /* Memory dereference case, e.g., -4@[fp, #96] */ in parse_usdt_arg()
1557 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1558 arg->val_off = off; in parse_usdt_arg()
1562 arg->reg_off = reg_off; in parse_usdt_arg()
1563 } else if (sscanf(arg_str, " %d @ \[ %15[a-z0-9] ] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1564 /* Memory dereference case, e.g., -4@[sp] */ in parse_usdt_arg()
1565 arg->arg_type = USDT_ARG_REG_DEREF; in parse_usdt_arg()
1566 arg->val_off = 0; in parse_usdt_arg()
1570 arg->reg_off = reg_off; in parse_usdt_arg()
1572 /* Constant value case, e.g., 4@#5 */ in parse_usdt_arg()
1573 arg->arg_type = USDT_ARG_CONST; in parse_usdt_arg()
1574 arg->val_off = off; in parse_usdt_arg()
1575 arg->reg_off = 0; in parse_usdt_arg()
1576 } else if (sscanf(arg_str, " %d @ %15[a-z0-9] %n", arg_sz, reg_name, &len) == 2) { in parse_usdt_arg()
1577 /* Register read case, e.g., -8@r4 */ in parse_usdt_arg()
1578 arg->arg_type = USDT_ARG_REG; in parse_usdt_arg()
1579 arg->val_off = 0; in parse_usdt_arg()
1583 arg->reg_off = reg_off; in parse_usdt_arg()
1586 return -EINVAL; in parse_usdt_arg()
1597 return -ENOTSUP; in parse_usdt_arg()