@@ -7,9 +7,10 @@ use std::io::{BufRead, BufReader};
7
7
use std:: path:: { Path , PathBuf } ;
8
8
use std:: process:: { Command , Stdio } ;
9
9
10
- use object:: read:: archive:: { ArchiveFile , ArchiveMember } ;
10
+ use object:: read:: archive:: ArchiveFile ;
11
11
use object:: {
12
- File as ObjFile , Object , ObjectSection , ObjectSymbol , Symbol , SymbolKind , SymbolScope ,
12
+ File as ObjFile , Object , ObjectSection , ObjectSymbol , Result as ObjResult , Symbol , SymbolKind ,
13
+ SymbolScope ,
13
14
} ;
14
15
use serde_json:: Value ;
15
16
@@ -71,7 +72,7 @@ fn check_paths<P: AsRef<Path>>(paths: &[P]) {
71
72
for path in paths {
72
73
let path = path. as_ref ( ) ;
73
74
println ! ( "Checking {}" , path. display( ) ) ;
74
- let archive = Archive :: from_path ( & path) ;
75
+ let archive = BinFile :: from_path ( & path) ;
75
76
76
77
verify_no_duplicates ( & archive) ;
77
78
verify_core_symbols ( & archive) ;
@@ -174,7 +175,7 @@ struct SymInfo {
174
175
}
175
176
176
177
impl SymInfo {
177
- fn new ( sym : & Symbol , obj : & ObjFile , member : & ArchiveMember ) -> Self {
178
+ fn new ( sym : & Symbol , obj : & ObjFile , obj_path : & str ) -> Self {
178
179
// Include the section name if possible. Fall back to the `Section` debug impl if not.
179
180
let section = sym. section ( ) ;
180
181
let section_name = sym
@@ -196,7 +197,7 @@ impl SymInfo {
196
197
is_weak : sym. is_weak ( ) ,
197
198
is_common : sym. is_common ( ) ,
198
199
address : sym. address ( ) ,
199
- object : String :: from_utf8_lossy ( member . name ( ) ) . into_owned ( ) ,
200
+ object : obj_path . to_owned ( ) ,
200
201
}
201
202
}
202
203
}
@@ -206,7 +207,7 @@ impl SymInfo {
206
207
/// Note that this will also locate cases where a symbol is weakly defined in more than one place.
207
208
/// Technically there are no linker errors that will come from this, but it keeps our binary more
208
209
/// straightforward and saves some distribution size.
209
- fn verify_no_duplicates ( archive : & Archive ) {
210
+ fn verify_no_duplicates ( archive : & BinFile ) {
210
211
let mut syms = BTreeMap :: < String , SymInfo > :: new ( ) ;
211
212
let mut dups = Vec :: new ( ) ;
212
213
let mut found_any = false ;
@@ -263,7 +264,7 @@ fn verify_no_duplicates(archive: &Archive) {
263
264
}
264
265
265
266
/// Ensure that there are no references to symbols from `core` that aren't also (somehow) defined.
266
- fn verify_core_symbols ( archive : & Archive ) {
267
+ fn verify_core_symbols ( archive : & BinFile ) {
267
268
let mut defined = BTreeSet :: new ( ) ;
268
269
let mut undefined = Vec :: new ( ) ;
269
270
let mut has_symbols = false ;
@@ -298,39 +299,59 @@ fn verify_core_symbols(archive: &Archive) {
298
299
}
299
300
300
301
/// Thin wrapper for owning data used by `object`.
301
- struct Archive {
302
+ struct BinFile {
303
+ path : PathBuf ,
302
304
data : Vec < u8 > ,
303
305
}
304
306
305
- impl Archive {
307
+ impl BinFile {
306
308
fn from_path ( path : & Path ) -> Self {
307
309
Self {
310
+ path : path. to_owned ( ) ,
308
311
data : fs:: read ( path) . expect ( "reading file failed" ) ,
309
312
}
310
313
}
311
314
312
- fn file ( & self ) -> ArchiveFile < ' _ > {
313
- ArchiveFile :: parse ( self . data . as_slice ( ) ) . expect ( "archive parse failed" )
315
+ fn as_archive_file ( & self ) -> ObjResult < ArchiveFile < ' _ > > {
316
+ ArchiveFile :: parse ( self . data . as_slice ( ) )
317
+ }
318
+
319
+ fn as_obj_file ( & self ) -> ObjResult < ObjFile < ' _ > > {
320
+ ObjFile :: parse ( self . data . as_slice ( ) )
314
321
}
315
322
316
323
/// For a given archive, do something with each object file.
317
- fn for_each_object ( & self , mut f : impl FnMut ( ObjFile , & ArchiveMember ) ) {
318
- let archive = self . file ( ) ;
319
-
320
- for member in archive. members ( ) {
321
- let member = member. expect ( "failed to access member" ) ;
322
- let obj_data = member
323
- . data ( self . data . as_slice ( ) )
324
- . expect ( "failed to access object" ) ;
325
- let obj = ObjFile :: parse ( obj_data) . expect ( "failed to parse object" ) ;
326
- f ( obj, & member) ;
324
+ fn for_each_object ( & self , mut f : impl FnMut ( ObjFile , & str ) ) {
325
+ let as_archive = self . as_archive_file ( ) ;
326
+ if let Ok ( archive) = as_archive {
327
+ for member in archive. members ( ) {
328
+ let member = member. expect ( "failed to access member" ) ;
329
+ let obj_data = member
330
+ . data ( self . data . as_slice ( ) )
331
+ . expect ( "failed to access object" ) ;
332
+ let obj = ObjFile :: parse ( obj_data) . expect ( "failed to parse object" ) ;
333
+ f ( obj, & String :: from_utf8_lossy ( member. name ( ) ) ) ;
334
+ }
335
+ return ;
327
336
}
337
+
338
+ let as_obj = self . as_obj_file ( ) ;
339
+ if let Ok ( obj) = as_obj {
340
+ f ( obj, & self . path . to_string_lossy ( ) ) ;
341
+ return ;
342
+ }
343
+
344
+ panic ! (
345
+ "failed to parse as either archive or object file: {:?}, {:?}" ,
346
+ as_archive. unwrap_err( ) ,
347
+ as_obj. unwrap_err( ) ,
348
+ ) ;
328
349
}
329
350
330
351
/// For a given archive, do something with each symbol.
331
- fn for_each_symbol ( & self , mut f : impl FnMut ( Symbol , & ObjFile , & ArchiveMember ) ) {
332
- self . for_each_object ( |obj, member | {
333
- obj. symbols ( ) . for_each ( |sym| f ( sym, & obj, member ) ) ;
352
+ fn for_each_symbol ( & self , mut f : impl FnMut ( Symbol , & ObjFile , & str ) ) {
353
+ self . for_each_object ( |obj, obj_path | {
354
+ obj. symbols ( ) . for_each ( |sym| f ( sym, & obj, obj_path ) ) ;
334
355
} ) ;
335
356
}
336
357
}
0 commit comments