@@ -560,7 +560,7 @@ static void emit_find_attach_target(struct bpf_gen *gen)
560
560
}
561
561
562
562
void bpf_gen__record_extern (struct bpf_gen * gen , const char * name , bool is_weak ,
563
- bool is_typeless , int kind , int insn_idx )
563
+ bool is_typeless , bool is_ld64 , int kind , int insn_idx )
564
564
{
565
565
struct ksym_relo_desc * relo ;
566
566
@@ -574,6 +574,7 @@ void bpf_gen__record_extern(struct bpf_gen *gen, const char *name, bool is_weak,
574
574
relo -> name = name ;
575
575
relo -> is_weak = is_weak ;
576
576
relo -> is_typeless = is_typeless ;
577
+ relo -> is_ld64 = is_ld64 ;
577
578
relo -> kind = kind ;
578
579
relo -> insn_idx = insn_idx ;
579
580
gen -> relo_cnt ++ ;
@@ -586,9 +587,11 @@ static struct ksym_desc *get_ksym_desc(struct bpf_gen *gen, struct ksym_relo_des
586
587
int i ;
587
588
588
589
for (i = 0 ; i < gen -> nr_ksyms ; i ++ ) {
589
- if (!strcmp (gen -> ksyms [i ].name , relo -> name )) {
590
- gen -> ksyms [i ].ref ++ ;
591
- return & gen -> ksyms [i ];
590
+ kdesc = & gen -> ksyms [i ];
591
+ if (kdesc -> kind == relo -> kind && kdesc -> is_ld64 == relo -> is_ld64 &&
592
+ !strcmp (kdesc -> name , relo -> name )) {
593
+ kdesc -> ref ++ ;
594
+ return kdesc ;
592
595
}
593
596
}
594
597
kdesc = libbpf_reallocarray (gen -> ksyms , gen -> nr_ksyms + 1 , sizeof (* kdesc ));
@@ -603,6 +606,7 @@ static struct ksym_desc *get_ksym_desc(struct bpf_gen *gen, struct ksym_relo_des
603
606
kdesc -> ref = 1 ;
604
607
kdesc -> off = 0 ;
605
608
kdesc -> insn = 0 ;
609
+ kdesc -> is_ld64 = relo -> is_ld64 ;
606
610
return kdesc ;
607
611
}
608
612
@@ -864,23 +868,17 @@ static void emit_relo(struct bpf_gen *gen, struct ksym_relo_desc *relo, int insn
864
868
{
865
869
int insn ;
866
870
867
- pr_debug ("gen: emit_relo (%d): %s at %d\n" , relo -> kind , relo -> name , relo -> insn_idx );
871
+ pr_debug ("gen: emit_relo (%d): %s at %d %s\n" ,
872
+ relo -> kind , relo -> name , relo -> insn_idx , relo -> is_ld64 ? "ld64" : "call" );
868
873
insn = insns + sizeof (struct bpf_insn ) * relo -> insn_idx ;
869
874
emit2 (gen , BPF_LD_IMM64_RAW_FULL (BPF_REG_8 , BPF_PSEUDO_MAP_IDX_VALUE , 0 , 0 , 0 , insn ));
870
- switch (relo -> kind ) {
871
- case BTF_KIND_VAR :
875
+ if (relo -> is_ld64 ) {
872
876
if (relo -> is_typeless )
873
877
emit_relo_ksym_typeless (gen , relo , insn );
874
878
else
875
879
emit_relo_ksym_btf (gen , relo , insn );
876
- break ;
877
- case BTF_KIND_FUNC :
880
+ } else {
878
881
emit_relo_kfunc_btf (gen , relo , insn );
879
- break ;
880
- default :
881
- pr_warn ("Unknown relocation kind '%d'\n" , relo -> kind );
882
- gen -> error = - EDOM ;
883
- return ;
884
882
}
885
883
}
886
884
@@ -903,18 +901,20 @@ static void cleanup_core_relo(struct bpf_gen *gen)
903
901
904
902
static void cleanup_relos (struct bpf_gen * gen , int insns )
905
903
{
904
+ struct ksym_desc * kdesc ;
906
905
int i , insn ;
907
906
908
907
for (i = 0 ; i < gen -> nr_ksyms ; i ++ ) {
908
+ kdesc = & gen -> ksyms [i ];
909
909
/* only close fds for typed ksyms and kfuncs */
910
- if (gen -> ksyms [ i ]. kind == BTF_KIND_VAR && !gen -> ksyms [ i ]. typeless ) {
910
+ if (kdesc -> is_ld64 && !kdesc -> typeless ) {
911
911
/* close fd recorded in insn[insn_idx + 1].imm */
912
- insn = gen -> ksyms [ i ]. insn ;
912
+ insn = kdesc -> insn ;
913
913
insn += sizeof (struct bpf_insn ) + offsetof(struct bpf_insn , imm );
914
914
emit_sys_close_blob (gen , insn );
915
- } else if (gen -> ksyms [ i ]. kind == BTF_KIND_FUNC ) {
916
- emit_sys_close_blob (gen , blob_fd_array_off (gen , gen -> ksyms [ i ]. off ));
917
- if (gen -> ksyms [ i ]. off < MAX_FD_ARRAY_SZ )
915
+ } else if (! kdesc -> is_ld64 ) {
916
+ emit_sys_close_blob (gen , blob_fd_array_off (gen , kdesc -> off ));
917
+ if (kdesc -> off < MAX_FD_ARRAY_SZ )
918
918
gen -> nr_fd_array -- ;
919
919
}
920
920
}
0 commit comments