1
- use super :: { Box , Context , Mapping , Mmap , Path , Stash , Vec } ;
1
+ use super :: { Box , Context , Mapping , Path , Stash , Vec } ;
2
2
use core:: convert:: TryInto ;
3
3
use object:: macho;
4
4
use object:: read:: macho:: { MachHeader , Nlist , Section , Segment as _} ;
@@ -30,8 +30,25 @@ impl Mapping {
30
30
// contains and try to find a macho file which has a matching UUID as
31
31
// the one of our own file. If we find a match that's the dwarf file we
32
32
// want to return.
33
- let parent = path. parent ( ) ?;
34
- for entry in parent. read_dir ( ) . ok ( ) ? {
33
+ if let Some ( parent) = path. parent ( ) {
34
+ if let Some ( mapping) = Mapping :: load_dsym ( parent, uuid) {
35
+ return Some ( mapping) ;
36
+ }
37
+ }
38
+
39
+ // Looks like nothing matched our UUID, so let's at least return our own
40
+ // file. This should have the symbol table for at least some
41
+ // symbolication purposes.
42
+ Mapping :: mk ( map, |data, stash| {
43
+ let ( macho, data) = find_header ( Bytes ( data) ) ?;
44
+ let endian = macho. endian ( ) . ok ( ) ?;
45
+ let obj = Object :: parse ( macho, endian, data) ?;
46
+ Context :: new ( stash, obj)
47
+ } )
48
+ }
49
+
50
+ fn load_dsym ( dir : & Path , uuid : [ u8 ; 16 ] ) -> Option < Mapping > {
51
+ for entry in dir. read_dir ( ) . ok ( ) ? {
35
52
let entry = entry. ok ( ) ?;
36
53
let filename = match entry. file_name ( ) . into_string ( ) {
37
54
Ok ( name) => name,
@@ -41,38 +58,36 @@ impl Mapping {
41
58
continue ;
42
59
}
43
60
let candidates = entry. path ( ) . join ( "Contents/Resources/DWARF" ) ;
44
- if let Some ( mapping) = load_dsym ( & candidates, uuid) {
61
+ if let Some ( mapping) = Mapping :: try_dsym_candidate ( & candidates, uuid) {
45
62
return Some ( mapping) ;
46
63
}
47
64
}
65
+ None
66
+ }
48
67
49
- // Looks like nothing matched our UUID, so let's at least return our own
50
- // file. This should have the symbol table for at least some
51
- // symbolication purposes.
52
- let stash = Stash :: new ( ) ;
53
- let inner = super :: cx ( & stash, Object :: parse ( macho, endian, data) ?) ?;
54
- return Some ( mk ! ( Mapping { map, inner, stash } ) ) ;
55
-
56
- fn load_dsym ( dir : & Path , uuid : [ u8 ; 16 ] ) -> Option < Mapping > {
57
- for entry in dir. read_dir ( ) . ok ( ) ? {
58
- let entry = entry. ok ( ) ?;
59
- let map = super :: mmap ( & entry. path ( ) ) ?;
60
- let ( macho, data) = find_header ( Bytes ( & map) ) ?;
68
+ fn try_dsym_candidate ( dir : & Path , uuid : [ u8 ; 16 ] ) -> Option < Mapping > {
69
+ // Look for files in the `DWARF` directory which have a matching uuid to
70
+ // the original object file. If we find one then we found the debug
71
+ // information.
72
+ for entry in dir. read_dir ( ) . ok ( ) ? {
73
+ let entry = entry. ok ( ) ?;
74
+ let map = super :: mmap ( & entry. path ( ) ) ?;
75
+ let candidate = Mapping :: mk ( map, |data, stash| {
76
+ let ( macho, data) = find_header ( Bytes ( data) ) ?;
61
77
let endian = macho. endian ( ) . ok ( ) ?;
62
78
let entry_uuid = macho. uuid ( endian, data) . ok ( ) ??;
63
79
if entry_uuid != uuid {
64
- continue ;
65
- }
66
- let stash = Stash :: new ( ) ;
67
- if let Some ( cx) =
68
- Object :: parse ( macho, endian, data) . and_then ( |o| super :: cx ( & stash, o) )
69
- {
70
- return Some ( mk ! ( Mapping { map, cx, stash } ) ) ;
80
+ return None ;
71
81
}
82
+ let obj = Object :: parse ( macho, endian, data) ?;
83
+ Context :: new ( stash, obj)
84
+ } ) ;
85
+ if let Some ( candidate) = candidate {
86
+ return Some ( candidate) ;
72
87
}
73
-
74
- None
75
88
}
89
+
90
+ None
76
91
}
77
92
}
78
93
@@ -269,25 +284,30 @@ fn object_mapping(path: &[u8]) -> Option<Mapping> {
269
284
let map;
270
285
271
286
// `N_OSO` symbol names can be either `/path/to/object.o` or `/path/to/archive.a(object.o)`.
272
- let data = if let Some ( ( archive_path, member_name) ) = split_archive_path ( path) {
287
+ let member_name = if let Some ( ( archive_path, member_name) ) = split_archive_path ( path) {
273
288
map = super :: mmap ( Path :: new ( OsStr :: from_bytes ( archive_path) ) ) ?;
274
- let archive = object:: read:: archive:: ArchiveFile :: parse ( & map) . ok ( ) ?;
275
- let member = archive
276
- . members ( )
277
- . filter_map ( Result :: ok)
278
- . find ( |m| m. name ( ) == member_name) ?;
279
- Bytes ( member. data ( ) )
289
+ Some ( member_name)
280
290
} else {
281
291
map = super :: mmap ( Path :: new ( OsStr :: from_bytes ( path) ) ) ?;
282
- Bytes ( & map )
292
+ None
283
293
} ;
284
-
285
- let ( macho, data) = find_header ( data) ?;
286
- let endian = macho. endian ( ) . ok ( ) ?;
287
- let object = Object :: parse ( macho, endian, data) ?;
288
- let stash = Stash :: new ( ) ;
289
- let inner = super :: cx ( & stash, object) ?;
290
- Some ( mk ! ( Mapping { map, inner, stash } ) )
294
+ Mapping :: mk ( map, |data, stash| {
295
+ let data = match member_name {
296
+ Some ( member_name) => {
297
+ let archive = object:: read:: archive:: ArchiveFile :: parse ( data) . ok ( ) ?;
298
+ let member = archive
299
+ . members ( )
300
+ . filter_map ( Result :: ok)
301
+ . find ( |m| m. name ( ) == member_name) ?;
302
+ Bytes ( member. data ( ) )
303
+ }
304
+ None => Bytes ( data) ,
305
+ } ;
306
+ let ( macho, data) = find_header ( data) ?;
307
+ let endian = macho. endian ( ) . ok ( ) ?;
308
+ let obj = Object :: parse ( macho, endian, data) ?;
309
+ Context :: new ( stash, obj)
310
+ } )
291
311
}
292
312
293
313
fn split_archive_path ( path : & [ u8 ] ) -> Option < ( & [ u8 ] , & [ u8 ] ) > {
0 commit comments