@@ -5,8 +5,10 @@ use std::process::Command;
5
5
6
6
use ar_archive_writer:: { ArchiveKind , COFFShortExport , MachineTypes } ;
7
7
use common:: { create_archive_with_ar_archive_writer, create_archive_with_llvm_ar} ;
8
+ use object:: coff:: CoffHeader ;
9
+ use object:: pe:: ImageFileHeader ;
8
10
use object:: read:: archive:: ArchiveFile ;
9
- use object:: { Architecture , SubArchitecture } ;
11
+ use object:: { bytes_of , Architecture , Object , SubArchitecture , U32Bytes } ;
10
12
use pretty_assertions:: assert_eq;
11
13
12
14
mod common;
@@ -99,6 +101,7 @@ fn create_import_library_with_ar_archive_writer(
99
101
temp_dir : & Path ,
100
102
machine_type : MachineTypes ,
101
103
mingw : bool ,
104
+ comdat : bool ,
102
105
) -> Vec < u8 > {
103
106
let mut output_bytes = Cursor :: new ( Vec :: new ( ) ) ;
104
107
ar_archive_writer:: write_import_library (
@@ -107,6 +110,7 @@ fn create_import_library_with_ar_archive_writer(
107
110
& get_members ( machine_type) ,
108
111
machine_type,
109
112
mingw,
113
+ comdat,
110
114
)
111
115
. unwrap ( ) ;
112
116
@@ -129,7 +133,7 @@ fn compare_to_lib() {
129
133
let temp_dir = common:: create_tmp_dir ( "import_library_compare_to_lib" ) ;
130
134
131
135
let archive_writer_bytes =
132
- create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, false ) ;
136
+ create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, false , false ) ;
133
137
134
138
let llvm_lib_bytes = {
135
139
let machine_arg = match machine_type {
@@ -164,6 +168,11 @@ fn compare_to_lib() {
164
168
llvm_lib_bytes, archive_writer_bytes,
165
169
"Import library differs. Machine type: {machine_type:?}" ,
166
170
) ;
171
+
172
+ compare_comdat (
173
+ & create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, false , true ) ,
174
+ & llvm_lib_bytes,
175
+ ) ;
167
176
}
168
177
}
169
178
@@ -178,7 +187,7 @@ fn compare_to_dlltool() {
178
187
let temp_dir = common:: create_tmp_dir ( "import_library_compare_to_dlltool" ) ;
179
188
180
189
let archive_writer_bytes =
181
- create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, true ) ;
190
+ create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, true , false ) ;
182
191
183
192
let llvm_lib_bytes = {
184
193
let machine_arg = match machine_type {
@@ -215,6 +224,11 @@ fn compare_to_dlltool() {
215
224
llvm_lib_bytes, archive_writer_bytes,
216
225
"Import library differs. Machine type: {machine_type:?}" ,
217
226
) ;
227
+
228
+ compare_comdat (
229
+ & create_import_library_with_ar_archive_writer ( & temp_dir, machine_type, true , true ) ,
230
+ & llvm_lib_bytes,
231
+ ) ;
218
232
}
219
233
}
220
234
@@ -237,10 +251,11 @@ fn wrap_in_archive() {
237
251
let mut import_lib_bytes = Cursor :: new ( Vec :: new ( ) ) ;
238
252
ar_archive_writer:: write_import_library (
239
253
& mut import_lib_bytes,
240
- & temp_dir. join ( "MyLibrary.dll" ) . to_string_lossy ( ) . to_string ( ) ,
254
+ & temp_dir. join ( "MyLibrary.dll" ) . to_string_lossy ( ) ,
241
255
& get_members ( machine_type) ,
242
256
machine_type,
243
257
false ,
258
+ false ,
244
259
)
245
260
. unwrap ( ) ;
246
261
let import_lib_bytes = import_lib_bytes. into_inner ( ) ;
@@ -281,3 +296,61 @@ fn wrap_in_archive() {
281
296
) ;
282
297
}
283
298
}
299
+
300
+ fn compare_comdat ( archive_writer_bytes : & [ u8 ] , llvm_bytes : & [ u8 ] ) {
301
+ let archive_writer = ArchiveFile :: parse ( archive_writer_bytes) . unwrap ( ) ;
302
+ let llvm = ArchiveFile :: parse ( llvm_bytes) . unwrap ( ) ;
303
+
304
+ for ( archive_member, llvm_member) in archive_writer. members ( ) . zip ( llvm. members ( ) ) {
305
+ let archive_member = archive_member. unwrap ( ) ;
306
+ let llvm_member = llvm_member. unwrap ( ) ;
307
+
308
+ if archive_member. size ( ) != llvm_member. size ( ) {
309
+ // Ensure that the member header is the same except for the file size.
310
+ let mut llvm_file_header = * llvm_member. header ( ) . unwrap ( ) ;
311
+ llvm_file_header. size = * b"163 " ;
312
+ assert_eq ! (
313
+ bytes_of( archive_member. header( ) . unwrap( ) ) ,
314
+ bytes_of( & llvm_file_header)
315
+ ) ;
316
+
317
+ // Ensure that the LLVM generated object contains .idata$3
318
+ object:: File :: parse ( llvm_member. data ( llvm_bytes) . unwrap ( ) )
319
+ . unwrap ( )
320
+ . section_by_name_bytes ( b".idata$3" )
321
+ . unwrap ( ) ;
322
+
323
+ // Ensure the COFF file headers are the same except for the symbol count.
324
+ let llvm_data = llvm_member. data ( llvm_bytes) . unwrap ( ) ;
325
+ let archive_data = archive_member. data ( archive_writer_bytes) . unwrap ( ) ;
326
+ let mut offset = 0 ;
327
+ let mut header = * ImageFileHeader :: parse ( llvm_data, & mut offset) . unwrap ( ) ;
328
+ header. number_of_symbols = U32Bytes :: from_bytes ( 3_u32 . to_le_bytes ( ) ) ;
329
+ assert_eq ! (
330
+ & archive_data[ ..size_of:: <ImageFileHeader >( ) ] ,
331
+ bytes_of( & header)
332
+ ) ;
333
+
334
+ // The rest of the object file will always be the same as `expected`
335
+ // for all import files no matter the platform.
336
+ let expected = [
337
+ 46 , 105 , 100 , 97 , 116 , 97 , 36 , 51 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 20 , 0 , 0 , 0 , 60 , 0 , 0 ,
338
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 64 , 16 , 48 , 192 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
339
+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 46 , 105 , 100 , 97 , 116 , 97 , 36 , 51 , 0 , 0 , 0 , 0 , 1 ,
340
+ 0 , 0 , 0 , 3 , 1 , 20 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 2 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
341
+ 4 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 2 , 0 , 29 , 0 , 0 , 0 , 95 , 95 , 78 , 85 , 76 , 76 , 95 ,
342
+ 73 , 77 , 80 , 79 , 82 , 84 , 95 , 68 , 69 , 83 , 67 , 82 , 73 , 80 , 84 , 79 , 82 , 0 ,
343
+ ] ;
344
+ assert_eq ! ( & archive_data[ size_of:: <ImageFileHeader >( ) ..] , & expected) ;
345
+ } else {
346
+ assert_eq ! (
347
+ bytes_of( archive_member. header( ) . unwrap( ) ) ,
348
+ bytes_of( llvm_member. header( ) . unwrap( ) )
349
+ ) ;
350
+ assert_eq ! (
351
+ archive_member. data( archive_writer_bytes) . unwrap( ) ,
352
+ llvm_member. data( llvm_bytes) . unwrap( )
353
+ ) ;
354
+ }
355
+ }
356
+ }
0 commit comments