@@ -5,6 +5,7 @@ use std::{
5
5
fs:: DirBuilder ,
6
6
io:: { Cursor , Seek , Write } ,
7
7
mem:: take,
8
+ str:: FromStr ,
8
9
time:: Instant ,
9
10
} ;
10
11
@@ -36,7 +37,7 @@ use crate::{
36
37
} ,
37
38
util:: {
38
39
asm:: write_asm,
39
- bin2c:: bin2c,
40
+ bin2c:: { bin2c, HeaderKind } ,
40
41
comment:: MWComment ,
41
42
config:: {
42
43
apply_splits_file, apply_symbols_file, is_auto_symbol, signed_hex_serde,
@@ -303,6 +304,20 @@ pub struct ExtractConfig {
303
304
/// Path is relative to `out_dir/include`.
304
305
#[ serde( with = "unix_path_serde_option" , default , skip_serializing_if = "Option::is_none" ) ]
305
306
pub header : Option < Utf8UnixPathBuf > ,
307
+ /// The type for the extracted symbol in the header file. By default, the header will emit
308
+ /// a full symbol declaration (a.k.a. `symbol`), but this can be set to `raw` to emit the raw
309
+ /// data as a byte array. `none` avoids emitting a header entirely, in which case the `header`
310
+ /// field can be used by external asset processing.
311
+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
312
+ pub header_type : Option < String > ,
313
+ /// A user-defined type for use with external asset processing. This value is simply passed
314
+ /// through to the `custom_type` field in the output config.
315
+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
316
+ pub custom_type : Option < String > ,
317
+ /// User-defined data for use with external asset processing. This value is simply passed
318
+ /// through to the `custom_data` field in the output config.
319
+ #[ serde( default , skip_serializing_if = "Option::is_none" ) ]
320
+ pub custom_data : Option < serde_json:: Value > ,
306
321
}
307
322
308
323
/// A relocation that should be blocked.
@@ -364,6 +379,19 @@ pub struct OutputModule {
364
379
pub ldscript : Utf8UnixPathBuf ,
365
380
pub entry : Option < String > ,
366
381
pub units : Vec < OutputUnit > ,
382
+ pub extract : Vec < OutputExtract > ,
383
+ }
384
+
385
+ #[ derive( Serialize , Deserialize , Debug , Clone , Default ) ]
386
+ pub struct OutputExtract {
387
+ pub symbol : String ,
388
+ #[ serde( with = "unix_path_serde_option" ) ]
389
+ pub binary : Option < Utf8UnixPathBuf > ,
390
+ #[ serde( with = "unix_path_serde_option" ) ]
391
+ pub header : Option < Utf8UnixPathBuf > ,
392
+ pub header_type : String ,
393
+ pub custom_type : Option < String > ,
394
+ pub custom_data : Option < serde_json:: Value > ,
367
395
}
368
396
369
397
#[ derive( Serialize , Deserialize , Debug , Clone , Default , PartialEq , Eq , Hash ) ]
@@ -938,6 +966,7 @@ fn split_write_obj(
938
966
ldscript : out_dir. join ( "ldscript.lcf" ) . with_unix_encoding ( ) ,
939
967
units : Vec :: with_capacity ( split_objs. len ( ) ) ,
940
968
entry,
969
+ extract : Vec :: with_capacity ( module. config . extract . len ( ) ) ,
941
970
} ;
942
971
for ( unit, split_obj) in module. obj . link_order . iter ( ) . zip ( & split_objs) {
943
972
let out_obj = write_elf ( split_obj, config. export_all ) ?;
@@ -975,14 +1004,34 @@ fn split_write_obj(
975
1004
write_if_changed ( & out_path, data) ?;
976
1005
}
977
1006
978
- if let Some ( header) = & extract. header {
979
- let header_string = bin2c ( symbol, section, data) ;
980
- let out_path = base_dir. join ( "include" ) . join ( header. with_encoding ( ) ) ;
981
- if let Some ( parent) = out_path. parent ( ) {
982
- DirBuilder :: new ( ) . recursive ( true ) . create ( parent) ?;
1007
+ let header_kind = match extract. header_type . as_deref ( ) {
1008
+ Some ( value) => match HeaderKind :: from_str ( value) {
1009
+ Ok ( kind) => kind,
1010
+ Err ( ( ) ) => bail ! ( "Invalid header type '{}'" , value) ,
1011
+ } ,
1012
+ _ => HeaderKind :: Symbol ,
1013
+ } ;
1014
+
1015
+ if header_kind != HeaderKind :: None {
1016
+ if let Some ( header) = & extract. header {
1017
+ let header_string = bin2c ( symbol, section, data, header_kind) ;
1018
+ let out_path = base_dir. join ( "include" ) . join ( header. with_encoding ( ) ) ;
1019
+ if let Some ( parent) = out_path. parent ( ) {
1020
+ DirBuilder :: new ( ) . recursive ( true ) . create ( parent) ?;
1021
+ }
1022
+ write_if_changed ( & out_path, header_string. as_bytes ( ) ) ?;
983
1023
}
984
- write_if_changed ( & out_path, header_string. as_bytes ( ) ) ?;
985
1024
}
1025
+
1026
+ // Copy to output config
1027
+ out_config. extract . push ( OutputExtract {
1028
+ symbol : symbol. name . clone ( ) ,
1029
+ binary : extract. binary . clone ( ) ,
1030
+ header : extract. header . clone ( ) ,
1031
+ header_type : header_kind. to_string ( ) ,
1032
+ custom_type : extract. custom_type . clone ( ) ,
1033
+ custom_data : extract. custom_data . clone ( ) ,
1034
+ } ) ;
986
1035
}
987
1036
988
1037
// Generate ldscript.lcf
0 commit comments