@@ -58,7 +58,7 @@ struct Mapping {
58
58
// 'static lifetime is a lie to hack around lack of support for self-referential structs.
59
59
cx : Context < ' static > ,
60
60
_map : Mmap ,
61
- _stash : Stash ,
61
+ stash : Stash ,
62
62
}
63
63
64
64
enum Either < A , B > {
@@ -97,7 +97,7 @@ impl Mapping {
97
97
// only borrow `map` and `stash` and we're preserving them below.
98
98
cx : unsafe { core:: mem:: transmute :: < Context < ' _ > , Context < ' static > > ( cx) } ,
99
99
_map : data,
100
- _stash : stash,
100
+ stash : stash,
101
101
} )
102
102
}
103
103
}
@@ -136,7 +136,10 @@ impl<'data> Context<'data> {
136
136
package = Some (
137
137
gimli:: DwarfPackage :: load (
138
138
|id| -> Result < _ , gimli:: Error > {
139
- let data = dwp. section ( stash, id. dwo_name ( ) . unwrap ( ) ) . unwrap_or ( & [ ] ) ;
139
+ let data = id
140
+ . dwo_name ( )
141
+ . and_then ( |name| dwp. section ( stash, name) )
142
+ . unwrap_or ( & [ ] ) ;
140
143
Ok ( EndianSlice :: new ( data, Endian ) )
141
144
} ,
142
145
EndianSlice :: new ( & [ ] , Endian ) ,
@@ -154,10 +157,10 @@ impl<'data> Context<'data> {
154
157
155
158
fn find_frames (
156
159
& ' _ self ,
160
+ stash : & ' data Stash ,
157
161
probe : u64 ,
158
162
) -> gimli:: Result < addr2line:: FrameIter < ' _ , EndianSlice < ' data , Endian > > > {
159
163
use addr2line:: { LookupContinuation , LookupResult } ;
160
- use alloc:: sync:: Arc ;
161
164
162
165
let mut l = self . dwarf . find_frames ( probe) ;
163
166
loop {
@@ -166,16 +169,7 @@ impl<'data> Context<'data> {
166
169
LookupResult :: Load { load, continuation } => ( load, continuation) ,
167
170
} ;
168
171
169
- let mut r: Option < Arc < gimli:: Dwarf < _ > > > = None ;
170
- if let Some ( dwp) = self . package . as_ref ( ) {
171
- if let Ok ( Some ( cu) ) = dwp. find_cu ( load. dwo_id , & load. parent ) {
172
- r = Some ( Arc :: new ( cu) ) ;
173
- }
174
- }
175
-
176
- // TODO: support unpacked split DWARF.
177
-
178
- l = continuation. resume ( r) ;
172
+ l = continuation. resume ( handle_split_dwarf ( self . package . as_ref ( ) , stash, load) ) ;
179
173
}
180
174
}
181
175
}
@@ -189,18 +183,18 @@ fn mmap(path: &Path) -> Option<Mmap> {
189
183
cfg_if:: cfg_if! {
190
184
if #[ cfg( windows) ] {
191
185
mod coff;
192
- use self :: coff:: Object ;
186
+ use self :: coff:: { handle_split_dwarf , Object } ;
193
187
} else if #[ cfg( any(
194
188
target_os = "macos" ,
195
189
target_os = "ios" ,
196
190
target_os = "tvos" ,
197
191
target_os = "watchos" ,
198
192
) ) ] {
199
193
mod macho;
200
- use self :: macho:: Object ;
194
+ use self :: macho:: { handle_split_dwarf , Object } ;
201
195
} else {
202
196
mod elf;
203
- use self :: elf:: Object ;
197
+ use self :: elf:: { handle_split_dwarf , Object } ;
204
198
}
205
199
}
206
200
@@ -349,7 +343,7 @@ impl Cache {
349
343
. next ( )
350
344
}
351
345
352
- fn mapping_for_lib < ' a > ( & ' a mut self , lib : usize ) -> Option < & ' a mut Context < ' a > > {
346
+ fn mapping_for_lib < ' a > ( & ' a mut self , lib : usize ) -> Option < ( & ' a mut Context < ' a > , & ' a Stash ) > {
353
347
let idx = self . mappings . iter ( ) . position ( |( idx, _) | * idx == lib) ;
354
348
355
349
// Invariant: after this conditional completes without early returning
@@ -375,10 +369,15 @@ impl Cache {
375
369
self . mappings . insert ( 0 , ( lib, mapping) ) ;
376
370
}
377
371
378
- let cx: & ' a mut Context < ' static > = & mut self . mappings [ 0 ] . 1 . cx ;
372
+ let mapping = & mut self . mappings [ 0 ] . 1 ;
373
+ let cx: & ' a mut Context < ' static > = & mut mapping. cx ;
374
+ let stash: & ' a Stash = & mapping. stash ;
379
375
// don't leak the `'static` lifetime, make sure it's scoped to just
380
376
// ourselves
381
- Some ( unsafe { mem:: transmute :: < & ' a mut Context < ' static > , & ' a mut Context < ' a > > ( cx) } )
377
+ Some ( (
378
+ unsafe { mem:: transmute :: < & ' a mut Context < ' static > , & ' a mut Context < ' a > > ( cx) } ,
379
+ stash,
380
+ ) )
382
381
}
383
382
}
384
383
@@ -400,12 +399,12 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
400
399
401
400
// Finally, get a cached mapping or create a new mapping for this file, and
402
401
// evaluate the DWARF info to find the file/line/name for this address.
403
- let cx = match cache. mapping_for_lib ( lib) {
404
- Some ( cx ) => cx ,
402
+ let ( cx , stash ) = match cache. mapping_for_lib ( lib) {
403
+ Some ( ( cx , stash ) ) => ( cx , stash ) ,
405
404
None => return ,
406
405
} ;
407
406
let mut any_frames = false ;
408
- if let Ok ( mut frames) = cx. find_frames ( addr as u64 ) {
407
+ if let Ok ( mut frames) = cx. find_frames ( stash , addr as u64 ) {
409
408
while let Ok ( Some ( frame) ) = frames. next ( ) {
410
409
any_frames = true ;
411
410
let name = match frame. function {
@@ -421,7 +420,7 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
421
420
}
422
421
if !any_frames {
423
422
if let Some ( ( object_cx, object_addr) ) = cx. object . search_object_map ( addr as u64 ) {
424
- if let Ok ( mut frames) = object_cx. find_frames ( object_addr) {
423
+ if let Ok ( mut frames) = object_cx. find_frames ( stash , object_addr) {
425
424
while let Ok ( Some ( frame) ) = frames. next ( ) {
426
425
any_frames = true ;
427
426
call ( Symbol :: Frame {
0 commit comments