@@ -10,13 +10,12 @@ use std::path::PathBuf;
10
10
use std:: str:: from_utf8;
11
11
12
12
use object:: pe:: {
13
- ImageAuxSymbolSection , ImageFileHeader , ImageImportDescriptor , ImageRelocation ,
14
- ImageSectionHeader , ImageSymbol , ImportObjectHeader , IMAGE_COMDAT_SELECT_ANY ,
15
- IMAGE_FILE_32BIT_MACHINE , IMAGE_REL_AMD64_ADDR32NB , IMAGE_REL_ARM64_ADDR32NB ,
16
- IMAGE_REL_ARM_ADDR32NB , IMAGE_REL_I386_DIR32NB , IMAGE_SCN_ALIGN_2BYTES , IMAGE_SCN_ALIGN_4BYTES ,
17
- IMAGE_SCN_ALIGN_8BYTES , IMAGE_SCN_CNT_INITIALIZED_DATA , IMAGE_SCN_LNK_COMDAT ,
18
- IMAGE_SCN_LNK_INFO , IMAGE_SCN_LNK_REMOVE , IMAGE_SCN_MEM_READ , IMAGE_SCN_MEM_WRITE ,
19
- IMAGE_SYM_CLASS_EXTERNAL , IMAGE_SYM_CLASS_NULL , IMAGE_SYM_CLASS_SECTION ,
13
+ ImageFileHeader , ImageImportDescriptor , ImageRelocation , ImageSectionHeader , ImageSymbol ,
14
+ ImportObjectHeader , IMAGE_FILE_32BIT_MACHINE , IMAGE_REL_AMD64_ADDR32NB ,
15
+ IMAGE_REL_ARM64_ADDR32NB , IMAGE_REL_ARM_ADDR32NB , IMAGE_REL_I386_DIR32NB ,
16
+ IMAGE_SCN_ALIGN_2BYTES , IMAGE_SCN_ALIGN_4BYTES , IMAGE_SCN_ALIGN_8BYTES ,
17
+ IMAGE_SCN_CNT_INITIALIZED_DATA , IMAGE_SCN_LNK_INFO , IMAGE_SCN_LNK_REMOVE , IMAGE_SCN_MEM_READ ,
18
+ IMAGE_SCN_MEM_WRITE , IMAGE_SYM_CLASS_EXTERNAL , IMAGE_SYM_CLASS_NULL , IMAGE_SYM_CLASS_SECTION ,
20
19
IMAGE_SYM_CLASS_STATIC , IMAGE_SYM_CLASS_WEAK_EXTERNAL , IMAGE_WEAK_EXTERN_SEARCH_ALIAS ,
21
20
} ;
22
21
use object:: pod:: bytes_of;
@@ -27,6 +26,7 @@ use crate::{write_archive_to_stream, ArchiveKind, NewArchiveMember, DEFAULT_OBJE
27
26
28
27
pub ( crate ) const IMPORT_DESCRIPTOR_PREFIX : & [ u8 ] = b"__IMPORT_DESCRIPTOR_" ;
29
28
pub ( crate ) const NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME : & [ u8 ] = b"__NULL_IMPORT_DESCRIPTOR" ;
29
+ pub ( crate ) const NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME_PREFIX : & [ u8 ] = b"__NULL_IMPORT_DESCRIPTOR_" ;
30
30
pub ( crate ) const NULL_THUNK_DATA_PREFIX : & [ u8 ] = b"\x7f " ;
31
31
pub ( crate ) const NULL_THUNK_DATA_SUFFIX : & [ u8 ] = b"_NULL_THUNK_DATA" ;
32
32
@@ -209,10 +209,11 @@ struct ObjectFactory<'a> {
209
209
import_name : & ' a str ,
210
210
import_descriptor_symbol_name : Vec < u8 > ,
211
211
null_thunk_symbol_name : Vec < u8 > ,
212
+ null_import_descriptor_symbol_name : Vec < u8 > ,
212
213
}
213
214
214
215
impl < ' a > ObjectFactory < ' a > {
215
- fn new ( s : & ' a str , m : MachineTypes ) -> Result < Self > {
216
+ fn new ( s : & ' a str , m : MachineTypes , whole_archive_compat : bool ) -> Result < Self > {
216
217
let import_as_path = PathBuf :: from ( s) ;
217
218
let library = import_as_path
218
219
. file_stem ( )
@@ -239,6 +240,15 @@ impl<'a> ObjectFactory<'a> {
239
240
. chain ( NULL_THUNK_DATA_SUFFIX )
240
241
. copied ( )
241
242
. collect ( ) ,
243
+ null_import_descriptor_symbol_name : if whole_archive_compat {
244
+ NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME_PREFIX
245
+ . iter ( )
246
+ . chain ( library)
247
+ . copied ( )
248
+ . collect ( )
249
+ } else {
250
+ NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME . into ( )
251
+ } ,
242
252
} )
243
253
}
244
254
@@ -439,7 +449,7 @@ impl<'a> ObjectFactory<'a> {
439
449
size_of :: < u32 > ( )
440
450
+ self . import_descriptor_symbol_name . len ( )
441
451
+ 1
442
- + NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME . len ( )
452
+ + self . null_import_descriptor_symbol_name . len ( )
443
453
+ 1 ,
444
454
) ;
445
455
buffer. write_all ( bytes_of ( & symbol_table) ) ?;
@@ -449,7 +459,7 @@ impl<'a> ObjectFactory<'a> {
449
459
& mut buffer,
450
460
& [
451
461
& self . import_descriptor_symbol_name ,
452
- NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME ,
462
+ & self . null_import_descriptor_symbol_name ,
453
463
& self . null_thunk_symbol_name ,
454
464
] ,
455
465
) ?;
@@ -464,14 +474,11 @@ impl<'a> ObjectFactory<'a> {
464
474
/// Creates a NULL import descriptor. This is a small object file whcih
465
475
/// contains a NULL import descriptor. It is used to terminate the imports
466
476
/// from a specific DLL.
467
- ///
468
- /// If `comdat` is set to true, the NULL import descriptor's section (`.idata$3`) will be
469
- /// turned into a COMDAT section.
470
- fn create_null_import_descriptor ( & self , comdat : bool ) -> Result < NewArchiveMember < ' _ > > {
477
+ fn create_null_import_descriptor ( & self ) -> Result < NewArchiveMember < ' _ > > {
471
478
let mut buffer = Vec :: new ( ) ;
472
479
473
480
const NUMBER_OF_SECTIONS : usize = 1 ;
474
- let number_of_symbols = if comdat { 3 } else { 1 } ;
481
+ const NUMBER_OF_SYMBOLS : usize = 1 ;
475
482
476
483
// COFF Header
477
484
let header = ImageFileHeader {
@@ -481,7 +488,7 @@ impl<'a> ObjectFactory<'a> {
481
488
pointer_to_symbol_table : u32 !( ( size_of :: < ImageFileHeader > ( ) + ( NUMBER_OF_SECTIONS * size_of :: < ImageSectionHeader > ( ) ) +
482
489
// .idata$3
483
490
size_of :: < ImageImportDescriptor > ( ) ) . try_into ( ) . unwrap ( ) ) ,
484
- number_of_symbols : u32 !( number_of_symbols . try_into ( ) . unwrap ( ) ) ,
491
+ number_of_symbols : u32 !( NUMBER_OF_SYMBOLS . try_into ( ) . unwrap ( ) ) ,
485
492
size_of_optional_header : u16 !( 0 ) ,
486
493
characteristics : u16 !( if self . is_64_bit ( ) {
487
494
0
@@ -510,7 +517,6 @@ impl<'a> ObjectFactory<'a> {
510
517
| IMAGE_SCN_CNT_INITIALIZED_DATA
511
518
| IMAGE_SCN_MEM_READ
512
519
| IMAGE_SCN_MEM_WRITE
513
- | if comdat { IMAGE_SCN_LNK_COMDAT } else { 0 }
514
520
) ,
515
521
} ] ;
516
522
buffer. write_all ( bytes_of ( & section_table) ) ?;
@@ -526,41 +532,19 @@ impl<'a> ObjectFactory<'a> {
526
532
buffer. write_all ( bytes_of ( & import_descriptor) ) ?;
527
533
528
534
// Symbol Table
529
- if comdat {
530
- let symbol = ImageSymbol {
531
- name : * b".idata$3" ,
532
- value : u32 !( 0 ) ,
533
- section_number : u16 !( 1 ) ,
534
- typ : u16 !( 0 ) ,
535
- storage_class : IMAGE_SYM_CLASS_STATIC ,
536
- number_of_aux_symbols : 1 ,
537
- } ;
538
- let aux = ImageAuxSymbolSection {
539
- length : u32 !( size_of :: < ImageImportDescriptor > ( ) . try_into ( ) . unwrap ( ) ) ,
540
- number_of_relocations : u16 !( 0 ) ,
541
- number_of_linenumbers : u16 !( 0 ) ,
542
- check_sum : u32 !( 0 ) ,
543
- selection : IMAGE_COMDAT_SELECT_ANY ,
544
- number : u16 !( 0 ) ,
545
- reserved : 0 ,
546
- high_number : u16 !( 0 ) ,
547
- } ;
548
- buffer. write_all ( bytes_of ( & symbol) ) ?;
549
- buffer. write_all ( bytes_of ( & aux) ) ?;
550
- }
551
- let mut null_descriptor_symbol = ImageSymbol {
535
+ let mut symbol_table: [ _ ; NUMBER_OF_SYMBOLS ] = [ ImageSymbol {
552
536
name : [ 0 ; 8 ] ,
553
537
value : u32 !( 0 ) ,
554
538
section_number : u16 !( 1 ) ,
555
539
typ : u16 !( 0 ) ,
556
540
storage_class : IMAGE_SYM_CLASS_EXTERNAL ,
557
541
number_of_aux_symbols : 0 ,
558
- } ;
559
- set_name_to_string_table_entry ( & mut null_descriptor_symbol , size_of :: < u32 > ( ) ) ;
560
- buffer. write_all ( bytes_of ( & null_descriptor_symbol ) ) ?;
542
+ } ] ;
543
+ set_name_to_string_table_entry ( & mut symbol_table [ 0 ] , size_of :: < u32 > ( ) ) ;
544
+ buffer. write_all ( bytes_of ( & symbol_table ) ) ?;
561
545
562
546
// String Table
563
- write_string_table ( & mut buffer, & [ NULL_IMPORT_DESCRIPTOR_SYMBOL_NAME ] ) ?;
547
+ write_string_table ( & mut buffer, & [ & self . null_import_descriptor_symbol_name ] ) ?;
564
548
565
549
Ok ( NewArchiveMember :: new (
566
550
buffer. into_boxed_slice ( ) ,
@@ -853,20 +837,20 @@ pub fn write_import_library<W: Write + Seek>(
853
837
exports : & [ COFFShortExport ] ,
854
838
machine : MachineTypes ,
855
839
mingw : bool ,
856
- comdat : bool ,
840
+ whole_archive_compat : bool ,
857
841
) -> Result < ( ) > {
858
842
let native_machine = if machine == MachineTypes :: ARM64EC {
859
843
MachineTypes :: ARM64
860
844
} else {
861
845
machine
862
846
} ;
863
847
864
- let of = ObjectFactory :: new ( import_name, native_machine) ?;
848
+ let of = ObjectFactory :: new ( import_name, native_machine, whole_archive_compat ) ?;
865
849
let mut members = Vec :: new ( ) ;
866
850
867
851
members. push ( of. create_import_descriptor ( ) ?) ;
868
852
869
- members. push ( of. create_null_import_descriptor ( comdat ) ?) ;
853
+ members. push ( of. create_null_import_descriptor ( ) ?) ;
870
854
871
855
members. push ( of. create_null_thunk ( ) ?) ;
872
856
0 commit comments