@@ -313,6 +313,10 @@ pub struct ExtractConfig {
313313/// Path is relative to `out_dir/include`. 
314314#[ serde( with = "unix_path_serde_option" ,  default ,  skip_serializing_if = "Option::is_none" ) ]  
315315    pub  header :  Option < Utf8UnixPathBuf > , 
316+     /// If specified, any relocations within the symbol will be written to the given file in JSON 
317+ /// format. Path is relative to `out_dir/bin`. 
318+ #[ serde( with = "unix_path_serde_option" ,  default ,  skip_serializing_if = "Option::is_none" ) ]  
319+     pub  relocations :  Option < Utf8UnixPathBuf > , 
316320    /// The type for the extracted symbol in the header file. By default, the header will emit 
317321/// a full symbol declaration (a.k.a. `symbol`), but this can be set to `raw` to emit the raw 
318322/// data as a byte array. `none` avoids emitting a header entirely, in which case the `header` 
@@ -399,11 +403,24 @@ pub struct OutputExtract {
399403    pub  binary :  Option < Utf8UnixPathBuf > , 
400404    #[ serde( with = "unix_path_serde_option" ) ]  
401405    pub  header :  Option < Utf8UnixPathBuf > , 
406+     #[ serde( with = "unix_path_serde_option" ) ]  
407+     pub  relocations :  Option < Utf8UnixPathBuf > , 
402408    pub  header_type :  String , 
403409    pub  custom_type :  Option < String > , 
404410    pub  custom_data :  Option < serde_json:: Value > , 
405411} 
406412
413+ #[ derive( Serialize ) ]  
414+ struct  ExtractRelocInfo  { 
415+     offset :  u32 , 
416+     #[ serde( rename = "type" ) ]  
417+     kind :  ObjRelocKind , 
418+     target :  String , 
419+     addend :  i64 , 
420+     #[ serde( skip_serializing_if = "Option::is_none" ) ]  
421+     module :  Option < u32 > , 
422+ } 
423+ 
407424#[ derive( Serialize ,  Deserialize ,  Debug ,  Clone ,  Default ,  PartialEq ,  Eq ,  Hash ) ]  
408425pub  struct  OutputLink  { 
409426    pub  modules :  Vec < String > , 
@@ -1059,12 +1076,35 @@ fn split_write_obj(
10591076            } 
10601077        } 
10611078
1079+         if  let  Some ( relocations)  = & extract. relocations  { 
1080+             let  start = symbol. address  as  u32  - section. address  as  u32 ; 
1081+             let  end = start + symbol. size  as  u32 ; 
1082+             let  mut  reloc_entries = Vec :: new ( ) ; 
1083+             for  ( addr,  reloc)  in  section. relocations . range ( start..end)  { 
1084+                 let  target_symbol = & module. obj . symbols [ reloc. target_symbol ] ; 
1085+                 reloc_entries. push ( ExtractRelocInfo  { 
1086+                     offset :  addr - start, 
1087+                     kind :  reloc. kind , 
1088+                     target :  target_symbol. name . clone ( ) , 
1089+                     addend :  reloc. addend , 
1090+                     module :  reloc. module , 
1091+                 } ) ; 
1092+             } 
1093+             let  relocations_json = serde_json:: to_vec_pretty ( & reloc_entries) ?; 
1094+             let  out_path = base_dir. join ( "bin" ) . join ( relocations. with_encoding ( ) ) ; 
1095+             if  let  Some ( parent)  = out_path. parent ( )  { 
1096+                 DirBuilder :: new ( ) . recursive ( true ) . create ( parent) ?; 
1097+             } 
1098+             write_if_changed ( & out_path,  & relocations_json) ?; 
1099+         } 
1100+ 
10621101        // Copy to output config 
10631102        out_config. extract . push ( OutputExtract  { 
10641103            symbol :  symbol. name . clone ( ) , 
10651104            rename :  extract. rename . clone ( ) , 
10661105            binary :  extract. binary . clone ( ) , 
10671106            header :  extract. header . clone ( ) , 
1107+             relocations :  extract. relocations . clone ( ) , 
10681108            header_type :  header_kind. to_string ( ) , 
10691109            custom_type :  extract. custom_type . clone ( ) , 
10701110            custom_data :  extract. custom_data . clone ( ) , 
0 commit comments