@@ -674,27 +674,29 @@ static void emit_relo_kfunc_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo
674
674
return ;
675
675
}
676
676
kdesc -> off = btf_fd_idx ;
677
- /* set a default value for imm */
677
+ /* jump to success case */
678
+ emit (gen , BPF_JMP_IMM (BPF_JSGE , BPF_REG_7 , 0 , 3 ));
679
+ /* set value for imm, off as 0 */
678
680
emit (gen , BPF_ST_MEM (BPF_W , BPF_REG_8 , offsetof(struct bpf_insn , imm ), 0 ));
679
- /* skip success case store if ret < 0 */
680
- emit (gen , BPF_JMP_IMM (BPF_JSLT , BPF_REG_7 , 0 , 1 ));
681
+ emit (gen , BPF_ST_MEM (BPF_H , BPF_REG_8 , offsetof(struct bpf_insn , off ), 0 ));
682
+ /* skip success case for ret < 0 */
683
+ emit (gen , BPF_JMP_IMM (BPF_JA , 0 , 0 , 10 ));
681
684
/* store btf_id into insn[insn_idx].imm */
682
685
emit (gen , BPF_STX_MEM (BPF_W , BPF_REG_8 , BPF_REG_7 , offsetof(struct bpf_insn , imm )));
686
+ /* obtain fd in BPF_REG_9 */
687
+ emit (gen , BPF_MOV64_REG (BPF_REG_9 , BPF_REG_7 ));
688
+ emit (gen , BPF_ALU64_IMM (BPF_RSH , BPF_REG_9 , 32 ));
689
+ /* jump to fd_array store if fd denotes module BTF */
690
+ emit (gen , BPF_JMP_IMM (BPF_JNE , BPF_REG_9 , 0 , 2 ));
691
+ /* set the default value for off */
692
+ emit (gen , BPF_ST_MEM (BPF_H , BPF_REG_8 , offsetof(struct bpf_insn , off ), 0 ));
693
+ /* skip BTF fd store for vmlinux BTF */
694
+ emit (gen , BPF_JMP_IMM (BPF_JA , 0 , 0 , 4 ));
683
695
/* load fd_array slot pointer */
684
696
emit2 (gen , BPF_LD_IMM64_RAW_FULL (BPF_REG_0 , BPF_PSEUDO_MAP_IDX_VALUE ,
685
697
0 , 0 , 0 , blob_fd_array_off (gen , btf_fd_idx )));
686
- /* skip store of BTF fd if ret < 0 */
687
- emit (gen , BPF_JMP_IMM (BPF_JSLT , BPF_REG_7 , 0 , 3 ));
688
698
/* store BTF fd in slot */
689
- emit (gen , BPF_MOV64_REG (BPF_REG_9 , BPF_REG_7 ));
690
- emit (gen , BPF_ALU64_IMM (BPF_RSH , BPF_REG_9 , 32 ));
691
699
emit (gen , BPF_STX_MEM (BPF_W , BPF_REG_0 , BPF_REG_9 , 0 ));
692
- /* set a default value for off */
693
- emit (gen , BPF_ST_MEM (BPF_H , BPF_REG_8 , offsetof(struct bpf_insn , off ), 0 ));
694
- /* skip insn->off store if ret < 0 */
695
- emit (gen , BPF_JMP_IMM (BPF_JSLT , BPF_REG_7 , 0 , 2 ));
696
- /* skip if vmlinux BTF */
697
- emit (gen , BPF_JMP_IMM (BPF_JEQ , BPF_REG_9 , 0 , 1 ));
698
700
/* store index into insn[insn_idx].off */
699
701
emit (gen , BPF_ST_MEM (BPF_H , BPF_REG_8 , offsetof(struct bpf_insn , off ), btf_fd_idx ));
700
702
log :
@@ -803,17 +805,20 @@ static void emit_relo_ksym_btf(struct bpf_gen *gen, struct ksym_relo_desc *relo,
803
805
emit_bpf_find_by_name_kind (gen , relo );
804
806
if (!relo -> is_weak )
805
807
emit_check_err (gen );
806
- /* set default values as 0 */
808
+ /* jump to success case */
809
+ emit (gen , BPF_JMP_IMM (BPF_JSGE , BPF_REG_7 , 0 , 3 ));
810
+ /* set values for insn[insn_idx].imm, insn[insn_idx + 1].imm as 0 */
807
811
emit (gen , BPF_ST_MEM (BPF_W , BPF_REG_8 , offsetof(struct bpf_insn , imm ), 0 ));
808
812
emit (gen , BPF_ST_MEM (BPF_W , BPF_REG_8 , sizeof (struct bpf_insn ) + offsetof(struct bpf_insn , imm ), 0 ));
809
- /* skip success case stores if ret < 0 */
810
- emit (gen , BPF_JMP_IMM (BPF_JSLT , BPF_REG_7 , 0 , 4 ));
813
+ /* skip success case for ret < 0 */
814
+ emit (gen , BPF_JMP_IMM (BPF_JA , 0 , 0 , 4 ));
811
815
/* store btf_id into insn[insn_idx].imm */
812
816
emit (gen , BPF_STX_MEM (BPF_W , BPF_REG_8 , BPF_REG_7 , offsetof(struct bpf_insn , imm )));
813
817
/* store btf_obj_fd into insn[insn_idx + 1].imm */
814
818
emit (gen , BPF_ALU64_IMM (BPF_RSH , BPF_REG_7 , 32 ));
815
819
emit (gen , BPF_STX_MEM (BPF_W , BPF_REG_8 , BPF_REG_7 ,
816
820
sizeof (struct bpf_insn ) + offsetof(struct bpf_insn , imm )));
821
+ /* skip src_reg adjustment */
817
822
emit (gen , BPF_JMP_IMM (BPF_JSGE , BPF_REG_7 , 0 , 3 ));
818
823
clear_src_reg :
819
824
/* clear bpf_object__relocate_data's src_reg assignment, otherwise we get a verifier failure */
0 commit comments