@ -1,12 +1,14 @@
use core ::{ mem , ptr, str ::FromS tr} ;
use core ::{ mem , ops::Bound ::Included , p tr} ;
use alloc ::{
use alloc ::{
borrow ::ToOwned ,
borrow ::ToOwned ,
collections ::BTreeMap ,
format ,
format ,
string ::{ String , ToString } ,
string ::{ String , ToString } ,
vec ,
vec ,
vec ::Vec ,
vec ::Vec ,
} ;
} ;
use object ::SectionIndex ;
use crate ::{
use crate ::{
btf ::{
btf ::{
@ -18,7 +20,7 @@ use crate::{
BPF_K , BPF_LD , BPF_LDX , BPF_ST , BPF_STX , BPF_W , BTF_INT_SIGNED ,
BPF_K , BPF_LD , BPF_LDX , BPF_ST , BPF_STX , BPF_W , BTF_INT_SIGNED ,
} ,
} ,
util ::HashMap ,
util ::HashMap ,
Function , Object , ProgramSection ,
Function , Object ,
} ;
} ;
#[ cfg(not(feature = " std " )) ]
#[ cfg(not(feature = " std " )) ]
@ -43,9 +45,13 @@ enum RelocationError {
#[ error(transparent) ]
#[ error(transparent) ]
IOError ( #[ from ] std ::io ::Error ) ,
IOError ( #[ from ] std ::io ::Error ) ,
/// Program not found
/// Section not found
#[ error( " program not found " ) ]
#[ error( " section not found " ) ]
ProgramNotFound ,
SectionNotFound ,
/// Function not found
#[ error( " function not found " ) ]
FunctionNotFound ,
/// Invalid relocation access string
/// Invalid relocation access string
#[ error( " invalid relocation access string {access_str} " ) ]
#[ error( " invalid relocation access string {access_str} " ) ]
@ -227,23 +233,17 @@ impl Object {
error : RelocationError ::BtfError ( e ) ,
error : RelocationError ::BtfError ( e ) ,
} ) ? ;
} ) ? ;
let program_section = match ProgramSection ::from_str ( & section_name ) {
let ( section_index , _ ) = self
Ok ( program ) = > program ,
. section_infos
Err ( _ ) = > continue ,
. get ( & section_name . to_string ( ) )
} ;
. ok_or_else ( | | BtfRelocationError {
let section_name = program_section . name ( ) ;
section : section_name . to_string ( ) ,
error : RelocationError ::SectionNotFound ,
let function = self
. programs
. get_mut ( section_name )
. and_then ( | x | self . functions . get_mut ( & x . function_key ( ) ) )
. ok_or ( BtfRelocationError {
section : section_name . to_owned ( ) ,
error : RelocationError ::ProgramNotFound ,
} ) ? ;
} ) ? ;
match relocate_btf_function (
match relocate_btf_functions (
function ,
section_index ,
& mut self . functions ,
relos ,
relos ,
local_btf ,
local_btf ,
target_btf ,
target_btf ,
@ -252,7 +252,7 @@ impl Object {
Ok ( _ ) = > { }
Ok ( _ ) = > { }
Err ( error ) = > {
Err ( error ) = > {
return Err ( BtfRelocationError {
return Err ( BtfRelocationError {
section : section_name . to_ owned ( ) ,
section : section_name . to_ string ( ) ,
error ,
error ,
} )
} )
}
}
@ -263,16 +263,55 @@ impl Object {
}
}
}
}
fn relocate_btf_function < ' target > (
fn is_relocation_inside_function (
function : & mut Function ,
section_index : & SectionIndex ,
func : & Function ,
rel : & Relocation ,
) -> bool {
if section_index . 0 ! = func . section_index . 0 {
return false ;
}
let ins_offset = rel . ins_offset / mem ::size_of ::< bpf_insn > ( ) ;
let func_offset = func . section_offset / mem ::size_of ::< bpf_insn > ( ) ;
let func_size = func . instructions . len ( ) ;
( func_offset .. func_offset + func_size ) . contains ( & ins_offset )
}
fn function_by_relocation < ' a > (
section_index : & SectionIndex ,
functions : & ' a mut BTreeMap < ( usize , u64 ) , Function > ,
rel : & Relocation ,
) -> Option < & ' a mut Function > {
functions
. range_mut ( (
Included ( & ( section_index . 0 , 0 ) ) ,
Included ( & ( section_index . 0 , u64 ::MAX ) ) ,
) )
. map ( | ( _ , func ) | func )
. find ( | func | is_relocation_inside_function ( section_index , func , rel ) )
}
fn relocate_btf_functions < ' target > (
section_index : & SectionIndex ,
functions : & mut BTreeMap < ( usize , u64 ) , Function > ,
relos : & [ Relocation ] ,
relos : & [ Relocation ] ,
local_btf : & Btf ,
local_btf : & Btf ,
target_btf : & ' target Btf ,
target_btf : & ' target Btf ,
candidates_cache : & mut HashMap < u32 , Vec < Candidate < ' target > > > ,
candidates_cache : & mut HashMap < u32 , Vec < Candidate < ' target > > > ,
) -> Result < ( ) , RelocationError > {
) -> Result < ( ) , RelocationError > {
let mut last_function_opt : Option < & mut Function > = None ;
for rel in relos {
for rel in relos {
let function = match last_function_opt . take ( ) {
Some ( func ) if is_relocation_inside_function ( section_index , func , rel ) = > func ,
_ = > function_by_relocation ( section_index , functions , rel )
. ok_or ( RelocationError ::FunctionNotFound ) ? ,
} ;
let instructions = & mut function . instructions ;
let instructions = & mut function . instructions ;
let ins_index = rel . ins_offset / mem ::size_of ::< bpf_insn > ( ) ;
let ins_index = ( rel . ins_offset - function . section_offset ) / mem ::size_of ::< bpf_insn > ( ) ;
if ins_index > = instructions . len ( ) {
if ins_index > = instructions . len ( ) {
return Err ( RelocationError ::InvalidInstructionIndex {
return Err ( RelocationError ::InvalidInstructionIndex {
index : ins_index ,
index : ins_index ,
@ -345,6 +384,8 @@ fn relocate_btf_function<'target>(
} ;
} ;
comp_rel . apply ( function , rel , local_btf , target_btf ) ? ;
comp_rel . apply ( function , rel , local_btf , target_btf ) ? ;
last_function_opt = Some ( function ) ;
}
}
Ok ( ( ) )
Ok ( ( ) )
@ -861,7 +902,7 @@ impl ComputedRelocation {
) -> Result < ( ) , RelocationError > {
) -> Result < ( ) , RelocationError > {
let instructions = & mut function . instructions ;
let instructions = & mut function . instructions ;
let num_instructions = instructions . len ( ) ;
let num_instructions = instructions . len ( ) ;
let ins_index = rel . ins_offset / mem ::size_of ::< bpf_insn > ( ) ;
let ins_index = ( rel . ins_offset - function . section_offset ) / mem ::size_of ::< bpf_insn > ( ) ;
let ins =
let ins =
instructions
instructions
. get_mut ( ins_index )
. get_mut ( ins_index )