Lines Matching refs:spec
227 * Turn bpf_core_relo into a low- and high-level spec representation,
229 * field bit offset, specified by accessor string. Low-level spec captures
248 * Low-level spec has 1:1 mapping with each element of access string (it's
251 * High-level spec will capture only 3 points:
253 * - field 'a' access (corresponds to '2' in low-level spec);
254 * - array element #3 access (corresponds to '3' in low-level spec).
258 * spec and raw_spec are kept empty.
265 struct bpf_core_spec *spec)
278 memset(spec, 0, sizeof(*spec));
279 spec->btf = btf;
280 spec->root_type_id = relo->type_id;
281 spec->relo_kind = relo->kind;
296 if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN)
299 spec->raw_spec[spec->raw_len++] = access_idx;
302 if (spec->raw_len == 0)
309 access_idx = spec->raw_spec[0];
310 acc = &spec->spec[0];
313 spec->len++;
316 if (!btf_is_any_enum(t) || spec->raw_len > 1 || access_idx >= btf_vlen(t))
332 spec->bit_offset = access_idx * sz * 8;
334 for (i = 1; i < spec->raw_len; i++) {
339 access_idx = spec->raw_spec[i];
340 acc = &spec->spec[spec->len];
350 spec->bit_offset += bit_offset;
361 spec->len++;
377 spec->spec[spec->len].type_id = id;
378 spec->spec[spec->len].idx = access_idx;
379 spec->len++;
384 spec->bit_offset += access_idx * sz * 8;
468 * maintain low-level spec for target as well. Also keep updating target
485 struct bpf_core_spec *spec,
513 if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN)
517 spec->bit_offset += bit_offset;
518 spec->raw_spec[spec->raw_len++] = i;
525 spec, next_targ_id);
532 targ_acc = &spec->spec[spec->len++];
542 spec->len--; /* pop accessor */
546 spec->bit_offset -= bit_offset;
547 spec->raw_len--;
554 * Try to match local spec to a target type and, if successful, produce full
555 * target spec (high-level, low-level + bit offset).
583 local_acc = &local_spec->spec[0];
584 targ_acc = &targ_spec->spec[0];
680 const struct bpf_core_spec *spec,
695 *val = spec ? 1 : 0;
699 if (!spec)
702 acc = &spec->spec[spec->len - 1];
703 t = btf_type_by_id(spec->btf, acc->type_id);
708 *val = spec->bit_offset / 8;
710 sz = btf__resolve_size(spec->btf, acc->type_id);
716 sz = btf__resolve_size(spec->btf, acc->type_id);
731 mt = skip_mods_and_typedefs(spec->btf, m->type, &field_type_id);
732 bit_off = spec->bit_offset;
751 sz = btf__resolve_size(spec->btf, field_type_id);
755 byte_off = spec->bit_offset / 8;
804 const struct bpf_core_spec *spec,
814 if (!spec) {
821 *val = spec->root_type_id;
833 sz = btf__resolve_size(spec->btf, spec->root_type_id);
848 const struct bpf_core_spec *spec,
855 *val = spec ? 1 : 0;
858 if (!spec)
860 t = btf_type_by_id(spec->btf, spec->spec[0].type_id);
862 *val = btf_enum(t)[spec->spec[0].idx].val;
864 *val = btf_enum64_value(btf_enum64(t) + spec->spec[0].idx);
1011 * For existence relocations target spec will be NULL if field/type is not found.
1013 * spec, and is checked before patching instruction. If actual insn->imm value
1152 /* Output spec definition in the format:
1153 * [<type-id>] (<type-name>) + <raw-spec> => <offset>@<spec>,
1154 * where <spec> is a C-syntax view of recorded field access, e.g.: x.a[3].b
1156 int bpf_core_format_spec(char *buf, size_t buf_sz, const struct bpf_core_spec *spec)
1174 type_id = spec->root_type_id;
1175 t = btf_type_by_id(spec->btf, type_id);
1176 s = btf__name_by_offset(spec->btf, t->name_off);
1179 core_relo_kind_str(spec->relo_kind),
1182 if (core_relo_is_type_based(spec->relo_kind))
1185 if (core_relo_is_enumval_based(spec->relo_kind)) {
1186 t = skip_mods_and_typedefs(spec->btf, type_id, NULL);
1191 e = btf_enum(t) + spec->raw_spec[0];
1192 s = btf__name_by_offset(spec->btf, e->name_off);
1199 e = btf_enum64(t) + spec->raw_spec[0];
1200 s = btf__name_by_offset(spec->btf, e->name_off);
1207 if (core_relo_is_field_based(spec->relo_kind)) {
1208 for (i = 0; i < spec->len; i++) {
1209 if (spec->spec[i].name)
1210 append_buf(".%s", spec->spec[i].name);
1211 else if (i > 0 || spec->spec[i].idx > 0)
1212 append_buf("[%u]", spec->spec[i].idx);
1216 for (i = 0; i < spec->raw_len; i++)
1217 append_buf("%s%d", i == 0 ? "" : ":", spec->raw_spec[i]);
1219 if (spec->bit_offset % 8)
1220 append_buf(" @ offset %u.%u)", spec->bit_offset / 8, spec->bit_offset % 8);
1222 append_buf(" @ offset %u)", spec->bit_offset / 8);
1256 * high-level spec accessors, meaning that all named fields should match,
1260 * matching the spec. As long as all the specs resolve to the same set of