Linux�ɂ����闘�p���}���ɑ����Ă���uBerkeley Packet Filter�iBPF�j�v�ɂ��āA��b���牞�p�܂ŕ��L���Љ��A�ځB����́A�ŋ߂�BPF�̔��W�Ɍ��������Ƃ̂ł��Ȃ��d�v�@�\�uBPF Type Format�iBTF�j�v�ɂ��āB
�@Linux�ɂ����闘�p���}���ɑ����Ă���uBerkeley Packet Filter�iBPF�j�v�ɂ��āA��b���牞�p�܂ŕ��L���Љ��A�ځuBerkeley Packet Filter�iBPF�j����v�B����́A�ŋ߂�BPF�̔��W�Ɍ��������Ƃ̂ł��Ȃ��d�v�@�\�uBPF Type Format�iBTF�j�v���Љ�܂��B
�@BPF�v���O�����͎��C����ŋL�q���邱�Ƃ������ł����A�J�[�l���Ƀ��[�h�����̂̓R���p�C�����ꂽ�o�C�i���f�[�^�ł��B�u�J�[�l���ɂǂ̂悤��BPF�v���O���������[�h���Ă��邩�v�Ƃ������Ƃ͌ォ��m�F�ł��܂����A�����̃o�C�i���f�[�^�����ł͂���BPF�v���O��������������̂���������͍̂���ł��B
�@��ʂ̃v���O�����ł́A�R���p�C�������o�C�i���f�[�^�ɂ��̃v���O�����̃\�[�X�̏���f�[�^�\���̏����u�f�o�b�O���v�Ƃ����`�Ŏ������邱�Ƃ��ł��܂��B��\�I�ȃf�o�b�O���̃t�H�[�}�b�g�ɁuDWARF�v������܂��BDWARF�𗘗p���邱�ƂŁA�o�C�i���R�[�h�ɑΉ������\�[�X�R�[�h�̈ʒu����̈����̌^���Ȃǂ������܂��B
�@BPF Type Format�iBTF�j�́ADWARF�̂悤�ɁABPF�v���O�����̃\�[�X����f�[�^�\����ێ����邽�߂̃f�[�^�t�H�[�}�b�g�ł��BBPF�v���O������⏕���邽�߂̃��^�f�[�^���Ǝv���Ε�����₷���ł��傤�BBTF��BPF�v���O�����̃f�o�b�O�݂̂ł͂Ȃ��ABPF�̂��܂��܂ȋ@�\�����̂��߂ɗ��p����Ă��܂��B
�@BTF�̋�̓I�Ȏd�l�́A�J�[�l���̃h�L�������g���Q�Ƃ��Ă��������BDWARF�̃f�o�b�O���̓T�C�Y���傫�����Ƃ�����A��ʂɃv���O�����̃f�o�b�O������Ƃ��������̋@�\��L���ɂ��邱�Ƃ������ł��B�����BTF�́ABPF�𗘗p����ꍇ�͏�ɂ��邱�Ɓi���邢�́A��ɂ����Ă����Ȃ����Ɓj��z�肵�Ă��܂��B���̂��߁ABTF��BPF�v���O�����ɓ��������v�ɂȂ��Ă���A�ێ���������i�邱�Ƃł��̃T�C�Y�����������Ă��܂��B
�@BTF�̎g�p�p�r�͑傫��2�ɕ������܂��B1�ڂ́ABPF�v���O�����̃f�o�b�O���Ƃ��Ă̗��p�ł��B������2�ڂ́ALinux�J�[�l���̃f�[�^�\�������擾���邽�߂̗��p�ł��B�ȍ~�A���ꂼ��ɂ��Đ������܂��B
�@Clang�ɂ�BTF�̃T�|�[�g���܂܂�Ă��܂��B�f�o�b�O����BPF�v���O�������R���p�C������ƁABTF����������܂��B�������ꂽBTF�͓����ELF�Z�N�V�����i.BTF�����.BTF.ext�j�Ɋi�[����܂��B�Ⴆ�A���L�̂悤�ɂ���C����̃t�@�C������BTF�������ł��܂��B
% clang -target bpf -g -c a.c % readelf -S a.o There are 16 section headers, starting at offset 0x6c0: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align ... [ 5] .BTF PROGBITS 0000000000000000 000001cb 00000000000000de 0000000000000000 0 0 1 [ 6] .BTF.ext PROGBITS 0000000000000000 000002a9 0000000000000070 0000000000000000 0 0 1 ...
�@�܂��A�upahole�v�Ƃ����c�[���𗘗p���āADWARF�̏���BTF�ɕϊ����邱�Ƃ��\�ł��B
�@�������ē�����BTF�̃f�[�^��BPF�v���O�����̃��[�h����}�b�v�쐬���Ɏw�肷�邱�ƂŁA�����BPF�v���O������BPF�}�b�v��BTF�̏����Ђ��t���邱�Ƃ��ł��܂��BBTF�̏���BPF�v���O������}�b�v�ƈꏏ�ɃJ�[�l�����ɕێ�����A�ォ�炻�̏����Q�Ƃ��邱�Ƃ��ł��܂��B
�@�A�ڑ�6���ŏЉ���ABPF�v���O�����쐬�̂��߂̃��C�u�����uBPF Compiler Collection�iBCC�j�v�ɂ́ABTF�̃T�|�[�g���܂܂�Ă��܂��BBTF�𗘗p���邱�ƂŁA�R���p�C�������v���O�����ƃ\�[�X�R�[�h���̑Ή��t����A�쐬�����}�b�v�̃f�[�^�\���̎擾�Ȃǂ��\�ł��B
�@��Ƃ��āA���L��BCC�v���O�������l���܂��B
#!/usr/bin/env python import bcc text = r""" #include <linux/ptrace.h> struct data_t { u32 a; u32 b; }; BPF_HASH(hash, int, struct data_t); int func(volatile struct pt_regs *ctx) { struct data_t data = { .a = 1, .b = 2 }; int key = 0; hash.update(&key, &data); return 0; } """ b = bcc.BPF(text=text, debug=0x8) b.attach_perf_event(ev_type=bcc.PerfType.SOFTWARE, ev_config=bcc.PerfSWConfig.CPU_CLOCK, fn_name="func", sample_freq=1, cpu=0) b.trace_print()
�@�����ŁA�ubcc.BPF(text=text, debug=0x8)�v�ƁABCC�ŃR���p�C������ۂɈ����́udebug�v��0x8��n���ƁABCC��BTF�̏����_���v���܂��B���L�ɏo�͗�������܂��B
% sudo ./example.py Disassembly of section .bpf.fn.func: func: ; int func(volatile struct pt_regs *ctx) { // Line 22 0: 18 01 00 00 01 00 00 00 00 00 00 00 02 00 00 00 r1 = 8589934593 ll ; struct data_t data = { .a = 1, .b = 2 }; // Line 24 2: 7b 1a f8 ff 00 00 00 00 *(u64 *)(r10 - 8) = r1 3: b7 01 00 00 00 00 00 00 r1 = 0 ; int key = 0; // Line 25 4: 63 1a f4 ff 00 00 00 00 *(u32 *)(r10 - 12) = r1 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &key, &data, BPF_ANY); // Line 26 5: 18 11 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 ld_pseudo r1, 1, 4294967295 7: bf a2 00 00 00 00 00 00 r2 = r10 8: 07 02 00 00 f4 ff ff ff r2 += -12 9: bf a3 00 00 00 00 00 00 r3 = r10 10: 07 03 00 00 f8 ff ff ff r3 += -8 11: b7 04 00 00 00 00 00 00 r4 = 0 12: 85 00 00 00 02 00 00 00 call 2 ; return 0; // Line 27 13: b7 00 00 00 00 00 00 00 r0 = 0 14: 95 00 00 00 00 00 00 00 exit
�@���̂悤�ɁABTF�̃f�[�^�Ɋ�Â��ABPF�̃o�C�i���ƃ\�[�X�R�[�h�̑Ή���������܂��B�Ȃ��A��L�̃\�[�X�R�[�h��BTF�ɂ��o�͂ɂ��\�[�X�R�[�h���ꕔ�Ⴄ�̂́ABCC���v���O���������[�h����ۂɃ\�[�X�R�[�h�̈ꕔ���������������߂ł��B
�@���ꂾ���ł͏������肪���݂�������ɂ�����������܂���B�ʂ̗�Ƃ��āA���L�̂悤�Ƀv���O�������ꕔ���������Ď��s���Ă��܂��B
int func(volatile struct pt_regs *ctx) { struct data_t data = { .a = 1, .b = 2 }; int key = 0; hash.update(&ctx->ax, &data); // &key ���� &ctx->ax �ɕύX return 0; }
�@����ƁA���L�̂悤�ȃG���[�������܂��B
% sudo ./example.py [...] bpf: Failed to load program: Permission denied Unrecognized arg#0 type PTR ; int func(volatile struct pt_regs *ctx) { 0: (bf) r2 = r1 1: (18) r1 = 0x200000001 ; struct data_t data = { .a = 1, .b = 2 }; 3: (7b) *(u64 *)(r10 -8) = r1 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &ctx->ax, &data, BPF_ANY); 4: (18) r1 = 0xffff9e28933be800 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &ctx->ax, &data, BPF_ANY); 6: (07) r2 += 80 7: (bf) r3 = r10 ; 8: (07) r3 += -8 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &ctx->ax, &data, BPF_ANY); 9: (b7) r4 = 0 10: (85) call bpf_map_update_elem#2 R2 type=ctx expected=fp processed 9 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0 [...]
�@�����ł́A�ubpf_map_update_elem()�v��key�̈����̓X�^�b�N��̕ϐ��łȂ�������Ȃ����߁A�G���[�ɂȂ��Ă��܂��BBPF�̌��؊�̃G���[���b�Z�[�W�́A���̂܂܂ł͕�����ɂ������̂������ł����A����̂悤�Ɂu�ǂ̃\�[�X�̉ӏ�����肩�v�������邾���ŁA�f�o�b�O���₷���Ȃ�܂��B
�@bpftool�𗘗p���邱�ƂŁA�J�[�l���Ƀ��[�h����BPF�̏����擾���邱�Ƃ��ł��܂��B��q��BCC�̃v���O���������s������ԂŁA�ȉ��̂悤��bpftool�Ń��[�h�����v���O�������m�F�ł��܂��B
% sudo bpftool prog [...] 1518: perf_event name func tag f54b2f831fe8b42d gpl loaded_at 2020-07-20T13:52:58+0900 uid 0 xlated 120B jited 87B memlock 4096B map_ids 1404 btf_id 17
�@�ȉ��̂悤�ɂ��āA���[�h�����v���O�������_���v���邱�Ƃ��ł��܂��BBCC��BTF�t���Ńv���O���������[�h�������߁A�\�[�X�̏����m�F�ł��܂��B
% sudo bpftool prog dump xlated id 1518 int func(volatile struct pt_regs * ctx): ; int func(volatile struct pt_regs *ctx) { 0: (18) r1 = 0x200000001 ; struct data_t data = { .a = 1, .b = 2 }; 2: (7b) *(u64 *)(r10 -8) = r1 3: (b7) r1 = 0 ; int key = 0; 4: (63) *(u32 *)(r10 -12) = r1 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &key, &data, BPF_ANY); 5: (18) r1 = map[id:1404] 7: (bf) r2 = r10 ; 8: (07) r2 += -12 9: (bf) r3 = r10 10: (07) r3 += -8 ; bpf_map_update_elem((void *)bpf_pseudo_fd(1, -1), &key, &data, BPF_ANY); 11: (b7) r4 = 0 12: (85) call htab_map_update_elem#123424 ; return 0; 13: (b7) r0 = 0 14: (95) exit
�@�܂��A�ȉ��̂悤��BPF�}�b�v���_���v���邱�Ƃ��ł��܂��B
% sudo bpftool map [...] 1404: hash name hash flags 0x0 key 4B value 8B max_entries 10240 memlock 921600B btf_id 17 % sudo bpftool map dump id 1404 [{ "key": 0, "value": { "a": 1, "b": 2 } } ]
�@�����ŁA�_���v�����ۂɂ��̃t�B�[���h���i�ua�v����сub�v�j�Ƃ��̒l���\�������̂�BTF�̌^���̂������ł��B������BTF���Ȃ�������A������8�o�C�g�i�t�B�[���h�ua�v�Ɓub�v�̍��v�T�C�Y�j�̒l���_���v����邱�ƂɂȂ�܂��B
Copyright © ITmedia, Inc. All Rights Reserved.