@ -27,17 +27,16 @@ pub enum RelocationError {
 
		
	
		
			
				     #[ error(transparent) ]  
		
	
		
			
				     IOError ( #[ from ]   io ::Error ) ,  
		
	
		
			
				
 
		
	
		
			
				     #[ error( " section `{name}`  not found" ) ]  
		
	
		
			
				     SectionNotFound  {   name : String  }  ,  
		
	
		
			
				     #[ error( " program  not found" ) ]  
		
	
		
			
				     ProgramNotFound ,  
		
	
		
			
				
 
		
	
		
			
				     #[ error( " invalid relocation access string {access_str} " ) ]  
		
	
		
			
				     InvalidAccessString   {   access_str : String  } ,  
		
	
		
			
				
 
		
	
		
			
				     #[ error( " invalid instruction index #{index} referenced by relocation #{relocation_number}  in section `{section_name}` " ) ]  
		
	
		
			
				     #[ error( " invalid instruction index #{index} referenced by relocation #{relocation_number} , the program contains {num_instructions} instructions " ) ]  
		
	
		
			
				     InvalidInstructionIndex   {  
		
	
		
			
				         index : usize ,  
		
	
		
			
				         num_instructions : usize ,  
		
	
		
			
				         section_name : String ,  
		
	
		
			
				         relocation_number : usize ,  
		
	
		
			
				     } ,  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -170,7 +169,6 @@ impl Object {
 
		
	
		
			
				         } ) ? ;  
		
	
		
			
				
 
		
	
		
			
				         let   mut   candidates_cache   =   HashMap ::< u32 ,   Vec < Candidate > > ::new ( ) ;  
		
	
		
			
				
 
		
	
		
			
				         for   ( sec_name_off ,   relos )   in   btf_ext . relocations ( )   {  
		
	
		
			
				             let   section_name   =   local_btf . string_at ( * sec_name_off ) ? ;  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -180,12 +178,42 @@ impl Object {
 
		
	
		
			
				                 continue ;  
		
	
		
			
				             }  
		
	
		
			
				             let   section_name   =   parts [ 1 ] ;  
		
	
		
			
				             let   program   =   self . programs . get_mut ( section_name ) . ok_or_else ( | |   {  
		
	
		
			
				                 RelocationError ::SectionNotFound   {  
		
	
		
			
				                     name : section_name . to_string ( ) ,  
		
	
		
			
				                 }  
		
	
		
			
				             let   program   =   self  
		
	
		
			
				                 . programs  
		
	
		
			
				                 . get_mut ( section_name )  
		
	
		
			
				                 . ok_or ( BpfError ::RelocationError   {  
		
	
		
			
				                     program_name : section_name . to_owned ( ) ,  
		
	
		
			
				                     error : Box ::new ( RelocationError ::ProgramNotFound ) ,  
		
	
		
			
				                 } ) ? ;  
		
	
		
			
				             match   relocate_btf_program (  
		
	
		
			
				                 program ,  
		
	
		
			
				                 relos ,  
		
	
		
			
				                 local_btf ,  
		
	
		
			
				                 & target_btf ,  
		
	
		
			
				                 & mut   candidates_cache ,  
		
	
		
			
				             )   {  
		
	
		
			
				                 Ok ( _ )   = >   { }  
		
	
		
			
				                 Err ( ErrorWrapper ::BtfError ( e ) )   = >   return   Err ( e ) ? ,  
		
	
		
			
				                 Err ( ErrorWrapper ::RelocationError ( error ) )   = >   {  
		
	
		
			
				                     return   Err ( BpfError ::RelocationError   {  
		
	
		
			
				                         program_name : section_name . to_owned ( ) ,  
		
	
		
			
				                         error : Box ::new ( error ) ,  
		
	
		
			
				                     } )  
		
	
		
			
				                 }  
		
	
		
			
				             }  
		
	
		
			
				         }  
		
	
		
			
				
 
		
	
		
			
				         Ok ( ( ) )  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				fn  relocate_btf_program < ' target > (  
		
	
		
			
				     program : & mut   Program ,  
		
	
		
			
				     relos : & [ Relocation ] ,  
		
	
		
			
				     local_btf : & Btf ,  
		
	
		
			
				     target_btf : & ' target  Btf ,  
		
	
		
			
				     candidates_cache : & mut   HashMap < u32 ,   Vec < Candidate < ' target > > > ,  
		
	
		
			
				)   -> Result < ( ) ,   ErrorWrapper >   {  
		
	
		
			
				     for   rel   in   relos   {  
		
	
		
			
				         let   instructions   =   & mut   program . instructions ;  
		
	
		
			
				         let   ins_index   =   rel . ins_offset   as   usize   /   std ::mem ::size_of ::< bpf_insn > ( ) ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -193,7 +221,6 @@ impl Object {
 
		
	
		
			
				             return   Err ( RelocationError ::InvalidInstructionIndex   {  
		
	
		
			
				                 index : ins_index ,  
		
	
		
			
				                 num_instructions : instructions . len ( ) ,  
		
	
		
			
				                         section_name : section_name . to_string ( ) ,  
		
	
		
			
				                 relocation_number : rel . number ,  
		
	
		
			
				             } ) ? ;  
		
	
		
			
				         }  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -211,7 +238,7 @@ impl Object {
 
		
	
		
			
				                     None   = >   {  
		
	
		
			
				                         candidates_cache . insert (  
		
	
		
			
				                             rel . type_id ,  
		
	
		
			
				                                      find_candidates ( local_ty ,   local_name ,   & target_btf ) ? ,  
		
	
		
			
				                             find_candidates ( local_ty ,   local_name ,   target_btf ) ? ,  
		
	
		
			
				                         ) ;  
		
	
		
			
				                         candidates_cache . get ( & rel . type_id ) . unwrap ( )  
		
	
		
			
				                     }  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -220,11 +247,8 @@ impl Object {
 
		
	
		
			
				                 let   mut   matches   =   Vec ::new ( ) ;  
		
	
		
			
				                 for   candidate   in   candidates   {  
		
	
		
			
				                     if   let   Some ( candidate_spec )   =   match_candidate ( & local_spec ,   candidate ) ?   {  
		
	
		
			
				                                 let   comp_rel   =   ComputedRelocation ::new (  
		
	
		
			
				                                     rel ,  
		
	
		
			
				                                     & local_spec ,  
		
	
		
			
				                                     Some ( & candidate_spec ) ,  
		
	
		
			
				                                 ) ? ;  
		
	
		
			
				                         let   comp_rel   =  
		
	
		
			
				                             ComputedRelocation ::new ( rel ,   & local_spec ,   Some ( & candidate_spec ) ) ? ;  
		
	
		
			
				                         matches . push ( ( candidate . name . clone ( ) ,   candidate_spec ,   comp_rel ) ) ;  
		
	
		
			
				                     }  
		
	
		
			
				                 }  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -264,12 +288,10 @@ impl Object {
 
		
	
		
			
				             ComputedRelocation ::new ( rel ,   & local_spec ,   None ) ?  
		
	
		
			
				         } ;  
		
	
		
			
				
 
		
	
		
			
				                 comp_rel . apply ( program ,   rel ,   section_name ,   local_btf ,   & target_btf ) ? ;  
		
	
		
			
				             }  
		
	
		
			
				         comp_rel . apply ( program ,   rel ,   local_btf ,   & target_btf ) ? ;  
		
	
		
			
				     }  
		
	
		
			
				
 
		
	
		
			
				     Ok ( ( ) )  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				fn  flavorless_name ( name : & str )   -> & str  {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -306,7 +328,7 @@ fn find_candidates<'target>(
 
		
	
		
			
				fn  match_candidate < ' target > (  
		
	
		
			
				     local_spec : & AccessSpec ,  
		
	
		
			
				     candidate : & ' target  Candidate ,  
		
	
		
			
				)   -> Result < Option < AccessSpec < ' target > > ,   Bpf Error>   {  
		
	
		
			
				)   -> Result < Option < AccessSpec < ' target > > ,   rWrappe r>   {  
		
	
		
			
				     let   mut   target_spec   =   AccessSpec   {  
		
	
		
			
				         btf : candidate . btf ,  
		
	
		
			
				         root_type_id : candidate . type_id ,  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -434,7 +456,7 @@ fn match_member<'local, 'target>(
 
		
	
		
			
				     target_btf : & ' target  Btf ,  
		
	
		
			
				     target_id : u32 ,  
		
	
		
			
				     target_spec : & mut   AccessSpec < ' target > ,  
		
	
		
			
				)   -> Result < Option < u32 > ,   Bpf Error>   {  
		
	
		
			
				)   -> Result < Option < u32 > ,   rWrappe r>   {  
		
	
		
			
				     let   local_ty   =   local_btf . type_by_id ( local_accessor . type_id ) ? ;  
		
	
		
			
				     let   local_member   =   match   local_ty   {  
		
	
		
			
				         BtfType ::Struct ( _ ,   members )   |   BtfType ::Union ( _ ,   members )   = >   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -519,7 +541,7 @@ impl<'a> AccessSpec<'a> {
 
		
	
		
			
				         root_type_id : u32 ,  
		
	
		
			
				         spec : & str ,  
		
	
		
			
				         relocation : Relocation ,  
		
	
		
			
				     )   -> Result < AccessSpec < ' a > ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < AccessSpec < ' a > ,   rWrappe r>   {  
		
	
		
			
				         let   parts   =   spec  
		
	
		
			
				             . split ( ":" )  
		
	
		
			
				             . map ( | s |   s . parse ::< usize > ( ) )  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -724,7 +746,7 @@ impl ComputedRelocation {
 
		
	
		
			
				         rel : & Relocation ,  
		
	
		
			
				         local_spec : & AccessSpec ,  
		
	
		
			
				         target_spec : Option < & AccessSpec > ,  
		
	
		
			
				     )   -> Result < ComputedRelocation ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < ComputedRelocation ,   rWrappe r>   {  
		
	
		
			
				         use   RelocationKind ::* ;  
		
	
		
			
				         let   ret   =   match   rel . kind   {  
		
	
		
			
				             FieldByteOffset   |   FieldByteSize   |   FieldExists   |   FieldSigned   |   FieldLShift64  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -749,10 +771,9 @@ impl ComputedRelocation {
 
		
	
		
			
				         & self ,  
		
	
		
			
				         program : & mut   Program ,  
		
	
		
			
				         rel : & Relocation ,  
		
	
		
			
				         section_name : & str ,  
		
	
		
			
				         local_btf : & Btf ,  
		
	
		
			
				         target_btf : & Btf ,  
		
	
		
			
				     )   -> Result < ( ) ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < ( ) ,   rWrappe r>   {  
		
	
		
			
				         let   instructions   =   & mut   program . instructions ;  
		
	
		
			
				         let   num_instructions   =   instructions . len ( ) ;  
		
	
		
			
				         let   ins_index   =   rel . ins_offset   as   usize   /   std ::mem ::size_of ::< bpf_insn > ( ) ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -762,7 +783,6 @@ impl ComputedRelocation {
 
		
	
		
			
				                 . ok_or ( RelocationError ::InvalidInstructionIndex   {  
		
	
		
			
				                     index : rel . ins_offset   as   usize ,  
		
	
		
			
				                     num_instructions ,  
		
	
		
			
				                     section_name : section_name . to_string ( ) ,  
		
	
		
			
				                     relocation_number : rel . number ,  
		
	
		
			
				                 } ) ? ;  
		
	
		
			
				
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -840,7 +860,6 @@ impl ComputedRelocation {
 
		
	
		
			
				                     RelocationError ::InvalidInstructionIndex   {  
		
	
		
			
				                         index : ins_index   +   1 ,  
		
	
		
			
				                         num_instructions ,  
		
	
		
			
				                         section_name : section_name . to_string ( ) ,  
		
	
		
			
				                         relocation_number : rel . number ,  
		
	
		
			
				                     } ,  
		
	
		
			
				                 ) ? ;  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -862,7 +881,7 @@ impl ComputedRelocation {
 
		
	
		
			
				     fn  compute_enum_relocation (  
		
	
		
			
				         rel : & Relocation ,  
		
	
		
			
				         spec : Option < & AccessSpec > ,  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   rWrappe r>   {  
		
	
		
			
				         use   RelocationKind ::* ;  
		
	
		
			
				         let   value   =   match   rel . kind   {  
		
	
		
			
				             EnumVariantExists   = >   spec . is_some ( )   as   u32 ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -888,7 +907,7 @@ impl ComputedRelocation {
 
		
	
		
			
				     fn  compute_field_relocation (  
		
	
		
			
				         rel : & Relocation ,  
		
	
		
			
				         spec : Option < & AccessSpec > ,  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   rWrappe r>   {  
		
	
		
			
				         use   RelocationKind ::* ;  
		
	
		
			
				
 
		
	
		
			
				         if   let   FieldExists   =   rel . kind   {  
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -1013,7 +1032,7 @@ impl ComputedRelocation {
 
		
	
		
			
				         rel : & Relocation ,  
		
	
		
			
				         local_spec : & AccessSpec ,  
		
	
		
			
				         target_spec : Option < & AccessSpec > ,  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   Bpf Error>   {  
		
	
		
			
				     )   -> Result < ComputedRelocationValue ,   rWrappe r>   {  
		
	
		
			
				         use   RelocationKind ::* ;  
		
	
		
			
				         let   value   =   match   rel . kind   {  
		
	
		
			
				             TypeIdLocal   = >   local_spec . root_type_id ,  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -1037,3 +1056,14 @@ impl ComputedRelocation {
 
		
	
		
			
				         } )  
		
	
		
			
				     }  
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				// this exists only to simplify propagating errors from relocate_btf() and to associate
  
		
	
		
			
				// RelocationError(s) with their respective program name
  
		
	
		
			
				#[ derive(Error, Debug) ]  
		
	
		
			
				enum  ErrorWrapper   {  
		
	
		
			
				     #[ error(transparent) ]  
		
	
		
			
				     BtfError ( #[ from ]   BtfError ) ,  
		
	
		
			
				
 
		
	
		
			
				     #[ error(transparent) ]  
		
	
		
			
				     RelocationError ( #[ from ]   RelocationError ) ,  
		
	
		
			
				}