@@ -4972,33 +4972,69 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog,
49724972 */
49734973#define BPF_APROG_COMPAT (string , ptype ) BPF_PROG_SEC(string, ptype)
49744974
4975- static const struct {
4975+ #define SEC_DEF (sec_pfx , ptype , ...) { \
4976+ .sec = sec_pfx, \
4977+ .len = sizeof(sec_pfx) - 1, \
4978+ .prog_type = BPF_PROG_TYPE_##ptype, \
4979+ __VA_ARGS__ \
4980+ }
4981+
4982+ struct bpf_sec_def ;
4983+
4984+ typedef struct bpf_link * (* attach_fn_t )(const struct bpf_sec_def * sec ,
4985+ struct bpf_program * prog );
4986+
4987+ static struct bpf_link * attach_kprobe (const struct bpf_sec_def * sec ,
4988+ struct bpf_program * prog );
4989+ static struct bpf_link * attach_tp (const struct bpf_sec_def * sec ,
4990+ struct bpf_program * prog );
4991+ static struct bpf_link * attach_raw_tp (const struct bpf_sec_def * sec ,
4992+ struct bpf_program * prog );
4993+ static struct bpf_link * attach_trace (const struct bpf_sec_def * sec ,
4994+ struct bpf_program * prog );
4995+
4996+ struct bpf_sec_def {
49764997 const char * sec ;
49774998 size_t len ;
49784999 enum bpf_prog_type prog_type ;
49795000 enum bpf_attach_type expected_attach_type ;
49805001 bool is_attachable ;
49815002 bool is_attach_btf ;
49825003 enum bpf_attach_type attach_type ;
4983- } section_names [] = {
5004+ attach_fn_t attach_fn ;
5005+ };
5006+
5007+ static const struct bpf_sec_def section_defs [] = {
49845008 BPF_PROG_SEC ("socket" , BPF_PROG_TYPE_SOCKET_FILTER ),
49855009 BPF_PROG_SEC ("sk_reuseport" , BPF_PROG_TYPE_SK_REUSEPORT ),
4986- BPF_PROG_SEC ("kprobe/" , BPF_PROG_TYPE_KPROBE ),
5010+ SEC_DEF ("kprobe/" , KPROBE ,
5011+ .attach_fn = attach_kprobe ),
49875012 BPF_PROG_SEC ("uprobe/" , BPF_PROG_TYPE_KPROBE ),
4988- BPF_PROG_SEC ("kretprobe/" , BPF_PROG_TYPE_KPROBE ),
5013+ SEC_DEF ("kretprobe/" , KPROBE ,
5014+ .attach_fn = attach_kprobe ),
49895015 BPF_PROG_SEC ("uretprobe/" , BPF_PROG_TYPE_KPROBE ),
49905016 BPF_PROG_SEC ("classifier" , BPF_PROG_TYPE_SCHED_CLS ),
49915017 BPF_PROG_SEC ("action" , BPF_PROG_TYPE_SCHED_ACT ),
4992- BPF_PROG_SEC ("tracepoint/" , BPF_PROG_TYPE_TRACEPOINT ),
4993- BPF_PROG_SEC ("tp/" , BPF_PROG_TYPE_TRACEPOINT ),
4994- BPF_PROG_SEC ("raw_tracepoint/" , BPF_PROG_TYPE_RAW_TRACEPOINT ),
4995- BPF_PROG_SEC ("raw_tp/" , BPF_PROG_TYPE_RAW_TRACEPOINT ),
4996- BPF_PROG_BTF ("tp_btf/" , BPF_PROG_TYPE_TRACING ,
4997- BPF_TRACE_RAW_TP ),
4998- BPF_PROG_BTF ("fentry/" , BPF_PROG_TYPE_TRACING ,
4999- BPF_TRACE_FENTRY ),
5000- BPF_PROG_BTF ("fexit/" , BPF_PROG_TYPE_TRACING ,
5001- BPF_TRACE_FEXIT ),
5018+ SEC_DEF ("tracepoint/" , TRACEPOINT ,
5019+ .attach_fn = attach_tp ),
5020+ SEC_DEF ("tp/" , TRACEPOINT ,
5021+ .attach_fn = attach_tp ),
5022+ SEC_DEF ("raw_tracepoint/" , RAW_TRACEPOINT ,
5023+ .attach_fn = attach_raw_tp ),
5024+ SEC_DEF ("raw_tp/" , RAW_TRACEPOINT ,
5025+ .attach_fn = attach_raw_tp ),
5026+ SEC_DEF ("tp_btf/" , TRACING ,
5027+ .expected_attach_type = BPF_TRACE_RAW_TP ,
5028+ .is_attach_btf = true,
5029+ .attach_fn = attach_trace ),
5030+ SEC_DEF ("fentry/" , TRACING ,
5031+ .expected_attach_type = BPF_TRACE_FENTRY ,
5032+ .is_attach_btf = true,
5033+ .attach_fn = attach_trace ),
5034+ SEC_DEF ("fexit/" , TRACING ,
5035+ .expected_attach_type = BPF_TRACE_FEXIT ,
5036+ .is_attach_btf = true,
5037+ .attach_fn = attach_trace ),
50025038 BPF_PROG_SEC ("xdp" , BPF_PROG_TYPE_XDP ),
50035039 BPF_PROG_SEC ("perf_event" , BPF_PROG_TYPE_PERF_EVENT ),
50045040 BPF_PROG_SEC ("lwt_in" , BPF_PROG_TYPE_LWT_IN ),
@@ -5060,12 +5096,26 @@ static const struct {
50605096#undef BPF_APROG_SEC
50615097#undef BPF_EAPROG_SEC
50625098#undef BPF_APROG_COMPAT
5099+ #undef SEC_DEF
50635100
50645101#define MAX_TYPE_NAME_SIZE 32
50655102
5103+ static const struct bpf_sec_def * find_sec_def (const char * sec_name )
5104+ {
5105+ int i , n = ARRAY_SIZE (section_defs );
5106+
5107+ for (i = 0 ; i < n ; i ++ ) {
5108+ if (strncmp (sec_name ,
5109+ section_defs [i ].sec , section_defs [i ].len ))
5110+ continue ;
5111+ return & section_defs [i ];
5112+ }
5113+ return NULL ;
5114+ }
5115+
50665116static char * libbpf_get_type_names (bool attach_type )
50675117{
5068- int i , len = ARRAY_SIZE (section_names ) * MAX_TYPE_NAME_SIZE ;
5118+ int i , len = ARRAY_SIZE (section_defs ) * MAX_TYPE_NAME_SIZE ;
50695119 char * buf ;
50705120
50715121 buf = malloc (len );
@@ -5074,16 +5124,16 @@ static char *libbpf_get_type_names(bool attach_type)
50745124
50755125 buf [0 ] = '\0' ;
50765126 /* Forge string buf with all available names */
5077- for (i = 0 ; i < ARRAY_SIZE (section_names ); i ++ ) {
5078- if (attach_type && !section_names [i ].is_attachable )
5127+ for (i = 0 ; i < ARRAY_SIZE (section_defs ); i ++ ) {
5128+ if (attach_type && !section_defs [i ].is_attachable )
50795129 continue ;
50805130
5081- if (strlen (buf ) + strlen (section_names [i ].sec ) + 2 > len ) {
5131+ if (strlen (buf ) + strlen (section_defs [i ].sec ) + 2 > len ) {
50825132 free (buf );
50835133 return NULL ;
50845134 }
50855135 strcat (buf , " " );
5086- strcat (buf , section_names [i ].sec );
5136+ strcat (buf , section_defs [i ].sec );
50875137 }
50885138
50895139 return buf ;
@@ -5092,19 +5142,19 @@ static char *libbpf_get_type_names(bool attach_type)
50925142int libbpf_prog_type_by_name (const char * name , enum bpf_prog_type * prog_type ,
50935143 enum bpf_attach_type * expected_attach_type )
50945144{
5145+ const struct bpf_sec_def * sec_def ;
50955146 char * type_names ;
5096- int i ;
50975147
50985148 if (!name )
50995149 return - EINVAL ;
51005150
5101- for (i = 0 ; i < ARRAY_SIZE (section_names ); i ++ ) {
5102- if (strncmp (name , section_names [i ].sec , section_names [i ].len ))
5103- continue ;
5104- * prog_type = section_names [i ].prog_type ;
5105- * expected_attach_type = section_names [i ].expected_attach_type ;
5151+ sec_def = find_sec_def (name );
5152+ if (sec_def ) {
5153+ * prog_type = sec_def -> prog_type ;
5154+ * expected_attach_type = sec_def -> expected_attach_type ;
51065155 return 0 ;
51075156 }
5157+
51085158 pr_warn ("failed to guess program type from ELF section '%s'\n" , name );
51095159 type_names = libbpf_get_type_names (false);
51105160 if (type_names != NULL ) {
@@ -5187,16 +5237,16 @@ static int libbpf_find_attach_btf_id(const char *name,
51875237 if (!name )
51885238 return - EINVAL ;
51895239
5190- for (i = 0 ; i < ARRAY_SIZE (section_names ); i ++ ) {
5191- if (!section_names [i ].is_attach_btf )
5240+ for (i = 0 ; i < ARRAY_SIZE (section_defs ); i ++ ) {
5241+ if (!section_defs [i ].is_attach_btf )
51925242 continue ;
5193- if (strncmp (name , section_names [i ].sec , section_names [i ].len ))
5243+ if (strncmp (name , section_defs [i ].sec , section_defs [i ].len ))
51945244 continue ;
51955245 if (attach_prog_fd )
5196- err = libbpf_find_prog_btf_id (name + section_names [i ].len ,
5246+ err = libbpf_find_prog_btf_id (name + section_defs [i ].len ,
51975247 attach_prog_fd );
51985248 else
5199- err = libbpf_find_vmlinux_btf_id (name + section_names [i ].len ,
5249+ err = libbpf_find_vmlinux_btf_id (name + section_defs [i ].len ,
52005250 attach_type );
52015251 if (err <= 0 )
52025252 pr_warn ("%s is not found in vmlinux BTF\n" , name );
@@ -5215,12 +5265,12 @@ int libbpf_attach_type_by_name(const char *name,
52155265 if (!name )
52165266 return - EINVAL ;
52175267
5218- for (i = 0 ; i < ARRAY_SIZE (section_names ); i ++ ) {
5219- if (strncmp (name , section_names [i ].sec , section_names [i ].len ))
5268+ for (i = 0 ; i < ARRAY_SIZE (section_defs ); i ++ ) {
5269+ if (strncmp (name , section_defs [i ].sec , section_defs [i ].len ))
52205270 continue ;
5221- if (!section_names [i ].is_attachable )
5271+ if (!section_defs [i ].is_attachable )
52225272 return - EINVAL ;
5223- * attach_type = section_names [i ].attach_type ;
5273+ * attach_type = section_defs [i ].attach_type ;
52245274 return 0 ;
52255275 }
52265276 pr_warn ("failed to guess attach type based on ELF section name '%s'\n" , name );
@@ -5680,6 +5730,18 @@ struct bpf_link *bpf_program__attach_kprobe(struct bpf_program *prog,
56805730 return link ;
56815731}
56825732
5733+ static struct bpf_link * attach_kprobe (const struct bpf_sec_def * sec ,
5734+ struct bpf_program * prog )
5735+ {
5736+ const char * func_name ;
5737+ bool retprobe ;
5738+
5739+ func_name = bpf_program__title (prog , false) + sec -> len ;
5740+ retprobe = strcmp (sec -> sec , "kretprobe/" ) == 0 ;
5741+
5742+ return bpf_program__attach_kprobe (prog , retprobe , func_name );
5743+ }
5744+
56835745struct bpf_link * bpf_program__attach_uprobe (struct bpf_program * prog ,
56845746 bool retprobe , pid_t pid ,
56855747 const char * binary_path ,
@@ -5792,6 +5854,32 @@ struct bpf_link *bpf_program__attach_tracepoint(struct bpf_program *prog,
57925854 return link ;
57935855}
57945856
5857+ static struct bpf_link * attach_tp (const struct bpf_sec_def * sec ,
5858+ struct bpf_program * prog )
5859+ {
5860+ char * sec_name , * tp_cat , * tp_name ;
5861+ struct bpf_link * link ;
5862+
5863+ sec_name = strdup (bpf_program__title (prog , false));
5864+ if (!sec_name )
5865+ return ERR_PTR (- ENOMEM );
5866+
5867+ /* extract "tp/<category>/<name>" */
5868+ tp_cat = sec_name + sec -> len ;
5869+ tp_name = strchr (tp_cat , '/' );
5870+ if (!tp_name ) {
5871+ link = ERR_PTR (- EINVAL );
5872+ goto out ;
5873+ }
5874+ * tp_name = '\0' ;
5875+ tp_name ++ ;
5876+
5877+ link = bpf_program__attach_tracepoint (prog , tp_cat , tp_name );
5878+ out :
5879+ free (sec_name );
5880+ return link ;
5881+ }
5882+
57955883static int bpf_link__destroy_fd (struct bpf_link * link )
57965884{
57975885 struct bpf_link_fd * l = (void * )link ;
@@ -5831,6 +5919,14 @@ struct bpf_link *bpf_program__attach_raw_tracepoint(struct bpf_program *prog,
58315919 return (struct bpf_link * )link ;
58325920}
58335921
5922+ static struct bpf_link * attach_raw_tp (const struct bpf_sec_def * sec ,
5923+ struct bpf_program * prog )
5924+ {
5925+ const char * tp_name = bpf_program__title (prog , false) + sec -> len ;
5926+
5927+ return bpf_program__attach_raw_tracepoint (prog , tp_name );
5928+ }
5929+
58345930struct bpf_link * bpf_program__attach_trace (struct bpf_program * prog )
58355931{
58365932 char errmsg [STRERR_BUFSIZE ];
@@ -5862,6 +5958,23 @@ struct bpf_link *bpf_program__attach_trace(struct bpf_program *prog)
58625958 return (struct bpf_link * )link ;
58635959}
58645960
5961+ static struct bpf_link * attach_trace (const struct bpf_sec_def * sec ,
5962+ struct bpf_program * prog )
5963+ {
5964+ return bpf_program__attach_trace (prog );
5965+ }
5966+
5967+ struct bpf_link * bpf_program__attach (struct bpf_program * prog )
5968+ {
5969+ const struct bpf_sec_def * sec_def ;
5970+
5971+ sec_def = find_sec_def (bpf_program__title (prog , false));
5972+ if (!sec_def || !sec_def -> attach_fn )
5973+ return ERR_PTR (- ESRCH );
5974+
5975+ return sec_def -> attach_fn (sec_def , prog );
5976+ }
5977+
58655978enum bpf_perf_event_ret
58665979bpf_perf_event_read_simple (void * mmap_mem , size_t mmap_size , size_t page_size ,
58675980 void * * copy_mem , size_t * copy_size ,
0 commit comments