@@ -58,7 +58,7 @@ struct Mapping {
5858 // 'static lifetime is a lie to hack around lack of support for self-referential structs.
5959 cx : Context < ' static > ,
6060 _map : Mmap ,
61- _stash : Stash ,
61+ stash : Stash ,
6262}
6363
6464enum Either < A , B > {
@@ -97,7 +97,7 @@ impl Mapping {
9797 // only borrow `map` and `stash` and we're preserving them below.
9898 cx : unsafe { core:: mem:: transmute :: < Context < ' _ > , Context < ' static > > ( cx) } ,
9999 _map : data,
100- _stash : stash,
100+ stash : stash,
101101 } )
102102 }
103103}
@@ -136,7 +136,10 @@ impl<'data> Context<'data> {
136136 package = Some (
137137 gimli:: DwarfPackage :: load (
138138 |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 ( & [ ] ) ;
140143 Ok ( EndianSlice :: new ( data, Endian ) )
141144 } ,
142145 EndianSlice :: new ( & [ ] , Endian ) ,
@@ -154,10 +157,10 @@ impl<'data> Context<'data> {
154157
155158 fn find_frames (
156159 & ' _ self ,
160+ stash : & ' data Stash ,
157161 probe : u64 ,
158162 ) -> gimli:: Result < addr2line:: FrameIter < ' _ , EndianSlice < ' data , Endian > > > {
159163 use addr2line:: { LookupContinuation , LookupResult } ;
160- use alloc:: sync:: Arc ;
161164
162165 let mut l = self . dwarf . find_frames ( probe) ;
163166 loop {
@@ -166,16 +169,7 @@ impl<'data> Context<'data> {
166169 LookupResult :: Load { load, continuation } => ( load, continuation) ,
167170 } ;
168171
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) ) ;
179173 }
180174 }
181175}
@@ -189,18 +183,18 @@ fn mmap(path: &Path) -> Option<Mmap> {
189183cfg_if:: cfg_if! {
190184 if #[ cfg( windows) ] {
191185 mod coff;
192- use self :: coff:: Object ;
186+ use self :: coff:: { handle_split_dwarf , Object } ;
193187 } else if #[ cfg( any(
194188 target_os = "macos" ,
195189 target_os = "ios" ,
196190 target_os = "tvos" ,
197191 target_os = "watchos" ,
198192 ) ) ] {
199193 mod macho;
200- use self :: macho:: Object ;
194+ use self :: macho:: { handle_split_dwarf , Object } ;
201195 } else {
202196 mod elf;
203- use self :: elf:: Object ;
197+ use self :: elf:: { handle_split_dwarf , Object } ;
204198 }
205199}
206200
@@ -349,7 +343,7 @@ impl Cache {
349343 . next ( )
350344 }
351345
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 ) > {
353347 let idx = self . mappings . iter ( ) . position ( |( idx, _) | * idx == lib) ;
354348
355349 // Invariant: after this conditional completes without early returning
@@ -375,10 +369,15 @@ impl Cache {
375369 self . mappings . insert ( 0 , ( lib, mapping) ) ;
376370 }
377371
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 ;
379375 // don't leak the `'static` lifetime, make sure it's scoped to just
380376 // 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+ ) )
382381 }
383382}
384383
@@ -400,12 +399,12 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
400399
401400 // Finally, get a cached mapping or create a new mapping for this file, and
402401 // 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 ) ,
405404 None => return ,
406405 } ;
407406 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 ) {
409408 while let Ok ( Some ( frame) ) = frames. next ( ) {
410409 any_frames = true ;
411410 let name = match frame. function {
@@ -421,7 +420,7 @@ pub unsafe fn resolve(what: ResolveWhat<'_>, cb: &mut dyn FnMut(&super::Symbol))
421420 }
422421 if !any_frames {
423422 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) {
425424 while let Ok ( Some ( frame) ) = frames. next ( ) {
426425 any_frames = true ;
427426 call ( Symbol :: Frame {
0 commit comments