Lines Matching full:spec
27 /* high-level spec: named fields and array indices only */
28 struct bpf_core_accessor spec[BPF_CORE_SPEC_MAX_LEN]; member
33 /* high-level spec length */
35 /* raw, low-level spec: 1-to-1 with accessor spec string */
37 /* raw spec length */
39 /* field bit offset represented by spec */
117 * Turn bpf_core_relo into a low- and high-level spec representation,
119 * field bit offset, specified by accessor string. Low-level spec captures
138 * Low-level spec has 1:1 mapping with each element of access string (it's
141 * High-level spec will capture only 3 points:
143 * - field 'a' access (corresponds to '2' in low-level spec);
144 * - array element #3 access (corresponds to '3' in low-level spec).
148 * spec and raw_spec are kept empty.
157 struct bpf_core_spec *spec) in bpf_core_parse_spec() argument
169 memset(spec, 0, sizeof(*spec)); in bpf_core_parse_spec()
170 spec->btf = btf; in bpf_core_parse_spec()
171 spec->root_type_id = type_id; in bpf_core_parse_spec()
172 spec->relo_kind = relo_kind; in bpf_core_parse_spec()
187 if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN) in bpf_core_parse_spec()
190 spec->raw_spec[spec->raw_len++] = access_idx; in bpf_core_parse_spec()
193 if (spec->raw_len == 0) in bpf_core_parse_spec()
200 access_idx = spec->raw_spec[0]; in bpf_core_parse_spec()
201 acc = &spec->spec[0]; in bpf_core_parse_spec()
204 spec->len++; in bpf_core_parse_spec()
207 if (!btf_is_enum(t) || spec->raw_len > 1 || access_idx >= btf_vlen(t)) in bpf_core_parse_spec()
221 spec->bit_offset = access_idx * sz * 8; in bpf_core_parse_spec()
223 for (i = 1; i < spec->raw_len; i++) { in bpf_core_parse_spec()
228 access_idx = spec->raw_spec[i]; in bpf_core_parse_spec()
229 acc = &spec->spec[spec->len]; in bpf_core_parse_spec()
239 spec->bit_offset += bit_offset; in bpf_core_parse_spec()
250 spec->len++; in bpf_core_parse_spec()
266 spec->spec[spec->len].type_id = id; in bpf_core_parse_spec()
267 spec->spec[spec->len].idx = access_idx; in bpf_core_parse_spec()
268 spec->len++; in bpf_core_parse_spec()
273 spec->bit_offset += access_idx * sz * 8; in bpf_core_parse_spec()
358 * maintain low-level spec for target as well. Also keep updating target
375 struct bpf_core_spec *spec, in bpf_core_match_member() argument
403 if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN) in bpf_core_match_member()
407 spec->bit_offset += bit_offset; in bpf_core_match_member()
408 spec->raw_spec[spec->raw_len++] = i; in bpf_core_match_member()
415 spec, next_targ_id); in bpf_core_match_member()
422 targ_acc = &spec->spec[spec->len++]; in bpf_core_match_member()
432 spec->len--; /* pop accessor */ in bpf_core_match_member()
436 spec->bit_offset -= bit_offset; in bpf_core_match_member()
437 spec->raw_len--; in bpf_core_match_member()
444 * Try to match local spec to a target type and, if successful, produce full
445 * target spec (high-level, low-level + bit offset).
467 local_acc = &local_spec->spec[0]; in bpf_core_spec_match()
468 targ_acc = &targ_spec->spec[0]; in bpf_core_spec_match()
560 const struct bpf_core_spec *spec, in bpf_core_calc_field_relo() argument
575 *val = spec ? 1 : 0; in bpf_core_calc_field_relo()
579 if (!spec) in bpf_core_calc_field_relo()
582 acc = &spec->spec[spec->len - 1]; in bpf_core_calc_field_relo()
583 t = btf__type_by_id(spec->btf, acc->type_id); in bpf_core_calc_field_relo()
588 *val = spec->bit_offset / 8; in bpf_core_calc_field_relo()
590 sz = btf__resolve_size(spec->btf, acc->type_id); in bpf_core_calc_field_relo()
596 sz = btf__resolve_size(spec->btf, acc->type_id); in bpf_core_calc_field_relo()
611 mt = skip_mods_and_typedefs(spec->btf, m->type, &field_type_id); in bpf_core_calc_field_relo()
612 bit_off = spec->bit_offset; in bpf_core_calc_field_relo()
631 sz = btf__resolve_size(spec->btf, field_type_id); in bpf_core_calc_field_relo()
635 byte_off = spec->bit_offset / 8; in bpf_core_calc_field_relo()
685 const struct bpf_core_spec *spec, in bpf_core_calc_type_relo() argument
691 if (!spec) { in bpf_core_calc_type_relo()
698 *val = spec->root_type_id; in bpf_core_calc_type_relo()
704 sz = btf__resolve_size(spec->btf, spec->root_type_id); in bpf_core_calc_type_relo()
719 const struct bpf_core_spec *spec, in bpf_core_calc_enumval_relo() argument
727 *val = spec ? 1 : 0; in bpf_core_calc_enumval_relo()
730 if (!spec) in bpf_core_calc_enumval_relo()
732 t = btf__type_by_id(spec->btf, spec->spec[0].type_id); in bpf_core_calc_enumval_relo()
733 e = btf_enum(t) + spec->spec[0].idx; in bpf_core_calc_enumval_relo()
906 * For existence relocations target spec will be NULL if field/type is not found.
908 * spec, and is checked before patching instruction. If actual insn->imm value
1044 /* Output spec definition in the format:
1045 * [<type-id>] (<type-name>) + <raw-spec> => <offset>@<spec>,
1046 * where <spec> is a C-syntax view of recorded field access, e.g.: x.a[3].b
1048 static void bpf_core_dump_spec(int level, const struct bpf_core_spec *spec) in bpf_core_dump_spec() argument
1056 type_id = spec->root_type_id; in bpf_core_dump_spec()
1057 t = btf__type_by_id(spec->btf, type_id); in bpf_core_dump_spec()
1058 s = btf__name_by_offset(spec->btf, t->name_off); in bpf_core_dump_spec()
1062 if (core_relo_is_type_based(spec->relo_kind)) in bpf_core_dump_spec()
1065 if (core_relo_is_enumval_based(spec->relo_kind)) { in bpf_core_dump_spec()
1066 t = skip_mods_and_typedefs(spec->btf, type_id, NULL); in bpf_core_dump_spec()
1067 e = btf_enum(t) + spec->raw_spec[0]; in bpf_core_dump_spec()
1068 s = btf__name_by_offset(spec->btf, e->name_off); in bpf_core_dump_spec()
1074 if (core_relo_is_field_based(spec->relo_kind)) { in bpf_core_dump_spec()
1075 for (i = 0; i < spec->len; i++) { in bpf_core_dump_spec()
1076 if (spec->spec[i].name) in bpf_core_dump_spec()
1077 libbpf_print(level, ".%s", spec->spec[i].name); in bpf_core_dump_spec()
1078 else if (i > 0 || spec->spec[i].idx > 0) in bpf_core_dump_spec()
1079 libbpf_print(level, "[%u]", spec->spec[i].idx); in bpf_core_dump_spec()
1083 for (i = 0; i < spec->raw_len; i++) in bpf_core_dump_spec()
1084 libbpf_print(level, "%s%d", i == 0 ? "" : ":", spec->raw_spec[i]); in bpf_core_dump_spec()
1086 if (spec->bit_offset % 8) in bpf_core_dump_spec()
1088 spec->bit_offset / 8, spec->bit_offset % 8); in bpf_core_dump_spec()
1090 libbpf_print(level, " @ offset %u)", spec->bit_offset / 8); in bpf_core_dump_spec()
1121 * high-level spec accessors, meaning that all named fields should match,
1125 * matching the spec. As long as all the specs resolve to the same set of
1182 pr_debug("prog '%s': relo #%d: kind <%s> (%d), spec is ", prog_name, in bpf_core_apply_relo_insn()