@@ -612,6 +612,7 @@ enum sec_type {
612612 SEC_BSS ,
613613 SEC_DATA ,
614614 SEC_RODATA ,
615+ SEC_ST_OPS ,
615616};
616617
617618struct elf_sec_desc {
@@ -627,8 +628,6 @@ struct elf_state {
627628 Elf * elf ;
628629 Elf64_Ehdr * ehdr ;
629630 Elf_Data * symbols ;
630- Elf_Data * st_ops_data ;
631- Elf_Data * st_ops_link_data ;
632631 size_t shstrndx ; /* section index for section name strings */
633632 size_t strtabidx ;
634633 struct elf_sec_desc * secs ;
@@ -637,8 +636,7 @@ struct elf_state {
637636 __u32 btf_maps_sec_btf_id ;
638637 int text_shndx ;
639638 int symbols_shndx ;
640- int st_ops_shndx ;
641- int st_ops_link_shndx ;
639+ bool has_st_ops ;
642640};
643641
644642struct usdt_manager ;
@@ -1266,7 +1264,7 @@ static int bpf_object__init_kern_struct_ops_maps(struct bpf_object *obj)
12661264}
12671265
12681266static int init_struct_ops_maps (struct bpf_object * obj , const char * sec_name ,
1269- int shndx , Elf_Data * data , __u32 map_flags )
1267+ int shndx , Elf_Data * data )
12701268{
12711269 const struct btf_type * type , * datasec ;
12721270 const struct btf_var_secinfo * vsi ;
@@ -1328,7 +1326,7 @@ static int init_struct_ops_maps(struct bpf_object *obj, const char *sec_name,
13281326 map -> def .key_size = sizeof (int );
13291327 map -> def .value_size = type -> size ;
13301328 map -> def .max_entries = 1 ;
1331- map -> def .map_flags = map_flags ;
1329+ map -> def .map_flags = strcmp ( sec_name , STRUCT_OPS_LINK_SEC ) == 0 ? BPF_F_LINK : 0 ;
13321330
13331331 map -> st_ops = calloc (1 , sizeof (* map -> st_ops ));
13341332 if (!map -> st_ops )
@@ -1363,15 +1361,25 @@ static int init_struct_ops_maps(struct bpf_object *obj, const char *sec_name,
13631361
13641362static int bpf_object_init_struct_ops (struct bpf_object * obj )
13651363{
1366- int err ;
1364+ const char * sec_name ;
1365+ int sec_idx , err ;
13671366
1368- err = init_struct_ops_maps (obj , STRUCT_OPS_SEC , obj -> efile .st_ops_shndx ,
1369- obj -> efile .st_ops_data , 0 );
1370- err = err ?: init_struct_ops_maps (obj , STRUCT_OPS_LINK_SEC ,
1371- obj -> efile .st_ops_link_shndx ,
1372- obj -> efile .st_ops_link_data ,
1373- BPF_F_LINK );
1374- return err ;
1367+ for (sec_idx = 0 ; sec_idx < obj -> efile .sec_cnt ; ++ sec_idx ) {
1368+ struct elf_sec_desc * desc = & obj -> efile .secs [sec_idx ];
1369+
1370+ if (desc -> sec_type != SEC_ST_OPS )
1371+ continue ;
1372+
1373+ sec_name = elf_sec_name (obj , elf_sec_by_idx (obj , sec_idx ));
1374+ if (!sec_name )
1375+ return - LIBBPF_ERRNO__FORMAT ;
1376+
1377+ err = init_struct_ops_maps (obj , sec_name , sec_idx , desc -> data );
1378+ if (err )
1379+ return err ;
1380+ }
1381+
1382+ return 0 ;
13751383}
13761384
13771385static struct bpf_object * bpf_object__new (const char * path ,
@@ -1409,8 +1417,6 @@ static struct bpf_object *bpf_object__new(const char *path,
14091417 obj -> efile .obj_buf = obj_buf ;
14101418 obj -> efile .obj_buf_sz = obj_buf_sz ;
14111419 obj -> efile .btf_maps_shndx = -1 ;
1412- obj -> efile .st_ops_shndx = -1 ;
1413- obj -> efile .st_ops_link_shndx = -1 ;
14141420 obj -> kconfig_map_idx = -1 ;
14151421
14161422 obj -> kern_version = get_kernel_version ();
@@ -1427,8 +1433,6 @@ static void bpf_object__elf_finish(struct bpf_object *obj)
14271433 elf_end (obj -> efile .elf );
14281434 obj -> efile .elf = NULL ;
14291435 obj -> efile .symbols = NULL ;
1430- obj -> efile .st_ops_data = NULL ;
1431- obj -> efile .st_ops_link_data = NULL ;
14321436
14331437 zfree (& obj -> efile .secs );
14341438 obj -> efile .sec_cnt = 0 ;
@@ -2973,14 +2977,13 @@ static int bpf_object__sanitize_btf(struct bpf_object *obj, struct btf *btf)
29732977static bool libbpf_needs_btf (const struct bpf_object * obj )
29742978{
29752979 return obj -> efile .btf_maps_shndx >= 0 ||
2976- obj -> efile .st_ops_shndx >= 0 ||
2977- obj -> efile .st_ops_link_shndx >= 0 ||
2980+ obj -> efile .has_st_ops ||
29782981 obj -> nr_extern > 0 ;
29792982}
29802983
29812984static bool kernel_needs_btf (const struct bpf_object * obj )
29822985{
2983- return obj -> efile .st_ops_shndx >= 0 || obj -> efile . st_ops_link_shndx >= 0 ;
2986+ return obj -> efile .has_st_ops ;
29842987}
29852988
29862989static int bpf_object__init_btf (struct bpf_object * obj ,
@@ -3681,12 +3684,12 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
36813684 sec_desc -> sec_type = SEC_RODATA ;
36823685 sec_desc -> shdr = sh ;
36833686 sec_desc -> data = data ;
3684- } else if (strcmp (name , STRUCT_OPS_SEC ) == 0 ) {
3685- obj -> efile . st_ops_data = data ;
3686- obj -> efile . st_ops_shndx = idx ;
3687- } else if ( strcmp ( name , STRUCT_OPS_LINK_SEC ) == 0 ) {
3688- obj -> efile . st_ops_link_data = data ;
3689- obj -> efile .st_ops_link_shndx = idx ;
3687+ } else if (strcmp (name , STRUCT_OPS_SEC ) == 0 ||
3688+ strcmp ( name , STRUCT_OPS_LINK_SEC ) == 0 ) {
3689+ sec_desc -> sec_type = SEC_ST_OPS ;
3690+ sec_desc -> shdr = sh ;
3691+ sec_desc -> data = data ;
3692+ obj -> efile .has_st_ops = true ;
36903693 } else {
36913694 pr_info ("elf: skipping unrecognized data section(%d) %s\n" ,
36923695 idx , name );
@@ -6999,12 +7002,12 @@ static int bpf_object__collect_relos(struct bpf_object *obj)
69997002 data = sec_desc -> data ;
70007003 idx = shdr -> sh_info ;
70017004
7002- if (shdr -> sh_type != SHT_REL ) {
7005+ if (shdr -> sh_type != SHT_REL || idx < 0 || idx >= obj -> efile . sec_cnt ) {
70037006 pr_warn ("internal error at %d\n" , __LINE__ );
70047007 return - LIBBPF_ERRNO__INTERNAL ;
70057008 }
70067009
7007- if (idx == obj -> efile .st_ops_shndx || idx == obj -> efile . st_ops_link_shndx )
7010+ if (obj -> efile .secs [ idx ]. sec_type == SEC_ST_OPS )
70087011 err = bpf_object__collect_st_ops_relos (obj , shdr , data );
70097012 else if (idx == obj -> efile .btf_maps_shndx )
70107013 err = bpf_object__collect_map_relos (obj , shdr , data );
0 commit comments