@@ -6793,3 +6793,165 @@ int libbpf_num_possible_cpus(void)
67936793 WRITE_ONCE (cpus , tmp_cpus );
67946794 return tmp_cpus ;
67956795}
6796+
6797+ int bpf_object__open_skeleton (struct bpf_object_skeleton * s ,
6798+ const struct bpf_object_open_opts * opts )
6799+ {
6800+ DECLARE_LIBBPF_OPTS (bpf_object_open_opts , skel_opts ,
6801+ .object_name = s -> name ,
6802+ );
6803+ struct bpf_object * obj ;
6804+ int i ;
6805+
6806+ /* Attempt to preserve opts->object_name, unless overriden by user
6807+ * explicitly. Overwriting object name for skeletons is discouraged,
6808+ * as it breaks global data maps, because they contain object name
6809+ * prefix as their own map name prefix. When skeleton is generated,
6810+ * bpftool is making an assumption that this name will stay the same.
6811+ */
6812+ if (opts ) {
6813+ memcpy (& skel_opts , opts , sizeof (* opts ));
6814+ if (!opts -> object_name )
6815+ skel_opts .object_name = s -> name ;
6816+ }
6817+
6818+ obj = bpf_object__open_mem (s -> data , s -> data_sz , & skel_opts );
6819+ if (IS_ERR (obj )) {
6820+ pr_warn ("failed to initialize skeleton BPF object '%s': %ld\n" ,
6821+ s -> name , PTR_ERR (obj ));
6822+ return PTR_ERR (obj );
6823+ }
6824+
6825+ * s -> obj = obj ;
6826+
6827+ for (i = 0 ; i < s -> map_cnt ; i ++ ) {
6828+ struct bpf_map * * map = s -> maps [i ].map ;
6829+ const char * name = s -> maps [i ].name ;
6830+ void * * mmaped = s -> maps [i ].mmaped ;
6831+
6832+ * map = bpf_object__find_map_by_name (obj , name );
6833+ if (!* map ) {
6834+ pr_warn ("failed to find skeleton map '%s'\n" , name );
6835+ return - ESRCH ;
6836+ }
6837+
6838+ if (mmaped )
6839+ * mmaped = (* map )-> mmaped ;
6840+ }
6841+
6842+ for (i = 0 ; i < s -> prog_cnt ; i ++ ) {
6843+ struct bpf_program * * prog = s -> progs [i ].prog ;
6844+ const char * name = s -> progs [i ].name ;
6845+
6846+ * prog = bpf_object__find_program_by_name (obj , name );
6847+ if (!* prog ) {
6848+ pr_warn ("failed to find skeleton program '%s'\n" , name );
6849+ return - ESRCH ;
6850+ }
6851+ }
6852+
6853+ return 0 ;
6854+ }
6855+
6856+ int bpf_object__load_skeleton (struct bpf_object_skeleton * s )
6857+ {
6858+ int i , err ;
6859+
6860+ err = bpf_object__load (* s -> obj );
6861+ if (err ) {
6862+ pr_warn ("failed to load BPF skeleton '%s': %d\n" , s -> name , err );
6863+ return err ;
6864+ }
6865+
6866+ for (i = 0 ; i < s -> map_cnt ; i ++ ) {
6867+ struct bpf_map * map = * s -> maps [i ].map ;
6868+ size_t mmap_sz = bpf_map_mmap_sz (map );
6869+ int prot , map_fd = bpf_map__fd (map );
6870+ void * * mmaped = s -> maps [i ].mmaped ;
6871+ void * remapped ;
6872+
6873+ if (!mmaped )
6874+ continue ;
6875+
6876+ if (!(map -> def .map_flags & BPF_F_MMAPABLE )) {
6877+ * mmaped = NULL ;
6878+ continue ;
6879+ }
6880+
6881+ if (map -> def .map_flags & BPF_F_RDONLY_PROG )
6882+ prot = PROT_READ ;
6883+ else
6884+ prot = PROT_READ | PROT_WRITE ;
6885+
6886+ /* Remap anonymous mmap()-ed "map initialization image" as
6887+ * a BPF map-backed mmap()-ed memory, but preserving the same
6888+ * memory address. This will cause kernel to change process'
6889+ * page table to point to a different piece of kernel memory,
6890+ * but from userspace point of view memory address (and its
6891+ * contents, being identical at this point) will stay the
6892+ * same. This mapping will be released by bpf_object__close()
6893+ * as per normal clean up procedure, so we don't need to worry
6894+ * about it from skeleton's clean up perspective.
6895+ */
6896+ remapped = mmap (* mmaped , mmap_sz , prot , MAP_SHARED | MAP_FIXED ,
6897+ map_fd , 0 );
6898+ if (remapped == MAP_FAILED ) {
6899+ err = - errno ;
6900+ * mmaped = NULL ;
6901+ pr_warn ("failed to re-mmap() map '%s': %d\n" ,
6902+ bpf_map__name (map ), err );
6903+ return err ;
6904+ }
6905+ }
6906+
6907+ return 0 ;
6908+ }
6909+
6910+ int bpf_object__attach_skeleton (struct bpf_object_skeleton * s )
6911+ {
6912+ int i ;
6913+
6914+ for (i = 0 ; i < s -> prog_cnt ; i ++ ) {
6915+ struct bpf_program * prog = * s -> progs [i ].prog ;
6916+ struct bpf_link * * link = s -> progs [i ].link ;
6917+ const struct bpf_sec_def * sec_def ;
6918+ const char * sec_name = bpf_program__title (prog , false);
6919+
6920+ sec_def = find_sec_def (sec_name );
6921+ if (!sec_def || !sec_def -> attach_fn )
6922+ continue ;
6923+
6924+ * link = sec_def -> attach_fn (sec_def , prog );
6925+ if (IS_ERR (* link )) {
6926+ pr_warn ("failed to auto-attach program '%s': %ld\n" ,
6927+ bpf_program__name (prog ), PTR_ERR (* link ));
6928+ return PTR_ERR (* link );
6929+ }
6930+ }
6931+
6932+ return 0 ;
6933+ }
6934+
6935+ void bpf_object__detach_skeleton (struct bpf_object_skeleton * s )
6936+ {
6937+ int i ;
6938+
6939+ for (i = 0 ; i < s -> prog_cnt ; i ++ ) {
6940+ struct bpf_link * * link = s -> progs [i ].link ;
6941+
6942+ if (!IS_ERR_OR_NULL (* link ))
6943+ bpf_link__destroy (* link );
6944+ * link = NULL ;
6945+ }
6946+ }
6947+
6948+ void bpf_object__destroy_skeleton (struct bpf_object_skeleton * s )
6949+ {
6950+ if (s -> progs )
6951+ bpf_object__detach_skeleton (s );
6952+ if (s -> obj )
6953+ bpf_object__close (* s -> obj );
6954+ free (s -> maps );
6955+ free (s -> progs );
6956+ free (s );
6957+ }
0 commit comments