@@ -3192,86 +3192,6 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
3192
3192
}
3193
3193
}
3194
3194
3195
- if (!kernel_supports (obj , FEAT_BTF_DECL_TAG ))
3196
- goto skip_exception_cb ;
3197
- for (i = 0 ; i < obj -> nr_programs ; i ++ ) {
3198
- struct bpf_program * prog = & obj -> programs [i ];
3199
- int j , k , n ;
3200
-
3201
- if (prog_is_subprog (obj , prog ))
3202
- continue ;
3203
- n = btf__type_cnt (obj -> btf );
3204
- for (j = 1 ; j < n ; j ++ ) {
3205
- const char * str = "exception_callback:" , * name ;
3206
- size_t len = strlen (str );
3207
- struct btf_type * t ;
3208
-
3209
- t = btf_type_by_id (obj -> btf , j );
3210
- if (!btf_is_decl_tag (t ) || btf_decl_tag (t )-> component_idx != -1 )
3211
- continue ;
3212
-
3213
- name = btf__str_by_offset (obj -> btf , t -> name_off );
3214
- if (strncmp (name , str , len ))
3215
- continue ;
3216
-
3217
- t = btf_type_by_id (obj -> btf , t -> type );
3218
- if (!btf_is_func (t ) || btf_func_linkage (t ) != BTF_FUNC_GLOBAL ) {
3219
- pr_warn ("prog '%s': exception_callback:<value> decl tag not applied to the main program\n" ,
3220
- prog -> name );
3221
- return - EINVAL ;
3222
- }
3223
- if (strcmp (prog -> name , btf__str_by_offset (obj -> btf , t -> name_off )))
3224
- continue ;
3225
- /* Multiple callbacks are specified for the same prog,
3226
- * the verifier will eventually return an error for this
3227
- * case, hence simply skip appending a subprog.
3228
- */
3229
- if (prog -> exception_cb_idx >= 0 ) {
3230
- prog -> exception_cb_idx = -1 ;
3231
- break ;
3232
- }
3233
-
3234
- name += len ;
3235
- if (str_is_empty (name )) {
3236
- pr_warn ("prog '%s': exception_callback:<value> decl tag contains empty value\n" ,
3237
- prog -> name );
3238
- return - EINVAL ;
3239
- }
3240
-
3241
- for (k = 0 ; k < obj -> nr_programs ; k ++ ) {
3242
- struct bpf_program * subprog = & obj -> programs [k ];
3243
-
3244
- if (!prog_is_subprog (obj , subprog ))
3245
- continue ;
3246
- if (strcmp (name , subprog -> name ))
3247
- continue ;
3248
- /* Enforce non-hidden, as from verifier point of
3249
- * view it expects global functions, whereas the
3250
- * mark_btf_static fixes up linkage as static.
3251
- */
3252
- if (!subprog -> sym_global || subprog -> mark_btf_static ) {
3253
- pr_warn ("prog '%s': exception callback %s must be a global non-hidden function\n" ,
3254
- prog -> name , subprog -> name );
3255
- return - EINVAL ;
3256
- }
3257
- /* Let's see if we already saw a static exception callback with the same name */
3258
- if (prog -> exception_cb_idx >= 0 ) {
3259
- pr_warn ("prog '%s': multiple subprogs with same name as exception callback '%s'\n" ,
3260
- prog -> name , subprog -> name );
3261
- return - EINVAL ;
3262
- }
3263
- prog -> exception_cb_idx = k ;
3264
- break ;
3265
- }
3266
-
3267
- if (prog -> exception_cb_idx >= 0 )
3268
- continue ;
3269
- pr_warn ("prog '%s': cannot find exception callback '%s'\n" , prog -> name , name );
3270
- return - ENOENT ;
3271
- }
3272
- }
3273
- skip_exception_cb :
3274
-
3275
3195
sanitize = btf_needs_sanitization (obj );
3276
3196
if (sanitize ) {
3277
3197
const void * raw_data ;
@@ -6661,6 +6581,88 @@ static void bpf_object__sort_relos(struct bpf_object *obj)
6661
6581
}
6662
6582
}
6663
6583
6584
+ static int bpf_prog_assign_exc_cb (struct bpf_object * obj , struct bpf_program * prog )
6585
+ {
6586
+ const char * str = "exception_callback:" ;
6587
+ size_t pfx_len = strlen (str );
6588
+ int i , j , n ;
6589
+
6590
+ if (!obj -> btf || !kernel_supports (obj , FEAT_BTF_DECL_TAG ))
6591
+ return 0 ;
6592
+
6593
+ n = btf__type_cnt (obj -> btf );
6594
+ for (i = 1 ; i < n ; i ++ ) {
6595
+ const char * name ;
6596
+ struct btf_type * t ;
6597
+
6598
+ t = btf_type_by_id (obj -> btf , i );
6599
+ if (!btf_is_decl_tag (t ) || btf_decl_tag (t )-> component_idx != -1 )
6600
+ continue ;
6601
+
6602
+ name = btf__str_by_offset (obj -> btf , t -> name_off );
6603
+ if (strncmp (name , str , pfx_len ) != 0 )
6604
+ continue ;
6605
+
6606
+ t = btf_type_by_id (obj -> btf , t -> type );
6607
+ if (!btf_is_func (t ) || btf_func_linkage (t ) != BTF_FUNC_GLOBAL ) {
6608
+ pr_warn ("prog '%s': exception_callback:<value> decl tag not applied to the main program\n" ,
6609
+ prog -> name );
6610
+ return - EINVAL ;
6611
+ }
6612
+ if (strcmp (prog -> name , btf__str_by_offset (obj -> btf , t -> name_off )) != 0 )
6613
+ continue ;
6614
+ /* Multiple callbacks are specified for the same prog,
6615
+ * the verifier will eventually return an error for this
6616
+ * case, hence simply skip appending a subprog.
6617
+ */
6618
+ if (prog -> exception_cb_idx >= 0 ) {
6619
+ prog -> exception_cb_idx = -1 ;
6620
+ break ;
6621
+ }
6622
+
6623
+ name += pfx_len ;
6624
+ if (str_is_empty (name )) {
6625
+ pr_warn ("prog '%s': exception_callback:<value> decl tag contains empty value\n" ,
6626
+ prog -> name );
6627
+ return - EINVAL ;
6628
+ }
6629
+
6630
+ for (j = 0 ; j < obj -> nr_programs ; j ++ ) {
6631
+ struct bpf_program * subprog = & obj -> programs [j ];
6632
+
6633
+ if (!prog_is_subprog (obj , subprog ))
6634
+ continue ;
6635
+ if (strcmp (name , subprog -> name ) != 0 )
6636
+ continue ;
6637
+ /* Enforce non-hidden, as from verifier point of
6638
+ * view it expects global functions, whereas the
6639
+ * mark_btf_static fixes up linkage as static.
6640
+ */
6641
+ if (!subprog -> sym_global || subprog -> mark_btf_static ) {
6642
+ pr_warn ("prog '%s': exception callback %s must be a global non-hidden function\n" ,
6643
+ prog -> name , subprog -> name );
6644
+ return - EINVAL ;
6645
+ }
6646
+ /* Let's see if we already saw a static exception callback with the same name */
6647
+ if (prog -> exception_cb_idx >= 0 ) {
6648
+ pr_warn ("prog '%s': multiple subprogs with same name as exception callback '%s'\n" ,
6649
+ prog -> name , subprog -> name );
6650
+ return - EINVAL ;
6651
+ }
6652
+ prog -> exception_cb_idx = j ;
6653
+ break ;
6654
+ }
6655
+
6656
+ if (prog -> exception_cb_idx >= 0 )
6657
+ continue ;
6658
+
6659
+ pr_warn ("prog '%s': cannot find exception callback '%s'\n" , prog -> name , name );
6660
+ return - ENOENT ;
6661
+ }
6662
+
6663
+ return 0 ;
6664
+ }
6665
+
6664
6666
static int
6665
6667
bpf_object__relocate (struct bpf_object * obj , const char * targ_btf_path )
6666
6668
{
@@ -6721,6 +6723,9 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
6721
6723
return err ;
6722
6724
}
6723
6725
6726
+ err = bpf_prog_assign_exc_cb (obj , prog );
6727
+ if (err )
6728
+ return err ;
6724
6729
/* Now, also append exception callback if it has not been done already. */
6725
6730
if (prog -> exception_cb_idx >= 0 ) {
6726
6731
struct bpf_program * subprog = & obj -> programs [prog -> exception_cb_idx ];
0 commit comments