Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bpf: Support multi-attach for freplace'

Toke Høiland-Jørgensen says:

====================
This series adds support attaching freplace BPF programs to multiple targets.
This is needed to support incremental attachment of multiple XDP programs using
the libxdp dispatcher model.

Patch 1 moves prog_aux->linked_prog and the trampoline to be embedded in
bpf_tracing_link on attach, and freed by the link release logic, and introduces
a mutex to protect the writing of the pointers in prog->aux.

Based on this refactoring (and previously applied patches), it becomes pretty
straight-forward to support multiple-attach for freplace programs (patch 2).
This is simply a matter of creating a second bpf_tracing_link if a target is
supplied. However, for API consistency with other types of link attach, this
option is added to the BPF_LINK_CREATE API instead of extending
bpf_raw_tracepoint_open().

Patch 3 is a port of Jiri Olsa's patch to support fentry/fexit on freplace
programs. His approach of getting the target type from the target program
reference no longer works after we've gotten rid of linked_prog (because the
bpf_tracing_link reference disappears on attach). Instead, we used the saved
reference to the target prog type that is also used to verify compatibility on
secondary freplace attachment.

Patch 4 is the accompanying libbpf update, and patches 5-7 are selftests: patch
5 tests for the multi-freplace functionality itself; patch 6 is Jiri's previous
selftest for the fentry-to-freplace fix; patch 7 is a test for the change
introduced in the previously-applied patches, blocking MODIFY_RETURN functions
from attaching to other BPF programs.

With this series, libxdp and xdp-tools can successfully attach multiple programs
one at a time. To play with this, use the 'freplace-multi-attach' branch of
xdp-tools:

$ git clone --recurse-submodules --branch freplace-multi-attach https://github.com/xdp-project/xdp-tools
$ cd xdp-tools/xdp-loader
$ make
$ sudo ./xdp-loader load veth0 ../lib/testing/xdp_drop.o
$ sudo ./xdp-loader load veth0 ../lib/testing/xdp_pass.o
$ sudo ./xdp-loader status

The series is also available here:
https://git.kernel.org/pub/scm/linux/kernel/git/toke/linux.git/log/?h=bpf-freplace-multi-attach-alt-10

Changelog:

v10:
- Dial back the s/tgt_/dst_/ replacement a bit
- Fix smatch warning (from ktest robot)
- Rebase to bpf-next, drop already-applied patches

v9:
- Clarify commit message of patch 3
- Add new struct bpf_attach_target_info for returning from
bpf_check_attach_target() and passing to bpf_trampoline_get()
- Move trampoline key computation into a helper
- Make sure we don't break bpffs debug umh
- Add some comment blocks explaining the logic flow in
bpf_tracing_prog_attach()
- s/tgt_/dst_/ in prog->aux, and for local variables using those members
- Always drop dst_trampoline and dst_prog from prog->aux on first attach
- Don't remove syscall fmod_ret test from selftest benchmarks
- Add saved_ prefix to dst_{prog,attach}_type members in prog_aux
- Drop prog argument from check_attach_modify_return()
- Add comment about possible NULL of tr_link->tgt_prog on link_release()

v8:
- Add a separate error message when trying to attach FMOD_REPLACE to tgt_prog
- Better error messages in bpf_program__attach_freplace()
- Don't lock mutex when setting tgt_* pointers in prog create and verifier
- Remove fmod_ret programs from benchmarks in selftests (new patch 11)
- Fix a few other nits in selftests

v7:
- Add back missing ptype == prog->type check in link_create()
- Use tracing_bpf_link_attach() instead of separate freplace_bpf_link_attach()
- Don't break attachment of bpf_iters in libbpf (by clobbering link_create.iter_info)

v6:
- Rebase to latest bpf-next
- Simplify logic in bpf_tracing_prog_attach()
- Don't create a new attach_type for link_create(), disambiguate on prog->type
instead
- Use raw_tracepoint_open() in libbpf bpf_program__attach_ftrace() if called
with NULL target
- Switch bpf_program__attach_ftrace() to take function name as parameter
instead of btf_id
- Add a patch disallowing MODIFY_RETURN programs from attaching to other BPF
programs, and an accompanying selftest (patches 1 and 10)

v5:
- Fix typo in inline function definition of bpf_trampoline_get()
- Don't put bpf_tracing_link in prog->aux, use a mutex to protect tgt_prog and
trampoline instead, and move them to the link on attach.
- Restore Jiri as author of the last selftest patch

v4:
- Cleanup the refactored check_attach_btf_id() to make the logic easier to follow
- Fix cleanup paths for bpf_tracing_link
- Use xchg() for removing the bpf_tracing_link from prog->aux and restore on (some) failures
- Use BPF_LINK_CREATE operation to create link with target instead of extending raw_tracepoint_open
- Fold update of tools/ UAPI header into main patch
- Update arg dereference patch to use skeletons and set_attach_target()

v3:
- Get rid of prog_aux->linked_prog entirely in favour of a bpf_tracing_link
- Incorporate Jiri's fix for attaching fentry to freplace programs

v2:
- Drop the log arguments from bpf_raw_tracepoint_open
- Fix kbot errors
- Rebase to latest bpf-next
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+867 -317
+11 -6
include/linux/bpf.h
··· 640 640 return bpf_func(ctx, insnsi); 641 641 } 642 642 #ifdef CONFIG_BPF_JIT 643 - int bpf_trampoline_link_prog(struct bpf_prog *prog); 644 - int bpf_trampoline_unlink_prog(struct bpf_prog *prog); 643 + int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr); 644 + int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr); 645 645 struct bpf_trampoline *bpf_trampoline_get(u64 key, 646 646 struct bpf_attach_target_info *tgt_info); 647 647 void bpf_trampoline_put(struct bpf_trampoline *tr); ··· 688 688 void bpf_ksym_add(struct bpf_ksym *ksym); 689 689 void bpf_ksym_del(struct bpf_ksym *ksym); 690 690 #else 691 - static inline int bpf_trampoline_link_prog(struct bpf_prog *prog) 691 + static inline int bpf_trampoline_link_prog(struct bpf_prog *prog, 692 + struct bpf_trampoline *tr) 692 693 { 693 694 return -ENOTSUPP; 694 695 } 695 - static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog) 696 + static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog, 697 + struct bpf_trampoline *tr) 696 698 { 697 699 return -ENOTSUPP; 698 700 } ··· 765 763 u32 max_rdonly_access; 766 764 u32 max_rdwr_access; 767 765 const struct bpf_ctx_arg_aux *ctx_arg_info; 768 - struct bpf_prog *linked_prog; 766 + struct mutex dst_mutex; /* protects dst_* pointers below, *after* prog becomes visible */ 767 + struct bpf_prog *dst_prog; 768 + struct bpf_trampoline *dst_trampoline; 769 + enum bpf_prog_type saved_dst_prog_type; 770 + enum bpf_attach_type saved_dst_attach_type; 769 771 bool verifier_zext; /* Zero extensions has been inserted by verifier. */ 770 772 bool offload_requested; 771 773 bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */ ··· 777 771 bool sleepable; 778 772 bool tail_call_reachable; 779 773 enum bpf_tramp_prog_type trampoline_prog_type; 780 - struct bpf_trampoline *trampoline; 781 774 struct hlist_node tramp_hlist; 782 775 /* BTF_KIND_FUNC_PROTO for valid attach_btf_id */ 783 776 const struct btf_type *attach_func_proto;
+7 -2
include/uapi/linux/bpf.h
··· 639 639 }; 640 640 __u32 attach_type; /* attach type */ 641 641 __u32 flags; /* extra flags */ 642 - __aligned_u64 iter_info; /* extra bpf_iter_link_info */ 643 - __u32 iter_info_len; /* iter_info length */ 642 + union { 643 + __u32 target_btf_id; /* btf_id of target to attach to */ 644 + struct { 645 + __aligned_u64 iter_info; /* extra bpf_iter_link_info */ 646 + __u32 iter_info_len; /* iter_info length */ 647 + }; 648 + }; 644 649 } link_create; 645 650 646 651 struct { /* struct used by BPF_LINK_UPDATE command */
+11 -4
kernel/bpf/btf.c
··· 4428 4428 4429 4429 struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog) 4430 4430 { 4431 - struct bpf_prog *tgt_prog = prog->aux->linked_prog; 4431 + struct bpf_prog *tgt_prog = prog->aux->dst_prog; 4432 4432 4433 4433 if (tgt_prog) { 4434 4434 return tgt_prog->aux->btf; ··· 4455 4455 struct bpf_insn_access_aux *info) 4456 4456 { 4457 4457 const struct btf_type *t = prog->aux->attach_func_proto; 4458 - struct bpf_prog *tgt_prog = prog->aux->linked_prog; 4458 + struct bpf_prog *tgt_prog = prog->aux->dst_prog; 4459 4459 struct btf *btf = bpf_prog_get_target_btf(prog); 4460 4460 const char *tname = prog->aux->attach_func_name; 4461 4461 struct bpf_verifier_log *log = info->log; ··· 4582 4582 4583 4583 info->reg_type = PTR_TO_BTF_ID; 4584 4584 if (tgt_prog) { 4585 - ret = btf_translate_to_vmlinux(log, btf, t, tgt_prog->type, arg); 4585 + enum bpf_prog_type tgt_type; 4586 + 4587 + if (tgt_prog->type == BPF_PROG_TYPE_EXT) 4588 + tgt_type = tgt_prog->aux->saved_dst_prog_type; 4589 + else 4590 + tgt_type = tgt_prog->type; 4591 + 4592 + ret = btf_translate_to_vmlinux(log, btf, t, tgt_type, arg); 4586 4593 if (ret > 0) { 4587 4594 info->btf_id = ret; 4588 4595 return true; ··· 5288 5281 return -EFAULT; 5289 5282 } 5290 5283 if (prog_type == BPF_PROG_TYPE_EXT) 5291 - prog_type = prog->aux->linked_prog->type; 5284 + prog_type = prog->aux->dst_prog->type; 5292 5285 5293 5286 t = btf_type_by_id(btf, t->type); 5294 5287 if (!t || !btf_type_is_func_proto(t)) {
+6 -3
kernel/bpf/core.c
··· 99 99 100 100 INIT_LIST_HEAD_RCU(&fp->aux->ksym.lnode); 101 101 mutex_init(&fp->aux->used_maps_mutex); 102 + mutex_init(&fp->aux->dst_mutex); 102 103 103 104 return fp; 104 105 } ··· 256 255 { 257 256 if (fp->aux) { 258 257 mutex_destroy(&fp->aux->used_maps_mutex); 258 + mutex_destroy(&fp->aux->dst_mutex); 259 259 free_percpu(fp->aux->stats); 260 260 kfree(fp->aux->poke_tab); 261 261 kfree(fp->aux); ··· 2140 2138 if (aux->prog->has_callchain_buf) 2141 2139 put_callchain_buffers(); 2142 2140 #endif 2143 - bpf_trampoline_put(aux->trampoline); 2141 + if (aux->dst_trampoline) 2142 + bpf_trampoline_put(aux->dst_trampoline); 2144 2143 for (i = 0; i < aux->func_cnt; i++) 2145 2144 bpf_jit_free(aux->func[i]); 2146 2145 if (aux->func_cnt) { ··· 2157 2154 { 2158 2155 struct bpf_prog_aux *aux = fp->aux; 2159 2156 2160 - if (aux->linked_prog) 2161 - bpf_prog_put(aux->linked_prog); 2157 + if (aux->dst_prog) 2158 + bpf_prog_put(aux->dst_prog); 2162 2159 INIT_WORK(&aux->work, bpf_prog_free_deferred); 2163 2160 schedule_work(&aux->work); 2164 2161 }
+2 -2
kernel/bpf/preload/iterators/iterators.bpf.c
··· 42 42 __u32 id; 43 43 char name[16]; 44 44 const char *attach_func_name; 45 - struct bpf_prog *linked_prog; 45 + struct bpf_prog *dst_prog; 46 46 struct bpf_func_info *func_info; 47 47 struct btf *btf; 48 48 }; ··· 108 108 109 109 BPF_SEQ_PRINTF(seq, "%4u %-16s %s %s\n", aux->id, 110 110 get_name(aux->btf, aux->func_info[0].type_id, aux->name), 111 - aux->attach_func_name, aux->linked_prog->aux->name); 111 + aux->attach_func_name, aux->dst_prog->aux->name); 112 112 return 0; 113 113 } 114 114 char LICENSE[] SEC("license") = "GPL";
+223 -221
kernel/bpf/preload/iterators/iterators.skel.h
··· 47 47 { 48 48 struct iterators_bpf *obj; 49 49 50 - obj = (typeof(obj))calloc(1, sizeof(*obj)); 50 + obj = (struct iterators_bpf *)calloc(1, sizeof(*obj)); 51 51 if (!obj) 52 52 return NULL; 53 53 if (iterators_bpf__create_skeleton(obj)) ··· 105 105 { 106 106 struct bpf_object_skeleton *s; 107 107 108 - s = (typeof(s))calloc(1, sizeof(*s)); 108 + s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s)); 109 109 if (!s) 110 110 return -1; 111 111 obj->skeleton = s; ··· 117 117 /* maps */ 118 118 s->map_cnt = 1; 119 119 s->map_skel_sz = sizeof(*s->maps); 120 - s->maps = (typeof(s->maps))calloc(s->map_cnt, s->map_skel_sz); 120 + s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz); 121 121 if (!s->maps) 122 122 goto err; 123 123 ··· 128 128 /* programs */ 129 129 s->prog_cnt = 2; 130 130 s->prog_skel_sz = sizeof(*s->progs); 131 - s->progs = (typeof(s->progs))calloc(s->prog_cnt, s->prog_skel_sz); 131 + s->progs = (struct bpf_prog_skeleton *)calloc(s->prog_cnt, s->prog_skel_sz); 132 132 if (!s->progs) 133 133 goto err; 134 134 ··· 140 140 s->progs[1].prog = &obj->progs.dump_bpf_prog; 141 141 s->progs[1].link = &obj->links.dump_bpf_prog; 142 142 143 - s->data_sz = 7128; 143 + s->data_sz = 7176; 144 144 s->data = (void *)"\ 145 145 \x7f\x45\x4c\x46\x02\x01\x01\0\0\0\0\0\0\0\0\0\x01\0\xf7\0\x01\0\0\0\0\0\0\0\0\ 146 - \0\0\0\0\0\0\0\0\0\0\0\x18\x18\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0f\0\ 146 + \0\0\0\0\0\0\0\0\0\0\0\x48\x18\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\x40\0\x0f\0\ 147 147 \x0e\0\x79\x12\0\0\0\0\0\0\x79\x26\0\0\0\0\0\0\x79\x17\x08\0\0\0\0\0\x15\x07\ 148 148 \x1a\0\0\0\0\0\x79\x21\x10\0\0\0\0\0\x55\x01\x08\0\0\0\0\0\xbf\xa4\0\0\0\0\0\0\ 149 149 \x07\x04\0\0\xe8\xff\xff\xff\xbf\x61\0\0\0\0\0\0\x18\x02\0\0\0\0\0\0\0\0\0\0\0\ ··· 164 164 \x79\x86\0\0\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\xf8\xff\xff\xff\xb7\x02\0\ 165 165 \0\x08\0\0\0\x85\0\0\0\x71\0\0\0\xb7\x01\0\0\0\0\0\0\x79\xa3\xf8\xff\0\0\0\0\ 166 166 \x0f\x13\0\0\0\0\0\0\xbf\xa1\0\0\0\0\0\0\x07\x01\0\0\xf4\xff\xff\xff\xb7\x02\0\ 167 - \0\x04\0\0\0\x85\0\0\0\x04\0\0\0\xb7\x03\0\0\x04\0\0\0\x61\xa1\xf4\xff\0\0\0\0\ 167 + \0\x04\0\0\0\x85\0\0\0\x71\0\0\0\xb7\x03\0\0\x04\0\0\0\x61\xa1\xf4\xff\0\0\0\0\ 168 168 \x61\x82\x10\0\0\0\0\0\x3d\x21\x02\0\0\0\0\0\x0f\x16\0\0\0\0\0\0\xbf\x69\0\0\0\ 169 169 \0\0\0\x7b\x9a\xd8\xff\0\0\0\0\x79\x71\x18\0\0\0\0\0\x7b\x1a\xe0\xff\0\0\0\0\ 170 170 \x79\x71\x20\0\0\0\0\0\x79\x11\0\0\0\0\0\0\x0f\x31\0\0\0\0\0\0\x7b\x1a\xe8\xff\ ··· 176 176 \x73\x25\x36\x64\x0a\0\x20\x20\x69\x64\x20\x6e\x61\x6d\x65\x20\x20\x20\x20\x20\ 177 177 \x20\x20\x20\x20\x20\x20\x20\x20\x61\x74\x74\x61\x63\x68\x65\x64\x0a\0\x25\x34\ 178 178 \x75\x20\x25\x2d\x31\x36\x73\x20\x25\x73\x20\x25\x73\x0a\0\x47\x50\x4c\0\x9f\ 179 - \xeb\x01\0\x18\0\0\0\0\0\0\0\x1c\x04\0\0\x1c\x04\0\0\0\x05\0\0\0\0\0\0\0\0\0\ 179 + \xeb\x01\0\x18\0\0\0\0\0\0\0\x1c\x04\0\0\x1c\x04\0\0\x09\x05\0\0\0\0\0\0\0\0\0\ 180 180 \x02\x02\0\0\0\x01\0\0\0\x02\0\0\x04\x10\0\0\0\x13\0\0\0\x03\0\0\0\0\0\0\0\x18\ 181 181 \0\0\0\x04\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\x02\x08\0\0\0\0\0\0\0\0\0\0\x02\x0d\0\ 182 182 \0\0\0\0\0\0\x01\0\0\x0d\x06\0\0\0\x1c\0\0\0\x01\0\0\0\x20\0\0\0\0\0\0\x01\x04\ 183 - \0\0\0\x20\0\0\x01\x24\0\0\0\x01\0\0\x0c\x05\0\0\0\xa3\0\0\0\x03\0\0\x04\x18\0\ 184 - \0\0\xb1\0\0\0\x09\0\0\0\0\0\0\0\xb5\0\0\0\x0b\0\0\0\x40\0\0\0\xc0\0\0\0\x0b\0\ 185 - \0\0\x80\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\xc8\0\0\0\0\0\0\x07\0\0\0\0\xd1\0\0\ 186 - \0\0\0\0\x08\x0c\0\0\0\xd7\0\0\0\0\0\0\x01\x08\0\0\0\x40\0\0\0\x98\x01\0\0\x03\ 187 - \0\0\x04\x18\0\0\0\xa0\x01\0\0\x0e\0\0\0\0\0\0\0\xa3\x01\0\0\x11\0\0\0\x20\0\0\ 188 - \0\xa8\x01\0\0\x0e\0\0\0\xa0\0\0\0\xb4\x01\0\0\0\0\0\x08\x0f\0\0\0\xba\x01\0\0\ 189 - \0\0\0\x01\x04\0\0\0\x20\0\0\0\xc7\x01\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\x01\0\0\ 190 - \0\0\0\0\0\x03\0\0\0\0\x10\0\0\0\x12\0\0\0\x10\0\0\0\xcc\x01\0\0\0\0\0\x01\x04\ 191 - \0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x14\0\0\0\x30\x02\0\0\x02\0\0\x04\x10\0\0\0\ 192 - \x13\0\0\0\x03\0\0\0\0\0\0\0\x43\x02\0\0\x15\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\x02\ 193 - \x18\0\0\0\0\0\0\0\x01\0\0\x0d\x06\0\0\0\x1c\0\0\0\x13\0\0\0\x48\x02\0\0\x01\0\ 194 - \0\x0c\x16\0\0\0\x94\x02\0\0\x01\0\0\x04\x08\0\0\0\x9d\x02\0\0\x19\0\0\0\0\0\0\ 195 - \0\0\0\0\0\0\0\0\x02\x1a\0\0\0\xee\x02\0\0\x06\0\0\x04\x38\0\0\0\xa0\x01\0\0\ 196 - \x0e\0\0\0\0\0\0\0\xa3\x01\0\0\x11\0\0\0\x20\0\0\0\xfb\x02\0\0\x1b\0\0\0\xc0\0\ 197 - \0\0\x0c\x03\0\0\x15\0\0\0\0\x01\0\0\x18\x03\0\0\x1d\0\0\0\x40\x01\0\0\x22\x03\ 183 + \0\0\0\x20\0\0\x01\x24\0\0\0\x01\0\0\x0c\x05\0\0\0\xaf\0\0\0\x03\0\0\x04\x18\0\ 184 + \0\0\xbd\0\0\0\x09\0\0\0\0\0\0\0\xc1\0\0\0\x0b\0\0\0\x40\0\0\0\xcc\0\0\0\x0b\0\ 185 + \0\0\x80\0\0\0\0\0\0\0\0\0\0\x02\x0a\0\0\0\xd4\0\0\0\0\0\0\x07\0\0\0\0\xdd\0\0\ 186 + \0\0\0\0\x08\x0c\0\0\0\xe3\0\0\0\0\0\0\x01\x08\0\0\0\x40\0\0\0\xa4\x01\0\0\x03\ 187 + \0\0\x04\x18\0\0\0\xac\x01\0\0\x0e\0\0\0\0\0\0\0\xaf\x01\0\0\x11\0\0\0\x20\0\0\ 188 + \0\xb4\x01\0\0\x0e\0\0\0\xa0\0\0\0\xc0\x01\0\0\0\0\0\x08\x0f\0\0\0\xc6\x01\0\0\ 189 + \0\0\0\x01\x04\0\0\0\x20\0\0\0\xd3\x01\0\0\0\0\0\x01\x01\0\0\0\x08\0\0\x01\0\0\ 190 + \0\0\0\0\0\x03\0\0\0\0\x10\0\0\0\x12\0\0\0\x10\0\0\0\xd8\x01\0\0\0\0\0\x01\x04\ 191 + \0\0\0\x20\0\0\0\0\0\0\0\0\0\0\x02\x14\0\0\0\x3c\x02\0\0\x02\0\0\x04\x10\0\0\0\ 192 + \x13\0\0\0\x03\0\0\0\0\0\0\0\x4f\x02\0\0\x15\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\x02\ 193 + \x18\0\0\0\0\0\0\0\x01\0\0\x0d\x06\0\0\0\x1c\0\0\0\x13\0\0\0\x54\x02\0\0\x01\0\ 194 + \0\x0c\x16\0\0\0\xa0\x02\0\0\x01\0\0\x04\x08\0\0\0\xa9\x02\0\0\x19\0\0\0\0\0\0\ 195 + \0\0\0\0\0\0\0\0\x02\x1a\0\0\0\xfa\x02\0\0\x06\0\0\x04\x38\0\0\0\xac\x01\0\0\ 196 + \x0e\0\0\0\0\0\0\0\xaf\x01\0\0\x11\0\0\0\x20\0\0\0\x07\x03\0\0\x1b\0\0\0\xc0\0\ 197 + \0\0\x18\x03\0\0\x15\0\0\0\0\x01\0\0\x21\x03\0\0\x1d\0\0\0\x40\x01\0\0\x2b\x03\ 198 198 \0\0\x1e\0\0\0\x80\x01\0\0\0\0\0\0\0\0\0\x02\x1c\0\0\0\0\0\0\0\0\0\0\x0a\x10\0\ 199 - \0\0\0\0\0\0\0\0\0\x02\x1f\0\0\0\0\0\0\0\0\0\0\x02\x20\0\0\0\x6c\x03\0\0\x02\0\ 200 - \0\x04\x08\0\0\0\x7a\x03\0\0\x0e\0\0\0\0\0\0\0\x83\x03\0\0\x0e\0\0\0\x20\0\0\0\ 201 - \x22\x03\0\0\x03\0\0\x04\x18\0\0\0\x8d\x03\0\0\x1b\0\0\0\0\0\0\0\x95\x03\0\0\ 202 - \x21\0\0\0\x40\0\0\0\x9b\x03\0\0\x23\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\x02\x22\0\0\ 203 - \0\0\0\0\0\0\0\0\x02\x24\0\0\0\x9f\x03\0\0\x01\0\0\x04\x04\0\0\0\xaa\x03\0\0\ 204 - \x0e\0\0\0\0\0\0\0\x13\x04\0\0\x01\0\0\x04\x04\0\0\0\x1c\x04\0\0\x0e\0\0\0\0\0\ 205 - \0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1c\0\0\0\x12\0\0\0\x23\0\0\0\x92\x04\0\0\0\0\0\ 199 + \0\0\0\0\0\0\0\0\0\x02\x1f\0\0\0\0\0\0\0\0\0\0\x02\x20\0\0\0\x75\x03\0\0\x02\0\ 200 + \0\x04\x08\0\0\0\x83\x03\0\0\x0e\0\0\0\0\0\0\0\x8c\x03\0\0\x0e\0\0\0\x20\0\0\0\ 201 + \x2b\x03\0\0\x03\0\0\x04\x18\0\0\0\x96\x03\0\0\x1b\0\0\0\0\0\0\0\x9e\x03\0\0\ 202 + \x21\0\0\0\x40\0\0\0\xa4\x03\0\0\x23\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\x02\x22\0\0\ 203 + \0\0\0\0\0\0\0\0\x02\x24\0\0\0\xa8\x03\0\0\x01\0\0\x04\x04\0\0\0\xb3\x03\0\0\ 204 + \x0e\0\0\0\0\0\0\0\x1c\x04\0\0\x01\0\0\x04\x04\0\0\0\x25\x04\0\0\x0e\0\0\0\0\0\ 205 + \0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1c\0\0\0\x12\0\0\0\x23\0\0\0\x9b\x04\0\0\0\0\0\ 206 206 \x0e\x25\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1c\0\0\0\x12\0\0\0\x0e\0\0\0\ 207 - \xa6\x04\0\0\0\0\0\x0e\x27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1c\0\0\0\ 208 - \x12\0\0\0\x20\0\0\0\xbc\x04\0\0\0\0\0\x0e\x29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\ 209 - \0\0\0\0\x1c\0\0\0\x12\0\0\0\x11\0\0\0\xd1\x04\0\0\0\0\0\x0e\x2b\0\0\0\0\0\0\0\ 210 - \0\0\0\0\0\0\0\x03\0\0\0\0\x10\0\0\0\x12\0\0\0\x04\0\0\0\xe8\x04\0\0\0\0\0\x0e\ 211 - \x2d\0\0\0\x01\0\0\0\xf0\x04\0\0\x04\0\0\x0f\0\0\0\0\x26\0\0\0\0\0\0\0\x23\0\0\ 207 + \xaf\x04\0\0\0\0\0\x0e\x27\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\0\0\0\x1c\0\0\0\ 208 + \x12\0\0\0\x20\0\0\0\xc5\x04\0\0\0\0\0\x0e\x29\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\ 209 + \0\0\0\0\x1c\0\0\0\x12\0\0\0\x11\0\0\0\xda\x04\0\0\0\0\0\x0e\x2b\0\0\0\0\0\0\0\ 210 + \0\0\0\0\0\0\0\x03\0\0\0\0\x10\0\0\0\x12\0\0\0\x04\0\0\0\xf1\x04\0\0\0\0\0\x0e\ 211 + \x2d\0\0\0\x01\0\0\0\xf9\x04\0\0\x04\0\0\x0f\0\0\0\0\x26\0\0\0\0\0\0\0\x23\0\0\ 212 212 \0\x28\0\0\0\x23\0\0\0\x0e\0\0\0\x2a\0\0\0\x31\0\0\0\x20\0\0\0\x2c\0\0\0\x51\0\ 213 - \0\0\x11\0\0\0\xf8\x04\0\0\x01\0\0\x0f\0\0\0\0\x2e\0\0\0\0\0\0\0\x04\0\0\0\0\ 213 + \0\0\x11\0\0\0\x01\x05\0\0\x01\0\0\x0f\0\0\0\0\x2e\0\0\0\0\0\0\0\x04\0\0\0\0\ 214 214 \x62\x70\x66\x5f\x69\x74\x65\x72\x5f\x5f\x62\x70\x66\x5f\x6d\x61\x70\0\x6d\x65\ 215 215 \x74\x61\0\x6d\x61\x70\0\x63\x74\x78\0\x69\x6e\x74\0\x64\x75\x6d\x70\x5f\x62\ 216 216 \x70\x66\x5f\x6d\x61\x70\0\x69\x74\x65\x72\x2f\x62\x70\x66\x5f\x6d\x61\x70\0\ 217 - \x30\x3a\x30\0\x2f\x77\x2f\x6e\x65\x74\x2d\x6e\x65\x78\x74\x2f\x6b\x65\x72\x6e\ 218 - \x65\x6c\x2f\x62\x70\x66\x2f\x70\x72\x65\x6c\x6f\x61\x64\x2f\x69\x74\x65\x72\ 219 - \x61\x74\x6f\x72\x73\x2f\x69\x74\x65\x72\x61\x74\x6f\x72\x73\x2e\x62\x70\x66\ 220 - \x2e\x63\0\x09\x73\x74\x72\x75\x63\x74\x20\x73\x65\x71\x5f\x66\x69\x6c\x65\x20\ 221 - \x2a\x73\x65\x71\x20\x3d\x20\x63\x74\x78\x2d\x3e\x6d\x65\x74\x61\x2d\x3e\x73\ 222 - \x65\x71\x3b\0\x62\x70\x66\x5f\x69\x74\x65\x72\x5f\x6d\x65\x74\x61\0\x73\x65\ 223 - \x71\0\x73\x65\x73\x73\x69\x6f\x6e\x5f\x69\x64\0\x73\x65\x71\x5f\x6e\x75\x6d\0\ 224 - \x73\x65\x71\x5f\x66\x69\x6c\x65\0\x5f\x5f\x75\x36\x34\0\x6c\x6f\x6e\x67\x20\ 225 - \x6c\x6f\x6e\x67\x20\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x30\x3a\ 226 - \x31\0\x09\x73\x74\x72\x75\x63\x74\x20\x62\x70\x66\x5f\x6d\x61\x70\x20\x2a\x6d\ 227 - \x61\x70\x20\x3d\x20\x63\x74\x78\x2d\x3e\x6d\x61\x70\x3b\0\x09\x69\x66\x20\x28\ 228 - \x21\x6d\x61\x70\x29\0\x30\x3a\x32\0\x09\x5f\x5f\x75\x36\x34\x20\x73\x65\x71\ 229 - \x5f\x6e\x75\x6d\x20\x3d\x20\x63\x74\x78\x2d\x3e\x6d\x65\x74\x61\x2d\x3e\x73\ 230 - \x65\x71\x5f\x6e\x75\x6d\x3b\0\x09\x69\x66\x20\x28\x73\x65\x71\x5f\x6e\x75\x6d\ 231 - \x20\x3d\x3d\x20\x30\x29\0\x09\x09\x42\x50\x46\x5f\x53\x45\x51\x5f\x50\x52\x49\ 232 - \x4e\x54\x46\x28\x73\x65\x71\x2c\x20\x22\x20\x20\x69\x64\x20\x6e\x61\x6d\x65\ 233 - \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x6d\x61\x78\x5f\x65\x6e\ 234 - \x74\x72\x69\x65\x73\x5c\x6e\x22\x29\x3b\0\x62\x70\x66\x5f\x6d\x61\x70\0\x69\ 235 - \x64\0\x6e\x61\x6d\x65\0\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\0\x5f\x5f\ 236 - \x75\x33\x32\0\x75\x6e\x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x63\x68\x61\ 237 - \x72\0\x5f\x5f\x41\x52\x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\ 238 - \x5f\0\x09\x42\x50\x46\x5f\x53\x45\x51\x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\ 239 - \x71\x2c\x20\x22\x25\x34\x75\x20\x25\x2d\x31\x36\x73\x25\x36\x64\x5c\x6e\x22\ 240 - \x2c\x20\x6d\x61\x70\x2d\x3e\x69\x64\x2c\x20\x6d\x61\x70\x2d\x3e\x6e\x61\x6d\ 241 - \x65\x2c\x20\x6d\x61\x70\x2d\x3e\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\ 242 - \x29\x3b\0\x7d\0\x62\x70\x66\x5f\x69\x74\x65\x72\x5f\x5f\x62\x70\x66\x5f\x70\ 243 - \x72\x6f\x67\0\x70\x72\x6f\x67\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\ 244 - \x6f\x67\0\x69\x74\x65\x72\x2f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x09\x73\x74\ 245 - \x72\x75\x63\x74\x20\x62\x70\x66\x5f\x70\x72\x6f\x67\x20\x2a\x70\x72\x6f\x67\ 246 - \x20\x3d\x20\x63\x74\x78\x2d\x3e\x70\x72\x6f\x67\x3b\0\x09\x69\x66\x20\x28\x21\ 247 - \x70\x72\x6f\x67\x29\0\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x61\x75\x78\0\x09\x61\ 248 - \x75\x78\x20\x3d\x20\x70\x72\x6f\x67\x2d\x3e\x61\x75\x78\x3b\0\x09\x09\x42\x50\ 249 - \x46\x5f\x53\x45\x51\x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\x71\x2c\x20\x22\ 250 - \x20\x20\x69\x64\x20\x6e\x61\x6d\x65\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\ 251 - \x20\x20\x20\x61\x74\x74\x61\x63\x68\x65\x64\x5c\x6e\x22\x29\x3b\0\x62\x70\x66\ 252 - \x5f\x70\x72\x6f\x67\x5f\x61\x75\x78\0\x61\x74\x74\x61\x63\x68\x5f\x66\x75\x6e\ 253 - \x63\x5f\x6e\x61\x6d\x65\0\x6c\x69\x6e\x6b\x65\x64\x5f\x70\x72\x6f\x67\0\x66\ 254 - \x75\x6e\x63\x5f\x69\x6e\x66\x6f\0\x62\x74\x66\0\x09\x42\x50\x46\x5f\x53\x45\ 255 - \x51\x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\x71\x2c\x20\x22\x25\x34\x75\x20\ 256 - \x25\x2d\x31\x36\x73\x20\x25\x73\x20\x25\x73\x5c\x6e\x22\x2c\x20\x61\x75\x78\ 257 - \x2d\x3e\x69\x64\x2c\0\x30\x3a\x34\0\x30\x3a\x35\0\x09\x69\x66\x20\x28\x21\x62\ 258 - \x74\x66\x29\0\x62\x70\x66\x5f\x66\x75\x6e\x63\x5f\x69\x6e\x66\x6f\0\x69\x6e\ 259 - \x73\x6e\x5f\x6f\x66\x66\0\x74\x79\x70\x65\x5f\x69\x64\0\x30\0\x73\x74\x72\x69\ 260 - \x6e\x67\x73\0\x74\x79\x70\x65\x73\0\x68\x64\x72\0\x62\x74\x66\x5f\x68\x65\x61\ 261 - \x64\x65\x72\0\x73\x74\x72\x5f\x6c\x65\x6e\0\x09\x74\x79\x70\x65\x73\x20\x3d\ 262 - \x20\x62\x74\x66\x2d\x3e\x74\x79\x70\x65\x73\x3b\0\x09\x62\x70\x66\x5f\x70\x72\ 263 - \x6f\x62\x65\x5f\x72\x65\x61\x64\x5f\x6b\x65\x72\x6e\x65\x6c\x28\x26\x74\x2c\ 264 - \x20\x73\x69\x7a\x65\x6f\x66\x28\x74\x29\x2c\x20\x74\x79\x70\x65\x73\x20\x2b\ 265 - \x20\x62\x74\x66\x5f\x69\x64\x29\x3b\0\x09\x73\x74\x72\x20\x3d\x20\x62\x74\x66\ 266 - \x2d\x3e\x73\x74\x72\x69\x6e\x67\x73\x3b\0\x62\x74\x66\x5f\x74\x79\x70\x65\0\ 267 - \x6e\x61\x6d\x65\x5f\x6f\x66\x66\0\x09\x6e\x61\x6d\x65\x5f\x6f\x66\x66\x20\x3d\ 268 - \x20\x42\x50\x46\x5f\x43\x4f\x52\x45\x5f\x52\x45\x41\x44\x28\x74\x2c\x20\x6e\ 269 - \x61\x6d\x65\x5f\x6f\x66\x66\x29\x3b\0\x30\x3a\x32\x3a\x30\0\x09\x69\x66\x20\ 270 - \x28\x6e\x61\x6d\x65\x5f\x6f\x66\x66\x20\x3e\x3d\x20\x62\x74\x66\x2d\x3e\x68\ 271 - \x64\x72\x2e\x73\x74\x72\x5f\x6c\x65\x6e\x29\0\x09\x72\x65\x74\x75\x72\x6e\x20\ 272 - \x73\x74\x72\x20\x2b\x20\x6e\x61\x6d\x65\x5f\x6f\x66\x66\x3b\0\x30\x3a\x33\0\ 273 - \x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\0\ 274 - \x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\ 275 - \x2e\x31\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\x2e\x5f\x5f\x5f\ 276 - \x66\x6d\x74\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\x2e\x5f\x5f\ 277 - \x5f\x66\x6d\x74\x2e\x32\0\x4c\x49\x43\x45\x4e\x53\x45\0\x2e\x72\x6f\x64\x61\ 278 - \x74\x61\0\x6c\x69\x63\x65\x6e\x73\x65\0\x9f\xeb\x01\0\x20\0\0\0\0\0\0\0\x24\0\ 279 - \0\0\x24\0\0\0\x44\x02\0\0\x68\x02\0\0\xa4\x01\0\0\x08\0\0\0\x31\0\0\0\x01\0\0\ 280 - \0\0\0\0\0\x07\0\0\0\x56\x02\0\0\x01\0\0\0\0\0\0\0\x17\0\0\0\x10\0\0\0\x31\0\0\ 281 - \0\x09\0\0\0\0\0\0\0\x42\0\0\0\x7b\0\0\0\x1e\x40\x01\0\x08\0\0\0\x42\0\0\0\x7b\ 282 - \0\0\0\x24\x40\x01\0\x10\0\0\0\x42\0\0\0\xf2\0\0\0\x1d\x48\x01\0\x18\0\0\0\x42\ 283 - \0\0\0\x13\x01\0\0\x06\x50\x01\0\x20\0\0\0\x42\0\0\0\x22\x01\0\0\x1d\x44\x01\0\ 284 - \x28\0\0\0\x42\0\0\0\x47\x01\0\0\x06\x5c\x01\0\x38\0\0\0\x42\0\0\0\x5a\x01\0\0\ 285 - \x03\x60\x01\0\x70\0\0\0\x42\0\0\0\xe0\x01\0\0\x02\x68\x01\0\xf0\0\0\0\x42\0\0\ 286 - \0\x2e\x02\0\0\x01\x70\x01\0\x56\x02\0\0\x1a\0\0\0\0\0\0\0\x42\0\0\0\x7b\0\0\0\ 287 - \x1e\x84\x01\0\x08\0\0\0\x42\0\0\0\x7b\0\0\0\x24\x84\x01\0\x10\0\0\0\x42\0\0\0\ 288 - \x64\x02\0\0\x1f\x8c\x01\0\x18\0\0\0\x42\0\0\0\x88\x02\0\0\x06\x98\x01\0\x20\0\ 289 - \0\0\x42\0\0\0\xa1\x02\0\0\x0e\xa4\x01\0\x28\0\0\0\x42\0\0\0\x22\x01\0\0\x1d\ 290 - \x88\x01\0\x30\0\0\0\x42\0\0\0\x47\x01\0\0\x06\xa8\x01\0\x40\0\0\0\x42\0\0\0\ 291 - \xb3\x02\0\0\x03\xac\x01\0\x80\0\0\0\x42\0\0\0\x26\x03\0\0\x02\xb4\x01\0\xb8\0\ 292 - \0\0\x42\0\0\0\x61\x03\0\0\x06\x08\x01\0\xd0\0\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\ 293 - \xd8\0\0\0\x42\0\0\0\xb2\x03\0\0\x0f\x14\x01\0\xe0\0\0\0\x42\0\0\0\xc7\x03\0\0\ 294 - \x2d\x18\x01\0\xf0\0\0\0\x42\0\0\0\xfe\x03\0\0\x0d\x10\x01\0\0\x01\0\0\x42\0\0\ 295 - \0\0\0\0\0\0\0\0\0\x08\x01\0\0\x42\0\0\0\xc7\x03\0\0\x02\x18\x01\0\x20\x01\0\0\ 296 - \x42\0\0\0\x25\x04\0\0\x0d\x1c\x01\0\x38\x01\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\x40\ 297 - \x01\0\0\x42\0\0\0\x25\x04\0\0\x0d\x1c\x01\0\x58\x01\0\0\x42\0\0\0\x25\x04\0\0\ 298 - \x0d\x1c\x01\0\x60\x01\0\0\x42\0\0\0\x53\x04\0\0\x1b\x20\x01\0\x68\x01\0\0\x42\ 299 - \0\0\0\x53\x04\0\0\x06\x20\x01\0\x70\x01\0\0\x42\0\0\0\x76\x04\0\0\x0d\x28\x01\ 300 - \0\x78\x01\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\x80\x01\0\0\x42\0\0\0\x26\x03\0\0\x02\ 301 - \xb4\x01\0\xf8\x01\0\0\x42\0\0\0\x2e\x02\0\0\x01\xc4\x01\0\x10\0\0\0\x31\0\0\0\ 302 - \x07\0\0\0\0\0\0\0\x02\0\0\0\x3e\0\0\0\0\0\0\0\x08\0\0\0\x08\0\0\0\x3e\0\0\0\0\ 303 - \0\0\0\x10\0\0\0\x02\0\0\0\xee\0\0\0\0\0\0\0\x20\0\0\0\x08\0\0\0\x1e\x01\0\0\0\ 304 - \0\0\0\x70\0\0\0\x0d\0\0\0\x3e\0\0\0\0\0\0\0\x80\0\0\0\x0d\0\0\0\xee\0\0\0\0\0\ 305 - \0\0\xa0\0\0\0\x0d\0\0\0\x1e\x01\0\0\0\0\0\0\x56\x02\0\0\x12\0\0\0\0\0\0\0\x14\ 306 - \0\0\0\x3e\0\0\0\0\0\0\0\x08\0\0\0\x08\0\0\0\x3e\0\0\0\0\0\0\0\x10\0\0\0\x14\0\ 307 - \0\0\xee\0\0\0\0\0\0\0\x20\0\0\0\x18\0\0\0\x3e\0\0\0\0\0\0\0\x28\0\0\0\x08\0\0\ 308 - \0\x1e\x01\0\0\0\0\0\0\x80\0\0\0\x1a\0\0\0\x3e\0\0\0\0\0\0\0\x90\0\0\0\x1a\0\0\ 309 - \0\xee\0\0\0\0\0\0\0\xa8\0\0\0\x1a\0\0\0\x59\x03\0\0\0\0\0\0\xb0\0\0\0\x1a\0\0\ 310 - \0\x5d\x03\0\0\0\0\0\0\xc0\0\0\0\x1f\0\0\0\x8b\x03\0\0\0\0\0\0\xd8\0\0\0\x20\0\ 311 - \0\0\xee\0\0\0\0\0\0\0\xf0\0\0\0\x20\0\0\0\x3e\0\0\0\0\0\0\0\x18\x01\0\0\x24\0\ 312 - \0\0\x3e\0\0\0\0\0\0\0\x50\x01\0\0\x1a\0\0\0\xee\0\0\0\0\0\0\0\x60\x01\0\0\x20\ 313 - \0\0\0\x4d\x04\0\0\0\0\0\0\x88\x01\0\0\x1a\0\0\0\x1e\x01\0\0\0\0\0\0\x98\x01\0\ 314 - \0\x1a\0\0\0\x8e\x04\0\0\0\0\0\0\xa0\x01\0\0\x18\0\0\0\x3e\0\0\0\0\0\0\0\0\0\0\ 315 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd6\0\0\0\0\0\x02\0\x70\0\0\0\0\ 316 - \0\0\0\0\0\0\0\0\0\0\0\xc8\0\0\0\0\0\x02\0\xf0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 317 - \xcf\0\0\0\0\0\x03\0\x78\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc1\0\0\0\0\0\x03\0\x80\ 318 - \x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xba\0\0\0\0\0\x03\0\xf8\x01\0\0\0\0\0\0\0\0\0\ 319 - \0\0\0\0\0\x14\0\0\0\x01\0\x04\0\0\0\0\0\0\0\0\0\x23\0\0\0\0\0\0\0\xf4\0\0\0\ 320 - \x01\0\x04\0\x23\0\0\0\0\0\0\0\x0e\0\0\0\0\0\0\0\x28\0\0\0\x01\0\x04\0\x31\0\0\ 321 - \0\0\0\0\0\x20\0\0\0\0\0\0\0\xdd\0\0\0\x01\0\x04\0\x51\0\0\0\0\0\0\0\x11\0\0\0\ 322 - \0\0\0\0\0\0\0\0\x03\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x03\ 323 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\ 324 - \0\0\0\0\xb2\0\0\0\x11\0\x05\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\x3d\0\0\0\x12\ 325 - \0\x02\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\x5b\0\0\0\x12\0\x03\0\0\0\0\0\0\0\0\ 326 - \0\x08\x02\0\0\0\0\0\0\x48\0\0\0\0\0\0\0\x01\0\0\0\x0c\0\0\0\xc8\0\0\0\0\0\0\0\ 327 - \x01\0\0\0\x0c\0\0\0\x50\0\0\0\0\0\0\0\x01\0\0\0\x0c\0\0\0\xd0\x01\0\0\0\0\0\0\ 328 - \x01\0\0\0\x0c\0\0\0\xf0\x03\0\0\0\0\0\0\x0a\0\0\0\x0c\0\0\0\xfc\x03\0\0\0\0\0\ 329 - \0\x0a\0\0\0\x0c\0\0\0\x08\x04\0\0\0\0\0\0\x0a\0\0\0\x0c\0\0\0\x14\x04\0\0\0\0\ 330 - \0\0\x0a\0\0\0\x0c\0\0\0\x2c\x04\0\0\0\0\0\0\0\0\0\0\x0d\0\0\0\x2c\0\0\0\0\0\0\ 331 - \0\0\0\0\0\x0a\0\0\0\x3c\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x50\0\0\0\0\0\0\0\0\0\ 332 - \0\0\x0a\0\0\0\x60\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\x70\0\0\0\0\0\0\0\0\0\0\0\ 333 - \x0a\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\x90\0\0\0\0\0\0\0\0\0\0\0\x0a\0\ 334 - \0\0\xa0\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xb0\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\ 335 - \xc0\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xd0\0\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xe8\0\ 336 - \0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xf8\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x08\x01\0\0\ 337 - \0\0\0\0\0\0\0\0\x0b\0\0\0\x18\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x28\x01\0\0\0\ 338 - \0\0\0\0\0\0\0\x0b\0\0\0\x38\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x48\x01\0\0\0\0\ 339 - \0\0\0\0\0\0\x0b\0\0\0\x58\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x68\x01\0\0\0\0\0\ 340 - \0\0\0\0\0\x0b\0\0\0\x78\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x88\x01\0\0\0\0\0\0\ 341 - \0\0\0\0\x0b\0\0\0\x98\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xa8\x01\0\0\0\0\0\0\0\ 342 - \0\0\0\x0b\0\0\0\xb8\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xc8\x01\0\0\0\0\0\0\0\0\ 343 - \0\0\x0b\0\0\0\xd8\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xe8\x01\0\0\0\0\0\0\0\0\0\ 344 - \0\x0b\0\0\0\xf8\x01\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x08\x02\0\0\0\0\0\0\0\0\0\0\ 345 - \x0b\0\0\0\x18\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x28\x02\0\0\0\0\0\0\0\0\0\0\ 346 - \x0b\0\0\0\x38\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x48\x02\0\0\0\0\0\0\0\0\0\0\ 347 - \x0b\0\0\0\x58\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x68\x02\0\0\0\0\0\0\0\0\0\0\ 348 - \x0b\0\0\0\x78\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x94\x02\0\0\0\0\0\0\0\0\0\0\ 349 - \x0a\0\0\0\xa4\x02\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xb4\x02\0\0\0\0\0\0\0\0\0\0\ 350 - \x0a\0\0\0\xc4\x02\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xd4\x02\0\0\0\0\0\0\0\0\0\0\ 351 - \x0a\0\0\0\xe4\x02\0\0\0\0\0\0\0\0\0\0\x0a\0\0\0\xf4\x02\0\0\0\0\0\0\0\0\0\0\ 352 - \x0a\0\0\0\x0c\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x1c\x03\0\0\0\0\0\0\0\0\0\0\ 353 - \x0b\0\0\0\x2c\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x3c\x03\0\0\0\0\0\0\0\0\0\0\ 354 - \x0b\0\0\0\x4c\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x5c\x03\0\0\0\0\0\0\0\0\0\0\ 355 - \x0b\0\0\0\x6c\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x7c\x03\0\0\0\0\0\0\0\0\0\0\ 356 - \x0b\0\0\0\x8c\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x9c\x03\0\0\0\0\0\0\0\0\0\0\ 357 - \x0b\0\0\0\xac\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xbc\x03\0\0\0\0\0\0\0\0\0\0\ 358 - \x0b\0\0\0\xcc\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xdc\x03\0\0\0\0\0\0\0\0\0\0\ 359 - \x0b\0\0\0\xec\x03\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xfc\x03\0\0\0\0\0\0\0\0\0\0\ 360 - \x0b\0\0\0\x0c\x04\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x1c\x04\0\0\0\0\0\0\0\0\0\0\ 361 - \x0b\0\0\0\x4e\x4f\x41\x42\x43\x44\x4d\0\x2e\x74\x65\x78\x74\0\x2e\x72\x65\x6c\ 362 - \x2e\x42\x54\x46\x2e\x65\x78\x74\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\x61\ 363 - \x70\x2e\x5f\x5f\x5f\x66\x6d\x74\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\ 364 - \x6f\x67\x2e\x5f\x5f\x5f\x66\x6d\x74\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\ 365 - \x61\x70\0\x2e\x72\x65\x6c\x69\x74\x65\x72\x2f\x62\x70\x66\x5f\x6d\x61\x70\0\ 366 - \x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x2e\x72\x65\x6c\x69\x74\ 367 - \x65\x72\x2f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\ 368 - \x64\x72\x73\x69\x67\0\x6c\x69\x63\x65\x6e\x73\x65\0\x2e\x73\x74\x72\x74\x61\ 369 - \x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\x72\x6f\x64\x61\x74\x61\0\x2e\x72\x65\ 370 - \x6c\x2e\x42\x54\x46\0\x4c\x49\x43\x45\x4e\x53\x45\0\x4c\x42\x42\x31\x5f\x37\0\ 371 - \x4c\x42\x42\x31\x5f\x36\0\x4c\x42\x42\x30\x5f\x34\0\x4c\x42\x42\x31\x5f\x33\0\ 372 - \x4c\x42\x42\x30\x5f\x33\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\ 373 - \x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x32\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\ 374 - \x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 217 + \x30\x3a\x30\0\x2f\x68\x6f\x6d\x65\x2f\x61\x6c\x72\x75\x61\x2f\x62\x75\x69\x6c\ 218 + \x64\x2f\x6c\x69\x6e\x75\x78\x2f\x6b\x65\x72\x6e\x65\x6c\x2f\x62\x70\x66\x2f\ 219 + \x70\x72\x65\x6c\x6f\x61\x64\x2f\x69\x74\x65\x72\x61\x74\x6f\x72\x73\x2f\x69\ 220 + \x74\x65\x72\x61\x74\x6f\x72\x73\x2e\x62\x70\x66\x2e\x63\0\x09\x73\x74\x72\x75\ 221 + \x63\x74\x20\x73\x65\x71\x5f\x66\x69\x6c\x65\x20\x2a\x73\x65\x71\x20\x3d\x20\ 222 + \x63\x74\x78\x2d\x3e\x6d\x65\x74\x61\x2d\x3e\x73\x65\x71\x3b\0\x62\x70\x66\x5f\ 223 + \x69\x74\x65\x72\x5f\x6d\x65\x74\x61\0\x73\x65\x71\0\x73\x65\x73\x73\x69\x6f\ 224 + \x6e\x5f\x69\x64\0\x73\x65\x71\x5f\x6e\x75\x6d\0\x73\x65\x71\x5f\x66\x69\x6c\ 225 + \x65\0\x5f\x5f\x75\x36\x34\0\x6c\x6f\x6e\x67\x20\x6c\x6f\x6e\x67\x20\x75\x6e\ 226 + \x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x30\x3a\x31\0\x09\x73\x74\x72\x75\ 227 + \x63\x74\x20\x62\x70\x66\x5f\x6d\x61\x70\x20\x2a\x6d\x61\x70\x20\x3d\x20\x63\ 228 + \x74\x78\x2d\x3e\x6d\x61\x70\x3b\0\x09\x69\x66\x20\x28\x21\x6d\x61\x70\x29\0\ 229 + \x30\x3a\x32\0\x09\x5f\x5f\x75\x36\x34\x20\x73\x65\x71\x5f\x6e\x75\x6d\x20\x3d\ 230 + \x20\x63\x74\x78\x2d\x3e\x6d\x65\x74\x61\x2d\x3e\x73\x65\x71\x5f\x6e\x75\x6d\ 231 + \x3b\0\x09\x69\x66\x20\x28\x73\x65\x71\x5f\x6e\x75\x6d\x20\x3d\x3d\x20\x30\x29\ 232 + \0\x09\x09\x42\x50\x46\x5f\x53\x45\x51\x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\ 233 + \x71\x2c\x20\x22\x20\x20\x69\x64\x20\x6e\x61\x6d\x65\x20\x20\x20\x20\x20\x20\ 234 + \x20\x20\x20\x20\x20\x20\x20\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x5c\ 235 + \x6e\x22\x29\x3b\0\x62\x70\x66\x5f\x6d\x61\x70\0\x69\x64\0\x6e\x61\x6d\x65\0\ 236 + \x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\0\x5f\x5f\x75\x33\x32\0\x75\x6e\ 237 + \x73\x69\x67\x6e\x65\x64\x20\x69\x6e\x74\0\x63\x68\x61\x72\0\x5f\x5f\x41\x52\ 238 + \x52\x41\x59\x5f\x53\x49\x5a\x45\x5f\x54\x59\x50\x45\x5f\x5f\0\x09\x42\x50\x46\ 239 + \x5f\x53\x45\x51\x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\x71\x2c\x20\x22\x25\ 240 + \x34\x75\x20\x25\x2d\x31\x36\x73\x25\x36\x64\x5c\x6e\x22\x2c\x20\x6d\x61\x70\ 241 + \x2d\x3e\x69\x64\x2c\x20\x6d\x61\x70\x2d\x3e\x6e\x61\x6d\x65\x2c\x20\x6d\x61\ 242 + \x70\x2d\x3e\x6d\x61\x78\x5f\x65\x6e\x74\x72\x69\x65\x73\x29\x3b\0\x7d\0\x62\ 243 + \x70\x66\x5f\x69\x74\x65\x72\x5f\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x70\x72\ 244 + \x6f\x67\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x69\x74\x65\ 245 + \x72\x2f\x62\x70\x66\x5f\x70\x72\x6f\x67\0\x09\x73\x74\x72\x75\x63\x74\x20\x62\ 246 + \x70\x66\x5f\x70\x72\x6f\x67\x20\x2a\x70\x72\x6f\x67\x20\x3d\x20\x63\x74\x78\ 247 + \x2d\x3e\x70\x72\x6f\x67\x3b\0\x09\x69\x66\x20\x28\x21\x70\x72\x6f\x67\x29\0\ 248 + \x62\x70\x66\x5f\x70\x72\x6f\x67\0\x61\x75\x78\0\x09\x61\x75\x78\x20\x3d\x20\ 249 + \x70\x72\x6f\x67\x2d\x3e\x61\x75\x78\x3b\0\x09\x09\x42\x50\x46\x5f\x53\x45\x51\ 250 + \x5f\x50\x52\x49\x4e\x54\x46\x28\x73\x65\x71\x2c\x20\x22\x20\x20\x69\x64\x20\ 251 + \x6e\x61\x6d\x65\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x61\x74\ 252 + \x74\x61\x63\x68\x65\x64\x5c\x6e\x22\x29\x3b\0\x62\x70\x66\x5f\x70\x72\x6f\x67\ 253 + \x5f\x61\x75\x78\0\x61\x74\x74\x61\x63\x68\x5f\x66\x75\x6e\x63\x5f\x6e\x61\x6d\ 254 + \x65\0\x64\x73\x74\x5f\x70\x72\x6f\x67\0\x66\x75\x6e\x63\x5f\x69\x6e\x66\x6f\0\ 255 + \x62\x74\x66\0\x09\x42\x50\x46\x5f\x53\x45\x51\x5f\x50\x52\x49\x4e\x54\x46\x28\ 256 + \x73\x65\x71\x2c\x20\x22\x25\x34\x75\x20\x25\x2d\x31\x36\x73\x20\x25\x73\x20\ 257 + \x25\x73\x5c\x6e\x22\x2c\x20\x61\x75\x78\x2d\x3e\x69\x64\x2c\0\x30\x3a\x34\0\ 258 + \x30\x3a\x35\0\x09\x69\x66\x20\x28\x21\x62\x74\x66\x29\0\x62\x70\x66\x5f\x66\ 259 + \x75\x6e\x63\x5f\x69\x6e\x66\x6f\0\x69\x6e\x73\x6e\x5f\x6f\x66\x66\0\x74\x79\ 260 + \x70\x65\x5f\x69\x64\0\x30\0\x73\x74\x72\x69\x6e\x67\x73\0\x74\x79\x70\x65\x73\ 261 + \0\x68\x64\x72\0\x62\x74\x66\x5f\x68\x65\x61\x64\x65\x72\0\x73\x74\x72\x5f\x6c\ 262 + \x65\x6e\0\x09\x74\x79\x70\x65\x73\x20\x3d\x20\x62\x74\x66\x2d\x3e\x74\x79\x70\ 263 + \x65\x73\x3b\0\x09\x62\x70\x66\x5f\x70\x72\x6f\x62\x65\x5f\x72\x65\x61\x64\x5f\ 264 + \x6b\x65\x72\x6e\x65\x6c\x28\x26\x74\x2c\x20\x73\x69\x7a\x65\x6f\x66\x28\x74\ 265 + \x29\x2c\x20\x74\x79\x70\x65\x73\x20\x2b\x20\x62\x74\x66\x5f\x69\x64\x29\x3b\0\ 266 + \x09\x73\x74\x72\x20\x3d\x20\x62\x74\x66\x2d\x3e\x73\x74\x72\x69\x6e\x67\x73\ 267 + \x3b\0\x62\x74\x66\x5f\x74\x79\x70\x65\0\x6e\x61\x6d\x65\x5f\x6f\x66\x66\0\x09\ 268 + \x6e\x61\x6d\x65\x5f\x6f\x66\x66\x20\x3d\x20\x42\x50\x46\x5f\x43\x4f\x52\x45\ 269 + \x5f\x52\x45\x41\x44\x28\x74\x2c\x20\x6e\x61\x6d\x65\x5f\x6f\x66\x66\x29\x3b\0\ 270 + \x30\x3a\x32\x3a\x30\0\x09\x69\x66\x20\x28\x6e\x61\x6d\x65\x5f\x6f\x66\x66\x20\ 271 + \x3e\x3d\x20\x62\x74\x66\x2d\x3e\x68\x64\x72\x2e\x73\x74\x72\x5f\x6c\x65\x6e\ 272 + \x29\0\x09\x72\x65\x74\x75\x72\x6e\x20\x73\x74\x72\x20\x2b\x20\x6e\x61\x6d\x65\ 273 + \x5f\x6f\x66\x66\x3b\0\x30\x3a\x33\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\ 274 + \x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\ 275 + \x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\x64\x75\x6d\x70\x5f\x62\x70\x66\ 276 + \x5f\x70\x72\x6f\x67\x2e\x5f\x5f\x5f\x66\x6d\x74\0\x64\x75\x6d\x70\x5f\x62\x70\ 277 + \x66\x5f\x70\x72\x6f\x67\x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x32\0\x4c\x49\x43\x45\ 278 + \x4e\x53\x45\0\x2e\x72\x6f\x64\x61\x74\x61\0\x6c\x69\x63\x65\x6e\x73\x65\0\x9f\ 279 + \xeb\x01\0\x20\0\0\0\0\0\0\0\x24\0\0\0\x24\0\0\0\x44\x02\0\0\x68\x02\0\0\xa4\ 280 + \x01\0\0\x08\0\0\0\x31\0\0\0\x01\0\0\0\0\0\0\0\x07\0\0\0\x62\x02\0\0\x01\0\0\0\ 281 + \0\0\0\0\x17\0\0\0\x10\0\0\0\x31\0\0\0\x09\0\0\0\0\0\0\0\x42\0\0\0\x87\0\0\0\ 282 + \x1e\x40\x01\0\x08\0\0\0\x42\0\0\0\x87\0\0\0\x24\x40\x01\0\x10\0\0\0\x42\0\0\0\ 283 + \xfe\0\0\0\x1d\x48\x01\0\x18\0\0\0\x42\0\0\0\x1f\x01\0\0\x06\x50\x01\0\x20\0\0\ 284 + \0\x42\0\0\0\x2e\x01\0\0\x1d\x44\x01\0\x28\0\0\0\x42\0\0\0\x53\x01\0\0\x06\x5c\ 285 + \x01\0\x38\0\0\0\x42\0\0\0\x66\x01\0\0\x03\x60\x01\0\x70\0\0\0\x42\0\0\0\xec\ 286 + \x01\0\0\x02\x68\x01\0\xf0\0\0\0\x42\0\0\0\x3a\x02\0\0\x01\x70\x01\0\x62\x02\0\ 287 + \0\x1a\0\0\0\0\0\0\0\x42\0\0\0\x87\0\0\0\x1e\x84\x01\0\x08\0\0\0\x42\0\0\0\x87\ 288 + \0\0\0\x24\x84\x01\0\x10\0\0\0\x42\0\0\0\x70\x02\0\0\x1f\x8c\x01\0\x18\0\0\0\ 289 + \x42\0\0\0\x94\x02\0\0\x06\x98\x01\0\x20\0\0\0\x42\0\0\0\xad\x02\0\0\x0e\xa4\ 290 + \x01\0\x28\0\0\0\x42\0\0\0\x2e\x01\0\0\x1d\x88\x01\0\x30\0\0\0\x42\0\0\0\x53\ 291 + \x01\0\0\x06\xa8\x01\0\x40\0\0\0\x42\0\0\0\xbf\x02\0\0\x03\xac\x01\0\x80\0\0\0\ 292 + \x42\0\0\0\x2f\x03\0\0\x02\xb4\x01\0\xb8\0\0\0\x42\0\0\0\x6a\x03\0\0\x06\x08\ 293 + \x01\0\xd0\0\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\xd8\0\0\0\x42\0\0\0\xbb\x03\0\0\x0f\ 294 + \x14\x01\0\xe0\0\0\0\x42\0\0\0\xd0\x03\0\0\x2d\x18\x01\0\xf0\0\0\0\x42\0\0\0\ 295 + \x07\x04\0\0\x0d\x10\x01\0\0\x01\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\x08\x01\0\0\x42\ 296 + \0\0\0\xd0\x03\0\0\x02\x18\x01\0\x20\x01\0\0\x42\0\0\0\x2e\x04\0\0\x0d\x1c\x01\ 297 + \0\x38\x01\0\0\x42\0\0\0\0\0\0\0\0\0\0\0\x40\x01\0\0\x42\0\0\0\x2e\x04\0\0\x0d\ 298 + \x1c\x01\0\x58\x01\0\0\x42\0\0\0\x2e\x04\0\0\x0d\x1c\x01\0\x60\x01\0\0\x42\0\0\ 299 + \0\x5c\x04\0\0\x1b\x20\x01\0\x68\x01\0\0\x42\0\0\0\x5c\x04\0\0\x06\x20\x01\0\ 300 + \x70\x01\0\0\x42\0\0\0\x7f\x04\0\0\x0d\x28\x01\0\x78\x01\0\0\x42\0\0\0\0\0\0\0\ 301 + \0\0\0\0\x80\x01\0\0\x42\0\0\0\x2f\x03\0\0\x02\xb4\x01\0\xf8\x01\0\0\x42\0\0\0\ 302 + \x3a\x02\0\0\x01\xc4\x01\0\x10\0\0\0\x31\0\0\0\x07\0\0\0\0\0\0\0\x02\0\0\0\x3e\ 303 + \0\0\0\0\0\0\0\x08\0\0\0\x08\0\0\0\x3e\0\0\0\0\0\0\0\x10\0\0\0\x02\0\0\0\xfa\0\ 304 + \0\0\0\0\0\0\x20\0\0\0\x08\0\0\0\x2a\x01\0\0\0\0\0\0\x70\0\0\0\x0d\0\0\0\x3e\0\ 305 + \0\0\0\0\0\0\x80\0\0\0\x0d\0\0\0\xfa\0\0\0\0\0\0\0\xa0\0\0\0\x0d\0\0\0\x2a\x01\ 306 + \0\0\0\0\0\0\x62\x02\0\0\x12\0\0\0\0\0\0\0\x14\0\0\0\x3e\0\0\0\0\0\0\0\x08\0\0\ 307 + \0\x08\0\0\0\x3e\0\0\0\0\0\0\0\x10\0\0\0\x14\0\0\0\xfa\0\0\0\0\0\0\0\x20\0\0\0\ 308 + \x18\0\0\0\x3e\0\0\0\0\0\0\0\x28\0\0\0\x08\0\0\0\x2a\x01\0\0\0\0\0\0\x80\0\0\0\ 309 + \x1a\0\0\0\x3e\0\0\0\0\0\0\0\x90\0\0\0\x1a\0\0\0\xfa\0\0\0\0\0\0\0\xa8\0\0\0\ 310 + \x1a\0\0\0\x62\x03\0\0\0\0\0\0\xb0\0\0\0\x1a\0\0\0\x66\x03\0\0\0\0\0\0\xc0\0\0\ 311 + \0\x1f\0\0\0\x94\x03\0\0\0\0\0\0\xd8\0\0\0\x20\0\0\0\xfa\0\0\0\0\0\0\0\xf0\0\0\ 312 + \0\x20\0\0\0\x3e\0\0\0\0\0\0\0\x18\x01\0\0\x24\0\0\0\x3e\0\0\0\0\0\0\0\x50\x01\ 313 + \0\0\x1a\0\0\0\xfa\0\0\0\0\0\0\0\x60\x01\0\0\x20\0\0\0\x56\x04\0\0\0\0\0\0\x88\ 314 + \x01\0\0\x1a\0\0\0\x2a\x01\0\0\0\0\0\0\x98\x01\0\0\x1a\0\0\0\x97\x04\0\0\0\0\0\ 315 + \0\xa0\x01\0\0\x18\0\0\0\x3e\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 316 + \0\0\0\0\0\0\0\x91\0\0\0\x04\0\xf1\xff\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe6\0\0\ 317 + \0\0\0\x02\0\x70\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd8\0\0\0\0\0\x02\0\xf0\0\0\0\0\ 318 + \0\0\0\0\0\0\0\0\0\0\0\xdf\0\0\0\0\0\x03\0\x78\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 319 + \xd1\0\0\0\0\0\x03\0\x80\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xca\0\0\0\0\0\x03\0\ 320 + \xf8\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x14\0\0\0\x01\0\x04\0\0\0\0\0\0\0\0\0\x23\ 321 + \0\0\0\0\0\0\0\x04\x01\0\0\x01\0\x04\0\x23\0\0\0\0\0\0\0\x0e\0\0\0\0\0\0\0\x28\ 322 + \0\0\0\x01\0\x04\0\x31\0\0\0\0\0\0\0\x20\0\0\0\0\0\0\0\xed\0\0\0\x01\0\x04\0\ 323 + \x51\0\0\0\0\0\0\0\x11\0\0\0\0\0\0\0\0\0\0\0\x03\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\ 324 + \0\0\0\0\0\0\0\0\0\x03\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x03\0\ 325 + \x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc2\0\0\0\x11\0\x05\0\0\0\0\0\0\0\0\0\ 326 + \x04\0\0\0\0\0\0\0\x3d\0\0\0\x12\0\x02\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\x5b\ 327 + \0\0\0\x12\0\x03\0\0\0\0\0\0\0\0\0\x08\x02\0\0\0\0\0\0\x48\0\0\0\0\0\0\0\x01\0\ 328 + \0\0\x0d\0\0\0\xc8\0\0\0\0\0\0\0\x01\0\0\0\x0d\0\0\0\x50\0\0\0\0\0\0\0\x01\0\0\ 329 + \0\x0d\0\0\0\xd0\x01\0\0\0\0\0\0\x01\0\0\0\x0d\0\0\0\xf0\x03\0\0\0\0\0\0\x0a\0\ 330 + \0\0\x0d\0\0\0\xfc\x03\0\0\0\0\0\0\x0a\0\0\0\x0d\0\0\0\x08\x04\0\0\0\0\0\0\x0a\ 331 + \0\0\0\x0d\0\0\0\x14\x04\0\0\0\0\0\0\x0a\0\0\0\x0d\0\0\0\x2c\x04\0\0\0\0\0\0\0\ 332 + \0\0\0\x0e\0\0\0\x2c\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x3c\0\0\0\0\0\0\0\0\0\0\0\ 333 + \x0c\0\0\0\x50\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x60\0\0\0\0\0\0\0\0\0\0\0\x0b\0\ 334 + \0\0\x70\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\ 335 + \x90\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xa0\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xb0\0\ 336 + \0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xc0\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xd0\0\0\0\0\ 337 + \0\0\0\0\0\0\0\x0b\0\0\0\xe8\0\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xf8\0\0\0\0\0\0\0\ 338 + \0\0\0\0\x0c\0\0\0\x08\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x18\x01\0\0\0\0\0\0\0\ 339 + \0\0\0\x0c\0\0\0\x28\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x38\x01\0\0\0\0\0\0\0\0\ 340 + \0\0\x0c\0\0\0\x48\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x58\x01\0\0\0\0\0\0\0\0\0\ 341 + \0\x0c\0\0\0\x68\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x78\x01\0\0\0\0\0\0\0\0\0\0\ 342 + \x0c\0\0\0\x88\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x98\x01\0\0\0\0\0\0\0\0\0\0\ 343 + \x0c\0\0\0\xa8\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xb8\x01\0\0\0\0\0\0\0\0\0\0\ 344 + \x0c\0\0\0\xc8\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xd8\x01\0\0\0\0\0\0\0\0\0\0\ 345 + \x0c\0\0\0\xe8\x01\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xf8\x01\0\0\0\0\0\0\0\0\0\0\ 346 + \x0c\0\0\0\x08\x02\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x18\x02\0\0\0\0\0\0\0\0\0\0\ 347 + \x0c\0\0\0\x28\x02\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x38\x02\0\0\0\0\0\0\0\0\0\0\ 348 + \x0c\0\0\0\x48\x02\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x58\x02\0\0\0\0\0\0\0\0\0\0\ 349 + \x0c\0\0\0\x68\x02\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x78\x02\0\0\0\0\0\0\0\0\0\0\ 350 + \x0c\0\0\0\x94\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xa4\x02\0\0\0\0\0\0\0\0\0\0\ 351 + \x0b\0\0\0\xb4\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xc4\x02\0\0\0\0\0\0\0\0\0\0\ 352 + \x0b\0\0\0\xd4\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\xe4\x02\0\0\0\0\0\0\0\0\0\0\ 353 + \x0b\0\0\0\xf4\x02\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x0c\x03\0\0\0\0\0\0\0\0\0\0\ 354 + \x0c\0\0\0\x1c\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x2c\x03\0\0\0\0\0\0\0\0\0\0\ 355 + \x0c\0\0\0\x3c\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x4c\x03\0\0\0\0\0\0\0\0\0\0\ 356 + \x0c\0\0\0\x5c\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x6c\x03\0\0\0\0\0\0\0\0\0\0\ 357 + \x0c\0\0\0\x7c\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x8c\x03\0\0\0\0\0\0\0\0\0\0\ 358 + \x0c\0\0\0\x9c\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xac\x03\0\0\0\0\0\0\0\0\0\0\ 359 + \x0c\0\0\0\xbc\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xcc\x03\0\0\0\0\0\0\0\0\0\0\ 360 + \x0c\0\0\0\xdc\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\xec\x03\0\0\0\0\0\0\0\0\0\0\ 361 + \x0c\0\0\0\xfc\x03\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x0c\x04\0\0\0\0\0\0\0\0\0\0\ 362 + \x0c\0\0\0\x1c\x04\0\0\0\0\0\0\0\0\0\0\x0c\0\0\0\x4d\x4e\x40\x41\x42\x43\x4c\0\ 363 + \x2e\x74\x65\x78\x74\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\x2e\x65\x78\x74\0\x64\ 364 + \x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\0\x64\ 365 + \x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\x72\x6f\x67\x2e\x5f\x5f\x5f\x66\x6d\x74\0\ 366 + \x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x6d\x61\x70\0\x2e\x72\x65\x6c\x69\x74\x65\ 367 + \x72\x2f\x62\x70\x66\x5f\x6d\x61\x70\0\x64\x75\x6d\x70\x5f\x62\x70\x66\x5f\x70\ 368 + \x72\x6f\x67\0\x2e\x72\x65\x6c\x69\x74\x65\x72\x2f\x62\x70\x66\x5f\x70\x72\x6f\ 369 + \x67\0\x2e\x6c\x6c\x76\x6d\x5f\x61\x64\x64\x72\x73\x69\x67\0\x6c\x69\x63\x65\ 370 + \x6e\x73\x65\0\x69\x74\x65\x72\x61\x74\x6f\x72\x73\x2e\x62\x70\x66\x2e\x63\0\ 371 + \x2e\x73\x74\x72\x74\x61\x62\0\x2e\x73\x79\x6d\x74\x61\x62\0\x2e\x72\x6f\x64\ 372 + \x61\x74\x61\0\x2e\x72\x65\x6c\x2e\x42\x54\x46\0\x4c\x49\x43\x45\x4e\x53\x45\0\ 373 + \x4c\x42\x42\x31\x5f\x37\0\x4c\x42\x42\x31\x5f\x36\0\x4c\x42\x42\x30\x5f\x34\0\ 374 + \x4c\x42\x42\x31\x5f\x33\0\x4c\x42\x42\x30\x5f\x33\0\x64\x75\x6d\x70\x5f\x62\ 375 + \x70\x66\x5f\x70\x72\x6f\x67\x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x32\0\x64\x75\x6d\ 376 + \x70\x5f\x62\x70\x66\x5f\x6d\x61\x70\x2e\x5f\x5f\x5f\x66\x6d\x74\x2e\x31\0\0\0\ 375 377 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 376 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\ 377 - \0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\ 378 - \0\0\0\0\0\0\0\x4e\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\ 379 - \0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 380 - \x6d\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x01\0\0\0\0\0\0\x08\ 381 - \x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa1\0\0\0\ 382 - \x01\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\x03\0\0\0\0\0\0\x62\0\0\0\0\0\ 383 - \0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x89\0\0\0\x01\0\0\0\x03\ 384 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\x03\0\0\0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\ 385 - \0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xad\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\ 386 - \0\0\0\0\0\0\0\xae\x03\0\0\0\0\0\0\x34\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\ 387 - \0\0\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 388 - \xe2\x0c\0\0\0\0\0\0\x2c\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\ 389 - \0\0\0\0\0\0\x99\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x10\x11\0\0\0\ 390 - \0\0\0\x80\x01\0\0\0\0\0\0\x0e\0\0\0\x0d\0\0\0\x08\0\0\0\0\0\0\0\x18\0\0\0\0\0\ 391 - \0\0\x4a\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x90\x12\0\0\0\0\0\0\ 392 - \x20\0\0\0\0\0\0\0\x08\0\0\0\x02\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x69\ 393 - \0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xb0\x12\0\0\0\0\0\0\x20\0\0\0\ 394 - \0\0\0\0\x08\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\xa9\0\0\0\x09\ 395 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd0\x12\0\0\0\0\0\0\x50\0\0\0\0\0\0\0\ 396 - \x08\0\0\0\x06\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x07\0\0\0\x09\0\0\0\0\ 397 - \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x20\x13\0\0\0\0\0\0\xe0\x03\0\0\0\0\0\0\x08\0\0\ 398 - \0\x07\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x7b\0\0\0\x03\x4c\xff\x6f\0\0\ 399 - \0\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\x17\0\0\0\0\0\0\x07\0\0\0\0\0\0\0\0\0\0\0\0\0\ 400 - \0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x91\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\ 401 - \0\0\0\0\0\0\x07\x17\0\0\0\0\0\0\x0a\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\ 402 - \0\0\0\0\0\0\0\0\0\0\0\0"; 378 + \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\x01\0\0\ 379 + \0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 380 + \0\0\0\0\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x4e\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\ 381 + \0\0\0\0\0\0\0\0\0\x40\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\ 382 + \0\0\0\0\0\0\0\0\0\0\0\0\0\x6d\0\0\0\x01\0\0\0\x06\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 383 + \0\x40\x01\0\0\0\0\0\0\x08\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x08\0\0\0\0\0\0\0\0\ 384 + \0\0\0\0\0\0\0\xb1\0\0\0\x01\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x48\x03\0\ 385 + \0\0\0\0\0\x62\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 386 + \x89\0\0\0\x01\0\0\0\x03\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xaa\x03\0\0\0\0\0\0\x04\ 387 + \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xbd\0\0\0\x01\ 388 + \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xae\x03\0\0\0\0\0\0\x3d\x09\0\0\0\0\0\0\ 389 + \0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0b\0\0\0\x01\0\0\0\0\0\0\0\ 390 + \0\0\0\0\0\0\0\0\0\0\0\0\xeb\x0c\0\0\0\0\0\0\x2c\x04\0\0\0\0\0\0\0\0\0\0\0\0\0\ 391 + \0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa9\0\0\0\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 392 + \0\0\0\0\0\x18\x11\0\0\0\0\0\0\x98\x01\0\0\0\0\0\0\x0e\0\0\0\x0e\0\0\0\x08\0\0\ 393 + \0\0\0\0\0\x18\0\0\0\0\0\0\0\x4a\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ 394 + \0\xb0\x12\0\0\0\0\0\0\x20\0\0\0\0\0\0\0\x08\0\0\0\x02\0\0\0\x08\0\0\0\0\0\0\0\ 395 + \x10\0\0\0\0\0\0\0\x69\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xd0\x12\ 396 + \0\0\0\0\0\0\x20\0\0\0\0\0\0\0\x08\0\0\0\x03\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\ 397 + \0\0\0\0\xb9\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xf0\x12\0\0\0\0\0\ 398 + \0\x50\0\0\0\0\0\0\0\x08\0\0\0\x06\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\ 399 + \x07\0\0\0\x09\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x40\x13\0\0\0\0\0\0\xe0\ 400 + \x03\0\0\0\0\0\0\x08\0\0\0\x07\0\0\0\x08\0\0\0\0\0\0\0\x10\0\0\0\0\0\0\0\x7b\0\ 401 + \0\0\x03\x4c\xff\x6f\0\0\0\x80\0\0\0\0\0\0\0\0\0\0\0\0\x20\x17\0\0\0\0\0\0\x07\ 402 + \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xa1\0\0\0\x03\ 403 + \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x27\x17\0\0\0\0\0\0\x1a\x01\0\0\0\0\0\0\ 404 + \0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 403 405 404 406 return 0; 405 407 err:
+156 -24
kernel/bpf/syscall.c
··· 4 4 #include <linux/bpf.h> 5 5 #include <linux/bpf_trace.h> 6 6 #include <linux/bpf_lirc.h> 7 + #include <linux/bpf_verifier.h> 7 8 #include <linux/btf.h> 8 9 #include <linux/syscalls.h> 9 10 #include <linux/slab.h> ··· 2155 2154 prog->expected_attach_type = attr->expected_attach_type; 2156 2155 prog->aux->attach_btf_id = attr->attach_btf_id; 2157 2156 if (attr->attach_prog_fd) { 2158 - struct bpf_prog *tgt_prog; 2157 + struct bpf_prog *dst_prog; 2159 2158 2160 - tgt_prog = bpf_prog_get(attr->attach_prog_fd); 2161 - if (IS_ERR(tgt_prog)) { 2162 - err = PTR_ERR(tgt_prog); 2159 + dst_prog = bpf_prog_get(attr->attach_prog_fd); 2160 + if (IS_ERR(dst_prog)) { 2161 + err = PTR_ERR(dst_prog); 2163 2162 goto free_prog_nouncharge; 2164 2163 } 2165 - prog->aux->linked_prog = tgt_prog; 2164 + prog->aux->dst_prog = dst_prog; 2166 2165 } 2167 2166 2168 2167 prog->aux->offload_requested = !!attr->prog_ifindex; ··· 2499 2498 struct bpf_tracing_link { 2500 2499 struct bpf_link link; 2501 2500 enum bpf_attach_type attach_type; 2501 + struct bpf_trampoline *trampoline; 2502 + struct bpf_prog *tgt_prog; 2502 2503 }; 2503 2504 2504 2505 static void bpf_tracing_link_release(struct bpf_link *link) 2505 2506 { 2506 - WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog)); 2507 + struct bpf_tracing_link *tr_link = 2508 + container_of(link, struct bpf_tracing_link, link); 2509 + 2510 + WARN_ON_ONCE(bpf_trampoline_unlink_prog(link->prog, 2511 + tr_link->trampoline)); 2512 + 2513 + bpf_trampoline_put(tr_link->trampoline); 2514 + 2515 + /* tgt_prog is NULL if target is a kernel function */ 2516 + if (tr_link->tgt_prog) 2517 + bpf_prog_put(tr_link->tgt_prog); 2507 2518 } 2508 2519 2509 2520 static void bpf_tracing_link_dealloc(struct bpf_link *link) ··· 2555 2542 .fill_link_info = bpf_tracing_link_fill_link_info, 2556 2543 }; 2557 2544 2558 - static int bpf_tracing_prog_attach(struct bpf_prog *prog) 2545 + static int bpf_tracing_prog_attach(struct bpf_prog *prog, 2546 + int tgt_prog_fd, 2547 + u32 btf_id) 2559 2548 { 2560 2549 struct bpf_link_primer link_primer; 2550 + struct bpf_prog *tgt_prog = NULL; 2551 + struct bpf_trampoline *tr = NULL; 2561 2552 struct bpf_tracing_link *link; 2553 + u64 key = 0; 2562 2554 int err; 2563 2555 2564 2556 switch (prog->type) { ··· 2592 2574 goto out_put_prog; 2593 2575 } 2594 2576 2577 + if (!!tgt_prog_fd != !!btf_id) { 2578 + err = -EINVAL; 2579 + goto out_put_prog; 2580 + } 2581 + 2582 + if (tgt_prog_fd) { 2583 + /* For now we only allow new targets for BPF_PROG_TYPE_EXT */ 2584 + if (prog->type != BPF_PROG_TYPE_EXT) { 2585 + err = -EINVAL; 2586 + goto out_put_prog; 2587 + } 2588 + 2589 + tgt_prog = bpf_prog_get(tgt_prog_fd); 2590 + if (IS_ERR(tgt_prog)) { 2591 + err = PTR_ERR(tgt_prog); 2592 + tgt_prog = NULL; 2593 + goto out_put_prog; 2594 + } 2595 + 2596 + key = bpf_trampoline_compute_key(tgt_prog, btf_id); 2597 + } 2598 + 2595 2599 link = kzalloc(sizeof(*link), GFP_USER); 2596 2600 if (!link) { 2597 2601 err = -ENOMEM; ··· 2623 2583 &bpf_tracing_link_lops, prog); 2624 2584 link->attach_type = prog->expected_attach_type; 2625 2585 2626 - err = bpf_link_prime(&link->link, &link_primer); 2627 - if (err) { 2628 - kfree(link); 2629 - goto out_put_prog; 2586 + mutex_lock(&prog->aux->dst_mutex); 2587 + 2588 + /* There are a few possible cases here: 2589 + * 2590 + * - if prog->aux->dst_trampoline is set, the program was just loaded 2591 + * and not yet attached to anything, so we can use the values stored 2592 + * in prog->aux 2593 + * 2594 + * - if prog->aux->dst_trampoline is NULL, the program has already been 2595 + * attached to a target and its initial target was cleared (below) 2596 + * 2597 + * - if tgt_prog != NULL, the caller specified tgt_prog_fd + 2598 + * target_btf_id using the link_create API. 2599 + * 2600 + * - if tgt_prog == NULL when this function was called using the old 2601 + * raw_tracepoint_open API, and we need a target from prog->aux 2602 + * 2603 + * The combination of no saved target in prog->aux, and no target 2604 + * specified on load is illegal, and we reject that here. 2605 + */ 2606 + if (!prog->aux->dst_trampoline && !tgt_prog) { 2607 + err = -ENOENT; 2608 + goto out_unlock; 2630 2609 } 2631 2610 2632 - err = bpf_trampoline_link_prog(prog); 2611 + if (!prog->aux->dst_trampoline || 2612 + (key && key != prog->aux->dst_trampoline->key)) { 2613 + /* If there is no saved target, or the specified target is 2614 + * different from the destination specified at load time, we 2615 + * need a new trampoline and a check for compatibility 2616 + */ 2617 + struct bpf_attach_target_info tgt_info = {}; 2618 + 2619 + err = bpf_check_attach_target(NULL, prog, tgt_prog, btf_id, 2620 + &tgt_info); 2621 + if (err) 2622 + goto out_unlock; 2623 + 2624 + tr = bpf_trampoline_get(key, &tgt_info); 2625 + if (!tr) { 2626 + err = -ENOMEM; 2627 + goto out_unlock; 2628 + } 2629 + } else { 2630 + /* The caller didn't specify a target, or the target was the 2631 + * same as the destination supplied during program load. This 2632 + * means we can reuse the trampoline and reference from program 2633 + * load time, and there is no need to allocate a new one. This 2634 + * can only happen once for any program, as the saved values in 2635 + * prog->aux are cleared below. 2636 + */ 2637 + tr = prog->aux->dst_trampoline; 2638 + tgt_prog = prog->aux->dst_prog; 2639 + } 2640 + 2641 + err = bpf_link_prime(&link->link, &link_primer); 2642 + if (err) 2643 + goto out_unlock; 2644 + 2645 + err = bpf_trampoline_link_prog(prog, tr); 2633 2646 if (err) { 2634 2647 bpf_link_cleanup(&link_primer); 2635 - goto out_put_prog; 2648 + link = NULL; 2649 + goto out_unlock; 2636 2650 } 2637 2651 2652 + link->tgt_prog = tgt_prog; 2653 + link->trampoline = tr; 2654 + 2655 + /* Always clear the trampoline and target prog from prog->aux to make 2656 + * sure the original attach destination is not kept alive after a 2657 + * program is (re-)attached to another target. 2658 + */ 2659 + if (prog->aux->dst_prog && 2660 + (tgt_prog_fd || tr != prog->aux->dst_trampoline)) 2661 + /* got extra prog ref from syscall, or attaching to different prog */ 2662 + bpf_prog_put(prog->aux->dst_prog); 2663 + if (prog->aux->dst_trampoline && tr != prog->aux->dst_trampoline) 2664 + /* we allocated a new trampoline, so free the old one */ 2665 + bpf_trampoline_put(prog->aux->dst_trampoline); 2666 + 2667 + prog->aux->dst_prog = NULL; 2668 + prog->aux->dst_trampoline = NULL; 2669 + mutex_unlock(&prog->aux->dst_mutex); 2670 + 2638 2671 return bpf_link_settle(&link_primer); 2672 + out_unlock: 2673 + if (tr && tr != prog->aux->dst_trampoline) 2674 + bpf_trampoline_put(tr); 2675 + mutex_unlock(&prog->aux->dst_mutex); 2676 + kfree(link); 2639 2677 out_put_prog: 2678 + if (tgt_prog_fd && tgt_prog) 2679 + bpf_prog_put(tgt_prog); 2640 2680 bpf_prog_put(prog); 2641 2681 return err; 2642 2682 } ··· 2830 2710 tp_name = prog->aux->attach_func_name; 2831 2711 break; 2832 2712 } 2833 - return bpf_tracing_prog_attach(prog); 2713 + return bpf_tracing_prog_attach(prog, 0, 0); 2834 2714 case BPF_PROG_TYPE_RAW_TRACEPOINT: 2835 2715 case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: 2836 2716 if (strncpy_from_user(buf, ··· 4014 3894 4015 3895 static int tracing_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) 4016 3896 { 4017 - if (attr->link_create.attach_type == BPF_TRACE_ITER && 4018 - prog->expected_attach_type == BPF_TRACE_ITER) 4019 - return bpf_iter_link_attach(attr, prog); 3897 + if (attr->link_create.attach_type != prog->expected_attach_type) 3898 + return -EINVAL; 4020 3899 3900 + if (prog->expected_attach_type == BPF_TRACE_ITER) 3901 + return bpf_iter_link_attach(attr, prog); 3902 + else if (prog->type == BPF_PROG_TYPE_EXT) 3903 + return bpf_tracing_prog_attach(prog, 3904 + attr->link_create.target_fd, 3905 + attr->link_create.target_btf_id); 4021 3906 return -EINVAL; 4022 3907 } 4023 3908 ··· 4036 3911 if (CHECK_ATTR(BPF_LINK_CREATE)) 4037 3912 return -EINVAL; 4038 3913 4039 - ptype = attach_type_to_prog_type(attr->link_create.attach_type); 4040 - if (ptype == BPF_PROG_TYPE_UNSPEC) 4041 - return -EINVAL; 4042 - 4043 - prog = bpf_prog_get_type(attr->link_create.prog_fd, ptype); 3914 + prog = bpf_prog_get(attr->link_create.prog_fd); 4044 3915 if (IS_ERR(prog)) 4045 3916 return PTR_ERR(prog); 4046 3917 4047 3918 ret = bpf_prog_attach_check_attach_type(prog, 4048 3919 attr->link_create.attach_type); 4049 3920 if (ret) 4050 - goto err_out; 3921 + goto out; 3922 + 3923 + if (prog->type == BPF_PROG_TYPE_EXT) { 3924 + ret = tracing_bpf_link_attach(attr, prog); 3925 + goto out; 3926 + } 3927 + 3928 + ptype = attach_type_to_prog_type(attr->link_create.attach_type); 3929 + if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) { 3930 + ret = -EINVAL; 3931 + goto out; 3932 + } 4051 3933 4052 3934 switch (ptype) { 4053 3935 case BPF_PROG_TYPE_CGROUP_SKB: ··· 4082 3950 ret = -EINVAL; 4083 3951 } 4084 3952 4085 - err_out: 3953 + out: 4086 3954 if (ret < 0) 4087 3955 bpf_prog_put(prog); 4088 3956 return ret;
+4 -8
kernel/bpf/trampoline.c
··· 261 261 } 262 262 } 263 263 264 - int bpf_trampoline_link_prog(struct bpf_prog *prog) 264 + int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr) 265 265 { 266 266 enum bpf_tramp_prog_type kind; 267 - struct bpf_trampoline *tr; 268 267 int err = 0; 269 268 int cnt; 270 269 271 - tr = prog->aux->trampoline; 272 270 kind = bpf_attach_type_to_tramp(prog); 273 271 mutex_lock(&tr->mutex); 274 272 if (tr->extension_prog) { ··· 299 301 } 300 302 hlist_add_head(&prog->aux->tramp_hlist, &tr->progs_hlist[kind]); 301 303 tr->progs_cnt[kind]++; 302 - err = bpf_trampoline_update(prog->aux->trampoline); 304 + err = bpf_trampoline_update(tr); 303 305 if (err) { 304 306 hlist_del(&prog->aux->tramp_hlist); 305 307 tr->progs_cnt[kind]--; ··· 310 312 } 311 313 312 314 /* bpf_trampoline_unlink_prog() should never fail. */ 313 - int bpf_trampoline_unlink_prog(struct bpf_prog *prog) 315 + int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr) 314 316 { 315 317 enum bpf_tramp_prog_type kind; 316 - struct bpf_trampoline *tr; 317 318 int err; 318 319 319 - tr = prog->aux->trampoline; 320 320 kind = bpf_attach_type_to_tramp(prog); 321 321 mutex_lock(&tr->mutex); 322 322 if (kind == BPF_TRAMP_REPLACE) { ··· 326 330 } 327 331 hlist_del(&prog->aux->tramp_hlist); 328 332 tr->progs_cnt[kind]--; 329 - err = bpf_trampoline_update(prog->aux->trampoline); 333 + err = bpf_trampoline_update(tr); 330 334 out: 331 335 mutex_unlock(&tr->mutex); 332 336 return err;
+17 -4
kernel/bpf/verifier.c
··· 2648 2648 2649 2649 static enum bpf_prog_type resolve_prog_type(struct bpf_prog *prog) 2650 2650 { 2651 - return prog->aux->linked_prog ? prog->aux->linked_prog->type 2652 - : prog->type; 2651 + return prog->aux->dst_prog ? prog->aux->dst_prog->type : prog->type; 2653 2652 } 2654 2653 2655 2654 static bool may_access_direct_pkt_data(struct bpf_verifier_env *env, ··· 11404 11405 if (!btf_type_is_func_proto(t)) 11405 11406 return -EINVAL; 11406 11407 11408 + if ((prog->aux->saved_dst_prog_type || prog->aux->saved_dst_attach_type) && 11409 + (!tgt_prog || prog->aux->saved_dst_prog_type != tgt_prog->type || 11410 + prog->aux->saved_dst_attach_type != tgt_prog->expected_attach_type)) 11411 + return -EINVAL; 11412 + 11407 11413 if (tgt_prog && conservative) 11408 11414 t = NULL; 11409 11415 ··· 11479 11475 static int check_attach_btf_id(struct bpf_verifier_env *env) 11480 11476 { 11481 11477 struct bpf_prog *prog = env->prog; 11482 - struct bpf_prog *tgt_prog = prog->aux->linked_prog; 11478 + struct bpf_prog *tgt_prog = prog->aux->dst_prog; 11483 11479 struct bpf_attach_target_info tgt_info = {}; 11484 11480 u32 btf_id = prog->aux->attach_btf_id; 11485 11481 struct bpf_trampoline *tr; ··· 11505 11501 return ret; 11506 11502 11507 11503 if (tgt_prog && prog->type == BPF_PROG_TYPE_EXT) { 11504 + /* to make freplace equivalent to their targets, they need to 11505 + * inherit env->ops and expected_attach_type for the rest of the 11506 + * verification 11507 + */ 11508 11508 env->ops = bpf_verifier_ops[tgt_prog->type]; 11509 11509 prog->expected_attach_type = tgt_prog->expected_attach_type; 11510 11510 } ··· 11516 11508 /* store info about the attachment target that will be used later */ 11517 11509 prog->aux->attach_func_proto = tgt_info.tgt_type; 11518 11510 prog->aux->attach_func_name = tgt_info.tgt_name; 11511 + 11512 + if (tgt_prog) { 11513 + prog->aux->saved_dst_prog_type = tgt_prog->type; 11514 + prog->aux->saved_dst_attach_type = tgt_prog->expected_attach_type; 11515 + } 11519 11516 11520 11517 if (prog->expected_attach_type == BPF_TRACE_RAW_TP) { 11521 11518 prog->aux->attach_btf_trace = true; ··· 11542 11529 if (!tr) 11543 11530 return -ENOMEM; 11544 11531 11545 - prog->aux->trampoline = tr; 11532 + prog->aux->dst_trampoline = tr; 11546 11533 return 0; 11547 11534 } 11548 11535
+7 -2
tools/include/uapi/linux/bpf.h
··· 639 639 }; 640 640 __u32 attach_type; /* attach type */ 641 641 __u32 flags; /* extra flags */ 642 - __aligned_u64 iter_info; /* extra bpf_iter_link_info */ 643 - __u32 iter_info_len; /* iter_info length */ 642 + union { 643 + __u32 target_btf_id; /* btf_id of target to attach to */ 644 + struct { 645 + __aligned_u64 iter_info; /* extra bpf_iter_link_info */ 646 + __u32 iter_info_len; /* iter_info length */ 647 + }; 648 + }; 644 649 } link_create; 645 650 646 651 struct { /* struct used by BPF_LINK_UPDATE command */
+15 -3
tools/lib/bpf/bpf.c
··· 586 586 enum bpf_attach_type attach_type, 587 587 const struct bpf_link_create_opts *opts) 588 588 { 589 + __u32 target_btf_id, iter_info_len; 589 590 union bpf_attr attr; 590 591 591 592 if (!OPTS_VALID(opts, bpf_link_create_opts)) 593 + return -EINVAL; 594 + 595 + iter_info_len = OPTS_GET(opts, iter_info_len, 0); 596 + target_btf_id = OPTS_GET(opts, target_btf_id, 0); 597 + 598 + if (iter_info_len && target_btf_id) 592 599 return -EINVAL; 593 600 594 601 memset(&attr, 0, sizeof(attr)); ··· 603 596 attr.link_create.target_fd = target_fd; 604 597 attr.link_create.attach_type = attach_type; 605 598 attr.link_create.flags = OPTS_GET(opts, flags, 0); 606 - attr.link_create.iter_info = 607 - ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0)); 608 - attr.link_create.iter_info_len = OPTS_GET(opts, iter_info_len, 0); 599 + 600 + if (iter_info_len) { 601 + attr.link_create.iter_info = 602 + ptr_to_u64(OPTS_GET(opts, iter_info, (void *)0)); 603 + attr.link_create.iter_info_len = iter_info_len; 604 + } else if (target_btf_id) { 605 + attr.link_create.target_btf_id = target_btf_id; 606 + } 609 607 610 608 return sys_bpf(BPF_LINK_CREATE, &attr, sizeof(attr)); 611 609 }
+2 -1
tools/lib/bpf/bpf.h
··· 174 174 __u32 flags; 175 175 union bpf_iter_link_info *iter_info; 176 176 __u32 iter_info_len; 177 + __u32 target_btf_id; 177 178 }; 178 - #define bpf_link_create_opts__last_field iter_info_len 179 + #define bpf_link_create_opts__last_field target_btf_id 179 180 180 181 LIBBPF_API int bpf_link_create(int prog_fd, int target_fd, 181 182 enum bpf_attach_type attach_type,
+39 -5
tools/lib/bpf/libbpf.c
··· 9390 9390 } 9391 9391 9392 9392 static struct bpf_link * 9393 - bpf_program__attach_fd(struct bpf_program *prog, int target_fd, 9393 + bpf_program__attach_fd(struct bpf_program *prog, int target_fd, int btf_id, 9394 9394 const char *target_name) 9395 9395 { 9396 + DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts, 9397 + .target_btf_id = btf_id); 9396 9398 enum bpf_attach_type attach_type; 9397 9399 char errmsg[STRERR_BUFSIZE]; 9398 9400 struct bpf_link *link; ··· 9412 9410 link->detach = &bpf_link__detach_fd; 9413 9411 9414 9412 attach_type = bpf_program__get_expected_attach_type(prog); 9415 - link_fd = bpf_link_create(prog_fd, target_fd, attach_type, NULL); 9413 + link_fd = bpf_link_create(prog_fd, target_fd, attach_type, &opts); 9416 9414 if (link_fd < 0) { 9417 9415 link_fd = -errno; 9418 9416 free(link); ··· 9428 9426 struct bpf_link * 9429 9427 bpf_program__attach_cgroup(struct bpf_program *prog, int cgroup_fd) 9430 9428 { 9431 - return bpf_program__attach_fd(prog, cgroup_fd, "cgroup"); 9429 + return bpf_program__attach_fd(prog, cgroup_fd, 0, "cgroup"); 9432 9430 } 9433 9431 9434 9432 struct bpf_link * 9435 9433 bpf_program__attach_netns(struct bpf_program *prog, int netns_fd) 9436 9434 { 9437 - return bpf_program__attach_fd(prog, netns_fd, "netns"); 9435 + return bpf_program__attach_fd(prog, netns_fd, 0, "netns"); 9438 9436 } 9439 9437 9440 9438 struct bpf_link *bpf_program__attach_xdp(struct bpf_program *prog, int ifindex) 9441 9439 { 9442 9440 /* target_fd/target_ifindex use the same field in LINK_CREATE */ 9443 - return bpf_program__attach_fd(prog, ifindex, "xdp"); 9441 + return bpf_program__attach_fd(prog, ifindex, 0, "xdp"); 9442 + } 9443 + 9444 + struct bpf_link *bpf_program__attach_freplace(struct bpf_program *prog, 9445 + int target_fd, 9446 + const char *attach_func_name) 9447 + { 9448 + int btf_id; 9449 + 9450 + if (!!target_fd != !!attach_func_name) { 9451 + pr_warn("prog '%s': supply none or both of target_fd and attach_func_name\n", 9452 + prog->name); 9453 + return ERR_PTR(-EINVAL); 9454 + } 9455 + 9456 + if (prog->type != BPF_PROG_TYPE_EXT) { 9457 + pr_warn("prog '%s': only BPF_PROG_TYPE_EXT can attach as freplace", 9458 + prog->name); 9459 + return ERR_PTR(-EINVAL); 9460 + } 9461 + 9462 + if (target_fd) { 9463 + btf_id = libbpf_find_prog_btf_id(attach_func_name, target_fd); 9464 + if (btf_id < 0) 9465 + return ERR_PTR(btf_id); 9466 + 9467 + return bpf_program__attach_fd(prog, target_fd, btf_id, "freplace"); 9468 + } else { 9469 + /* no target, so use raw_tracepoint_open for compatibility 9470 + * with old kernels 9471 + */ 9472 + return bpf_program__attach_trace(prog); 9473 + } 9444 9474 } 9445 9475 9446 9476 struct bpf_link *
+3
tools/lib/bpf/libbpf.h
··· 261 261 bpf_program__attach_netns(struct bpf_program *prog, int netns_fd); 262 262 LIBBPF_API struct bpf_link * 263 263 bpf_program__attach_xdp(struct bpf_program *prog, int ifindex); 264 + LIBBPF_API struct bpf_link * 265 + bpf_program__attach_freplace(struct bpf_program *prog, 266 + int target_fd, const char *attach_func_name); 264 267 265 268 struct bpf_map; 266 269
+1
tools/lib/bpf/libbpf.map
··· 304 304 global: 305 305 bpf_prog_bind_map; 306 306 bpf_prog_test_run_opts; 307 + bpf_program__attach_freplace; 307 308 bpf_program__section_name; 308 309 btf__add_array; 309 310 btf__add_const;
+180 -32
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
··· 2 2 /* Copyright (c) 2019 Facebook */ 3 3 #include <test_progs.h> 4 4 #include <network_helpers.h> 5 + #include <bpf/btf.h> 6 + 7 + typedef int (*test_cb)(struct bpf_object *obj); 8 + 9 + static int check_data_map(struct bpf_object *obj, int prog_cnt, bool reset) 10 + { 11 + struct bpf_map *data_map = NULL, *map; 12 + __u64 *result = NULL; 13 + const int zero = 0; 14 + __u32 duration = 0; 15 + int ret = -1, i; 16 + 17 + result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64)); 18 + if (CHECK(!result, "alloc_memory", "failed to alloc memory")) 19 + return -ENOMEM; 20 + 21 + bpf_object__for_each_map(map, obj) 22 + if (bpf_map__is_internal(map)) { 23 + data_map = map; 24 + break; 25 + } 26 + if (CHECK(!data_map, "find_data_map", "data map not found\n")) 27 + goto out; 28 + 29 + ret = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); 30 + if (CHECK(ret, "get_result", 31 + "failed to get output data: %d\n", ret)) 32 + goto out; 33 + 34 + for (i = 0; i < prog_cnt; i++) { 35 + if (CHECK(result[i] != 1, "result", 36 + "fexit_bpf2bpf result[%d] failed err %llu\n", 37 + i, result[i])) 38 + goto out; 39 + result[i] = 0; 40 + } 41 + if (reset) { 42 + ret = bpf_map_update_elem(bpf_map__fd(data_map), &zero, result, 0); 43 + if (CHECK(ret, "reset_result", "failed to reset result\n")) 44 + goto out; 45 + } 46 + 47 + ret = 0; 48 + out: 49 + free(result); 50 + return ret; 51 + } 5 52 6 53 static void test_fexit_bpf2bpf_common(const char *obj_file, 7 54 const char *target_obj_file, 8 55 int prog_cnt, 9 56 const char **prog_name, 10 - bool run_prog) 57 + bool run_prog, 58 + test_cb cb) 11 59 { 12 - struct bpf_object *obj = NULL, *pkt_obj; 13 - int err, pkt_fd, i; 14 - struct bpf_link **link = NULL; 60 + struct bpf_object *obj = NULL, *tgt_obj; 15 61 struct bpf_program **prog = NULL; 62 + struct bpf_link **link = NULL; 16 63 __u32 duration = 0, retval; 17 - struct bpf_map *data_map; 18 - const int zero = 0; 19 - __u64 *result = NULL; 64 + int err, tgt_fd, i; 20 65 21 66 err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC, 22 - &pkt_obj, &pkt_fd); 67 + &tgt_obj, &tgt_fd); 23 68 if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", 24 69 target_obj_file, err, errno)) 25 70 return; 26 71 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, 27 - .attach_prog_fd = pkt_fd, 72 + .attach_prog_fd = tgt_fd, 28 73 ); 29 74 30 75 link = calloc(sizeof(struct bpf_link *), prog_cnt); 31 76 prog = calloc(sizeof(struct bpf_program *), prog_cnt); 32 - result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64)); 33 - if (CHECK(!link || !prog || !result, "alloc_memory", 34 - "failed to alloc memory")) 77 + if (CHECK(!link || !prog, "alloc_memory", "failed to alloc memory")) 35 78 goto close_prog; 36 79 37 80 obj = bpf_object__open_file(obj_file, &opts); ··· 96 53 goto close_prog; 97 54 } 98 55 56 + if (cb) { 57 + err = cb(obj); 58 + if (err) 59 + goto close_prog; 60 + } 61 + 99 62 if (!run_prog) 100 63 goto close_prog; 101 64 102 - data_map = bpf_object__find_map_by_name(obj, "fexit_bp.bss"); 103 - if (CHECK(!data_map, "find_data_map", "data map not found\n")) 104 - goto close_prog; 105 - 106 - err = bpf_prog_test_run(pkt_fd, 1, &pkt_v6, sizeof(pkt_v6), 65 + err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), 107 66 NULL, NULL, &retval, &duration); 108 67 CHECK(err || retval, "ipv6", 109 68 "err %d errno %d retval %d duration %d\n", 110 69 err, errno, retval, duration); 111 70 112 - err = bpf_map_lookup_elem(bpf_map__fd(data_map), &zero, result); 113 - if (CHECK(err, "get_result", 114 - "failed to get output data: %d\n", err)) 71 + if (check_data_map(obj, prog_cnt, false)) 115 72 goto close_prog; 116 - 117 - for (i = 0; i < prog_cnt; i++) 118 - if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %llu\n", 119 - result[i])) 120 - goto close_prog; 121 73 122 74 close_prog: 123 75 for (i = 0; i < prog_cnt; i++) ··· 120 82 bpf_link__destroy(link[i]); 121 83 if (!IS_ERR_OR_NULL(obj)) 122 84 bpf_object__close(obj); 123 - bpf_object__close(pkt_obj); 85 + bpf_object__close(tgt_obj); 124 86 free(link); 125 87 free(prog); 126 - free(result); 127 88 } 128 89 129 90 static void test_target_no_callees(void) ··· 133 96 test_fexit_bpf2bpf_common("./fexit_bpf2bpf_simple.o", 134 97 "./test_pkt_md_access.o", 135 98 ARRAY_SIZE(prog_name), 136 - prog_name, true); 99 + prog_name, true, NULL); 137 100 } 138 101 139 102 static void test_target_yes_callees(void) ··· 147 110 test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 148 111 "./test_pkt_access.o", 149 112 ARRAY_SIZE(prog_name), 150 - prog_name, true); 113 + prog_name, true, NULL); 151 114 } 152 115 153 116 static void test_func_replace(void) ··· 165 128 test_fexit_bpf2bpf_common("./fexit_bpf2bpf.o", 166 129 "./test_pkt_access.o", 167 130 ARRAY_SIZE(prog_name), 168 - prog_name, true); 131 + prog_name, true, NULL); 169 132 } 170 133 171 134 static void test_func_replace_verify(void) ··· 176 139 test_fexit_bpf2bpf_common("./freplace_connect4.o", 177 140 "./connect4_prog.o", 178 141 ARRAY_SIZE(prog_name), 179 - prog_name, false); 142 + prog_name, false, NULL); 180 143 } 144 + 145 + static int test_second_attach(struct bpf_object *obj) 146 + { 147 + const char *prog_name = "freplace/get_constant"; 148 + const char *tgt_name = prog_name + 9; /* cut off freplace/ */ 149 + const char *tgt_obj_file = "./test_pkt_access.o"; 150 + struct bpf_program *prog = NULL; 151 + struct bpf_object *tgt_obj; 152 + __u32 duration = 0, retval; 153 + struct bpf_link *link; 154 + int err = 0, tgt_fd; 155 + 156 + prog = bpf_object__find_program_by_title(obj, prog_name); 157 + if (CHECK(!prog, "find_prog", "prog %s not found\n", prog_name)) 158 + return -ENOENT; 159 + 160 + err = bpf_prog_load(tgt_obj_file, BPF_PROG_TYPE_UNSPEC, 161 + &tgt_obj, &tgt_fd); 162 + if (CHECK(err, "second_prog_load", "file %s err %d errno %d\n", 163 + tgt_obj_file, err, errno)) 164 + return err; 165 + 166 + link = bpf_program__attach_freplace(prog, tgt_fd, tgt_name); 167 + if (CHECK(IS_ERR(link), "second_link", "failed to attach second link prog_fd %d tgt_fd %d\n", bpf_program__fd(prog), tgt_fd)) 168 + goto out; 169 + 170 + err = bpf_prog_test_run(tgt_fd, 1, &pkt_v6, sizeof(pkt_v6), 171 + NULL, NULL, &retval, &duration); 172 + if (CHECK(err || retval, "ipv6", 173 + "err %d errno %d retval %d duration %d\n", 174 + err, errno, retval, duration)) 175 + goto out; 176 + 177 + err = check_data_map(obj, 1, true); 178 + if (err) 179 + goto out; 180 + 181 + out: 182 + bpf_link__destroy(link); 183 + bpf_object__close(tgt_obj); 184 + return err; 185 + } 186 + 187 + static void test_func_replace_multi(void) 188 + { 189 + const char *prog_name[] = { 190 + "freplace/get_constant", 191 + }; 192 + test_fexit_bpf2bpf_common("./freplace_get_constant.o", 193 + "./test_pkt_access.o", 194 + ARRAY_SIZE(prog_name), 195 + prog_name, true, test_second_attach); 196 + } 197 + 198 + static void test_fmod_ret_freplace(void) 199 + { 200 + struct bpf_object *freplace_obj = NULL, *pkt_obj, *fmod_obj = NULL; 201 + const char *freplace_name = "./freplace_get_constant.o"; 202 + const char *fmod_ret_name = "./fmod_ret_freplace.o"; 203 + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); 204 + const char *tgt_name = "./test_pkt_access.o"; 205 + struct bpf_link *freplace_link = NULL; 206 + struct bpf_program *prog; 207 + __u32 duration = 0; 208 + int err, pkt_fd; 209 + 210 + err = bpf_prog_load(tgt_name, BPF_PROG_TYPE_UNSPEC, 211 + &pkt_obj, &pkt_fd); 212 + /* the target prog should load fine */ 213 + if (CHECK(err, "tgt_prog_load", "file %s err %d errno %d\n", 214 + tgt_name, err, errno)) 215 + return; 216 + opts.attach_prog_fd = pkt_fd; 217 + 218 + freplace_obj = bpf_object__open_file(freplace_name, &opts); 219 + if (CHECK(IS_ERR_OR_NULL(freplace_obj), "freplace_obj_open", 220 + "failed to open %s: %ld\n", freplace_name, 221 + PTR_ERR(freplace_obj))) 222 + goto out; 223 + 224 + err = bpf_object__load(freplace_obj); 225 + if (CHECK(err, "freplace_obj_load", "err %d\n", err)) 226 + goto out; 227 + 228 + prog = bpf_program__next(NULL, freplace_obj); 229 + freplace_link = bpf_program__attach_trace(prog); 230 + if (CHECK(IS_ERR(freplace_link), "freplace_attach_trace", "failed to link\n")) 231 + goto out; 232 + 233 + opts.attach_prog_fd = bpf_program__fd(prog); 234 + fmod_obj = bpf_object__open_file(fmod_ret_name, &opts); 235 + if (CHECK(IS_ERR_OR_NULL(fmod_obj), "fmod_obj_open", 236 + "failed to open %s: %ld\n", fmod_ret_name, 237 + PTR_ERR(fmod_obj))) 238 + goto out; 239 + 240 + err = bpf_object__load(fmod_obj); 241 + if (CHECK(!err, "fmod_obj_load", "loading fmod_ret should fail\n")) 242 + goto out; 243 + 244 + out: 245 + bpf_link__destroy(freplace_link); 246 + bpf_object__close(freplace_obj); 247 + bpf_object__close(fmod_obj); 248 + bpf_object__close(pkt_obj); 249 + } 250 + 181 251 182 252 static void test_func_sockmap_update(void) 183 253 { ··· 294 150 test_fexit_bpf2bpf_common("./freplace_cls_redirect.o", 295 151 "./test_cls_redirect.o", 296 152 ARRAY_SIZE(prog_name), 297 - prog_name, false); 153 + prog_name, false, NULL); 298 154 } 299 155 300 156 static void test_obj_load_failure_common(const char *obj_file, ··· 366 222 test_func_replace_return_code(); 367 223 if (test__start_subtest("func_map_prog_compatibility")) 368 224 test_func_map_prog_compatibility(); 225 + if (test__start_subtest("func_replace_multi")) 226 + test_func_replace_multi(); 227 + if (test__start_subtest("fmod_ret_freplace")) 228 + test_fmod_ret_freplace(); 369 229 }
+111
tools/testing/selftests/bpf/prog_tests/trace_ext.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #define _GNU_SOURCE 4 + #include <test_progs.h> 5 + #include <network_helpers.h> 6 + #include <sys/stat.h> 7 + #include <linux/sched.h> 8 + #include <sys/syscall.h> 9 + 10 + #include "test_pkt_md_access.skel.h" 11 + #include "test_trace_ext.skel.h" 12 + #include "test_trace_ext_tracing.skel.h" 13 + 14 + static __u32 duration; 15 + 16 + void test_trace_ext(void) 17 + { 18 + struct test_pkt_md_access *skel_pkt = NULL; 19 + struct test_trace_ext_tracing *skel_trace = NULL; 20 + struct test_trace_ext_tracing__bss *bss_trace; 21 + struct test_trace_ext *skel_ext = NULL; 22 + struct test_trace_ext__bss *bss_ext; 23 + int err, pkt_fd, ext_fd; 24 + struct bpf_program *prog; 25 + char buf[100]; 26 + __u32 retval; 27 + __u64 len; 28 + 29 + /* open/load/attach test_pkt_md_access */ 30 + skel_pkt = test_pkt_md_access__open_and_load(); 31 + if (CHECK(!skel_pkt, "setup", "classifier/test_pkt_md_access open failed\n")) 32 + goto cleanup; 33 + 34 + err = test_pkt_md_access__attach(skel_pkt); 35 + if (CHECK(err, "setup", "classifier/test_pkt_md_access attach failed: %d\n", err)) 36 + goto cleanup; 37 + 38 + prog = skel_pkt->progs.test_pkt_md_access; 39 + pkt_fd = bpf_program__fd(prog); 40 + 41 + /* open extension */ 42 + skel_ext = test_trace_ext__open(); 43 + if (CHECK(!skel_ext, "setup", "freplace/test_pkt_md_access open failed\n")) 44 + goto cleanup; 45 + 46 + /* set extension's attach target - test_pkt_md_access */ 47 + prog = skel_ext->progs.test_pkt_md_access_new; 48 + bpf_program__set_attach_target(prog, pkt_fd, "test_pkt_md_access"); 49 + 50 + /* load/attach extension */ 51 + err = test_trace_ext__load(skel_ext); 52 + if (CHECK(err, "setup", "freplace/test_pkt_md_access load failed\n")) { 53 + libbpf_strerror(err, buf, sizeof(buf)); 54 + fprintf(stderr, "%s\n", buf); 55 + goto cleanup; 56 + } 57 + 58 + err = test_trace_ext__attach(skel_ext); 59 + if (CHECK(err, "setup", "freplace/test_pkt_md_access attach failed: %d\n", err)) 60 + goto cleanup; 61 + 62 + prog = skel_ext->progs.test_pkt_md_access_new; 63 + ext_fd = bpf_program__fd(prog); 64 + 65 + /* open tracing */ 66 + skel_trace = test_trace_ext_tracing__open(); 67 + if (CHECK(!skel_trace, "setup", "tracing/test_pkt_md_access_new open failed\n")) 68 + goto cleanup; 69 + 70 + /* set tracing's attach target - fentry */ 71 + prog = skel_trace->progs.fentry; 72 + bpf_program__set_attach_target(prog, ext_fd, "test_pkt_md_access_new"); 73 + 74 + /* set tracing's attach target - fexit */ 75 + prog = skel_trace->progs.fexit; 76 + bpf_program__set_attach_target(prog, ext_fd, "test_pkt_md_access_new"); 77 + 78 + /* load/attach tracing */ 79 + err = test_trace_ext_tracing__load(skel_trace); 80 + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new load failed\n")) { 81 + libbpf_strerror(err, buf, sizeof(buf)); 82 + fprintf(stderr, "%s\n", buf); 83 + goto cleanup; 84 + } 85 + 86 + err = test_trace_ext_tracing__attach(skel_trace); 87 + if (CHECK(err, "setup", "tracing/test_pkt_md_access_new attach failed: %d\n", err)) 88 + goto cleanup; 89 + 90 + /* trigger the test */ 91 + err = bpf_prog_test_run(pkt_fd, 1, &pkt_v4, sizeof(pkt_v4), 92 + NULL, NULL, &retval, &duration); 93 + CHECK(err || retval, "run", "err %d errno %d retval %d\n", err, errno, retval); 94 + 95 + bss_ext = skel_ext->bss; 96 + bss_trace = skel_trace->bss; 97 + 98 + len = bss_ext->ext_called; 99 + 100 + CHECK(bss_ext->ext_called == 0, 101 + "check", "failed to trigger freplace/test_pkt_md_access\n"); 102 + CHECK(bss_trace->fentry_called != len, 103 + "check", "failed to trigger fentry/test_pkt_md_access_new\n"); 104 + CHECK(bss_trace->fexit_called != len, 105 + "check", "failed to trigger fexit/test_pkt_md_access_new\n"); 106 + 107 + cleanup: 108 + test_trace_ext_tracing__destroy(skel_trace); 109 + test_trace_ext__destroy(skel_ext); 110 + test_pkt_md_access__destroy(skel_pkt); 111 + }
+14
tools/testing/selftests/bpf/progs/fmod_ret_freplace.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/bpf.h> 3 + #include <bpf/bpf_helpers.h> 4 + #include <bpf/bpf_tracing.h> 5 + 6 + volatile __u64 test_fmod_ret = 0; 7 + SEC("fmod_ret/security_new_get_constant") 8 + int BPF_PROG(fmod_ret_test, long val, int ret) 9 + { 10 + test_fmod_ret = 1; 11 + return 120; 12 + } 13 + 14 + char _license[] SEC("license") = "GPL";
+15
tools/testing/selftests/bpf/progs/freplace_get_constant.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/bpf.h> 3 + #include <bpf/bpf_helpers.h> 4 + #include <bpf/bpf_endian.h> 5 + 6 + volatile __u64 test_get_constant = 0; 7 + SEC("freplace/get_constant") 8 + int security_new_get_constant(long val) 9 + { 10 + if (val != 123) 11 + return 0; 12 + test_get_constant = 1; 13 + return test_get_constant; /* original get_constant() returns val - 122 */ 14 + } 15 + char _license[] SEC("license") = "GPL";
+18
tools/testing/selftests/bpf/progs/test_trace_ext.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (c) 2019 Facebook 3 + #include <linux/bpf.h> 4 + #include <stdbool.h> 5 + #include <bpf/bpf_helpers.h> 6 + #include <bpf/bpf_endian.h> 7 + #include <bpf/bpf_tracing.h> 8 + 9 + __u64 ext_called = 0; 10 + 11 + SEC("freplace/test_pkt_md_access") 12 + int test_pkt_md_access_new(struct __sk_buff *skb) 13 + { 14 + ext_called = skb->len; 15 + return 0; 16 + } 17 + 18 + char _license[] SEC("license") = "GPL";
+25
tools/testing/selftests/bpf/progs/test_trace_ext_tracing.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include "vmlinux.h" 4 + #include <bpf/bpf_helpers.h> 5 + #include <bpf/bpf_tracing.h> 6 + 7 + __u64 fentry_called = 0; 8 + 9 + SEC("fentry/test_pkt_md_access_new") 10 + int BPF_PROG(fentry, struct sk_buff *skb) 11 + { 12 + fentry_called = skb->len; 13 + return 0; 14 + } 15 + 16 + __u64 fexit_called = 0; 17 + 18 + SEC("fexit/test_pkt_md_access_new") 19 + int BPF_PROG(fexit, struct sk_buff *skb) 20 + { 21 + fexit_called = skb->len; 22 + return 0; 23 + } 24 + 25 + char _license[] SEC("license") = "GPL";