@@ -3192,86 +3192,6 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
31923192 }
31933193 }
31943194
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-
32753195 sanitize = btf_needs_sanitization (obj );
32763196 if (sanitize ) {
32773197 const void * raw_data ;
@@ -6661,6 +6581,88 @@ static void bpf_object__sort_relos(struct bpf_object *obj)
66616581 }
66626582}
66636583
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+
66646666static int
66656667bpf_object__relocate (struct bpf_object * obj , const char * targ_btf_path )
66666668{
@@ -6721,6 +6723,9 @@ bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_path)
67216723 return err ;
67226724 }
67236725
6726+ err = bpf_prog_assign_exc_cb (obj , prog );
6727+ if (err )
6728+ return err ;
67246729 /* Now, also append exception callback if it has not been done already. */
67256730 if (prog -> exception_cb_idx >= 0 ) {
67266731 struct bpf_program * subprog = & obj -> programs [prog -> exception_cb_idx ];
0 commit comments