@@ -106,8 +106,8 @@ fn name_arr_to_string(a: &[c_char], default: &str) -> String {
106
106
}
107
107
}
108
108
109
- #[ derive( Clone , Debug ) ]
110
109
/// BTF Line information
110
+ #[ derive( Clone , Debug ) ]
111
111
pub struct LineInfo {
112
112
/// Offset of instruction in vector
113
113
pub insn_off : u32 ,
@@ -497,32 +497,84 @@ gen_info_impl!(
497
497
498
498
/// Information about BPF type format
499
499
#[ derive( Debug , Clone ) ]
500
- // TODO: Document members.
501
500
#[ allow( missing_docs) ]
502
501
pub struct BtfInfo {
503
- pub btf : u64 ,
504
- pub btf_size : u32 ,
502
+ /// The name associated with this btf information in the kernel
503
+ pub name : String ,
504
+ /// The raw btf bytes from the kernel
505
+ pub btf : Vec < u8 > ,
506
+ /// The btf id associated with this btf information in the kernel
505
507
pub id : u32 ,
506
508
}
507
509
508
510
impl BtfInfo {
509
- fn from_uapi ( _fd : i32 , s : libbpf_sys:: bpf_btf_info ) -> Option < Self > {
510
- Some ( Self {
511
- btf : s. btf ,
512
- btf_size : s. btf_size ,
513
- id : s. id ,
511
+ fn load_from_fd ( fd : i32 ) -> Result < Self > {
512
+ let mut item = libbpf_sys:: bpf_btf_info:: default ( ) ;
513
+ let mut btf: Vec < u8 > = Vec :: new ( ) ;
514
+ let mut name: Vec < u8 > = Vec :: new ( ) ;
515
+
516
+ let item_ptr: * mut libbpf_sys:: bpf_btf_info = & mut item;
517
+ let mut len = size_of :: < libbpf_sys:: bpf_btf_info > ( ) as u32 ;
518
+
519
+ let ret =
520
+ unsafe { libbpf_sys:: bpf_obj_get_info_by_fd ( fd, item_ptr as * mut c_void , & mut len) } ;
521
+ util:: parse_ret ( ret) ?;
522
+
523
+ // The API gives you the ascii string length while expecting
524
+ // you to give it back space for a nul-terminator
525
+ item. name_len += 1 ;
526
+ name. resize ( item. name_len as usize , 0u8 ) ;
527
+ item. name = name. as_mut_ptr ( ) as * mut c_void as u64 ;
528
+
529
+ btf. resize ( item. btf_size as usize , 0u8 ) ;
530
+ item. btf = btf. as_mut_ptr ( ) as * mut c_void as u64 ;
531
+
532
+ let ret =
533
+ unsafe { libbpf_sys:: bpf_obj_get_info_by_fd ( fd, item_ptr as * mut c_void , & mut len) } ;
534
+ util:: parse_ret ( ret) ?;
535
+
536
+ Ok ( BtfInfo {
537
+ name : String :: from_utf8 ( name) . unwrap_or_else ( |_| "(?)" . to_string ( ) ) ,
538
+ btf,
539
+ id : item. id ,
514
540
} )
515
541
}
516
542
}
517
543
518
- gen_info_impl ! (
519
- /// Iterator that returns [`BtfInfo`]s.
520
- BtfInfoIter ,
521
- BtfInfo ,
522
- libbpf_sys:: bpf_btf_info,
523
- libbpf_sys:: bpf_btf_get_next_id,
524
- libbpf_sys:: bpf_btf_get_fd_by_id
525
- ) ;
544
+ #[ derive( Debug , Default ) ]
545
+ /// An iterator for the btf type information of modules and programs
546
+ /// in the kernel
547
+ pub struct BtfInfoIter {
548
+ cur_id : u32 ,
549
+ }
550
+
551
+ impl Iterator for BtfInfoIter {
552
+ type Item = BtfInfo ;
553
+
554
+ fn next ( & mut self ) -> Option < Self :: Item > {
555
+ loop {
556
+ if unsafe { libbpf_sys:: bpf_btf_get_next_id ( self . cur_id , & mut self . cur_id ) } != 0 {
557
+ return None ;
558
+ }
559
+
560
+ let fd = unsafe { libbpf_sys:: bpf_btf_get_fd_by_id ( self . cur_id ) } ;
561
+ if fd < 0 {
562
+ if errno:: errno ( ) == errno:: Errno :: ENOENT as i32 {
563
+ continue ;
564
+ }
565
+ return None ;
566
+ }
567
+
568
+ let info = BtfInfo :: load_from_fd ( fd) ;
569
+ let _ = close ( fd) ;
570
+
571
+ match info {
572
+ Ok ( i) => return Some ( i) ,
573
+ Err ( e) => eprintln ! ( "Failed to load btf information: {}" , e) ,
574
+ }
575
+ }
576
+ }
577
+ }
526
578
527
579
#[ derive( Debug , Clone ) ]
528
580
// TODO: Document members.
0 commit comments