Skip to content

Commit d4032b2

Browse files
committed
Make DWARF debug info symbolication work on non-ELF again.
1 parent 101d2eb commit d4032b2

File tree

7 files changed

+120
-50
lines changed

7 files changed

+120
-50
lines changed

samply-symbols/src/binary_image.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use object::{
88
use crate::debugid_util::{code_id_for_object, debug_id_for_object};
99
use crate::error::Error;
1010
use crate::jitdump::{debug_id_and_code_id_for_jitdump, JitDumpIndex};
11-
use crate::macho::{DyldCacheFileData, MachOData, MachOFatArchiveMemberData, ObjectAndMachOData};
11+
use crate::macho::{DyldCacheFileData, MachOData, MachOFatArchiveMemberData};
1212
use crate::shared::{
1313
relative_address_base, CodeId, ElfBuildId, FileAndPathHelperError, FileContents,
1414
FileContentsWrapper, LibraryInfo, PeCodeId, RangeReadRef,
@@ -154,10 +154,9 @@ impl<F: FileContents> BinaryImageInner<F> {
154154
(debug_id, code_id, debug_path, debug_name, arch)
155155
}
156156
BinaryImageInner::MemberOfDyldSharedCache(dyld_cache_file_data) => {
157-
let ObjectAndMachOData { object, macho_data } =
158-
dyld_cache_file_data.make_object()?;
159-
let debug_id = debug_id_for_object(&object);
160-
let code_id = code_id_for_object(&object);
157+
let (obj, macho_data) = dyld_cache_file_data.make_object()?.into_parts();
158+
let debug_id = debug_id_for_object(&obj);
159+
let code_id = code_id_for_object(&obj);
161160
let (debug_path, debug_name) = (path.clone(), name.clone());
162161
let arch = macho_data.get_arch().map(ToOwned::to_owned);
163162
(debug_id, code_id, debug_path, debug_name, arch)
@@ -209,8 +208,8 @@ impl<F: FileContents> BinaryImageInner<F> {
209208
Ok(Some(obj))
210209
}
211210
BinaryImageInner::MemberOfDyldSharedCache(dyld_cache_file_data) => {
212-
let obj_and_macho_data = dyld_cache_file_data.make_object()?;
213-
Ok(Some(obj_and_macho_data.object))
211+
let (obj, _) = dyld_cache_file_data.make_object()?.into_parts();
212+
Ok(Some(obj))
214213
}
215214
BinaryImageInner::JitDump(_file, _index) => Ok(None),
216215
}

samply-symbols/src/elf.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub async fn load_symbol_map_for_elf<H: FileAndPathHelper>(
5353

5454
let owner = ElfSymbolMapDataAndObjects::new(file_contents, None, file_kind, None)?;
5555
let symbol_map = ObjectSymbolMap::new(owner)?;
56-
Ok(SymbolMap::new_with(
56+
Ok(SymbolMap::new_with_external_file_support(
5757
file_location,
5858
Box::new(symbol_map),
5959
helper,

samply-symbols/src/lib.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ where
557557
file_location,
558558
file_contents,
559559
file_kind,
560-
self.helper.clone(),
560+
self.helper(),
561561
)
562562
.await
563563
}
@@ -571,10 +571,11 @@ where
571571
file_location,
572572
file_contents,
573573
member,
574+
self.helper(),
574575
)
575576
}
576577
FileKind::MachO32 | FileKind::MachO64 => {
577-
macho::get_symbol_map_for_macho(file_location, file_contents)
578+
macho::get_symbol_map_for_macho(file_location, file_contents, self.helper())
578579
}
579580
FileKind::Pe32 | FileKind::Pe64 => {
580581
match windows::load_symbol_map_for_pdb_corresponding_to_binary(
@@ -586,9 +587,12 @@ where
586587
.await
587588
{
588589
Ok(symbol_map) => Ok(symbol_map),
589-
Err(_) => {
590-
windows::get_symbol_map_for_pe(file_contents, file_kind, file_location)
591-
}
590+
Err(_) => windows::get_symbol_map_for_pe(
591+
file_contents,
592+
file_kind,
593+
file_location,
594+
self.helper(),
595+
),
592596
}
593597
}
594598
_ => Err(Error::InvalidInputError(

samply-symbols/src/macho.rs

+46-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::marker::PhantomData;
2+
use std::sync::Arc;
23

34
use debugid::DebugId;
45
use macho_unwind_info::UnwindInfo;
@@ -15,6 +16,7 @@ use yoke_derive::Yokeable;
1516
use crate::binary_image::BinaryImage;
1617
use crate::binary_image::BinaryImageInner;
1718
use crate::debugid_util::debug_id_for_object;
19+
use crate::dwarf::Addr2lineContextData;
1820
use crate::error::Error;
1921
use crate::shared::{
2022
FileAndPathHelper, FileContents, FileContentsWrapper, FileLocation, MultiArchDisambiguator,
@@ -298,10 +300,35 @@ where
298300
dylib_path: String,
299301
}
300302

303+
type FileContentsRange<'data, T> = RangeReadRef<'data, &'data FileContentsWrapper<T>>;
304+
301305
#[derive(Yokeable)]
302306
pub struct ObjectAndMachOData<'data, T: FileContents + 'static> {
303-
pub object: File<'data, RangeReadRef<'data, &'data FileContentsWrapper<T>>>,
304-
pub macho_data: MachOData<'data, RangeReadRef<'data, &'data FileContentsWrapper<T>>>,
307+
object: File<'data, FileContentsRange<'data, T>>,
308+
macho_data: MachOData<'data, FileContentsRange<'data, T>>,
309+
addr2line_context: Addr2lineContextData,
310+
}
311+
312+
impl<'data, T: FileContents + 'static> ObjectAndMachOData<'data, T> {
313+
pub fn new(
314+
object: File<'data, FileContentsRange<'data, T>>,
315+
macho_data: MachOData<'data, FileContentsRange<'data, T>>,
316+
) -> Self {
317+
Self {
318+
object,
319+
macho_data,
320+
addr2line_context: Addr2lineContextData::new(),
321+
}
322+
}
323+
324+
pub fn into_parts(
325+
self,
326+
) -> (
327+
File<'data, FileContentsRange<'data, T>>,
328+
MachOData<'data, FileContentsRange<'data, T>>,
329+
) {
330+
(self.object, self.macho_data)
331+
}
305332
}
306333

307334
trait MakeMachObject<T: FileContents + 'static> {
@@ -347,7 +374,7 @@ impl<T: FileContents + 'static> DyldCacheFileData<T> {
347374
.image_data_and_offset()
348375
.map_err(Error::MachOHeaderParseError)?;
349376
let macho_data = MachOData::new(data, header_offset, object.is_64());
350-
Ok(ObjectAndMachOData { object, macho_data })
377+
Ok(ObjectAndMachOData::new(object, macho_data))
351378
}
352379
}
353380

@@ -373,13 +400,19 @@ impl<T: FileContents + 'static> FileDataAndObject<T> {
373400

374401
impl<T: FileContents + 'static> ObjectSymbolMapOuter<T> for FileDataAndObject<T> {
375402
fn make_symbol_map_inner(&self) -> Result<ObjectSymbolMapInnerWrapper<'_, T>, Error> {
376-
let ObjectAndMachOData { object, macho_data } = self.0.get();
403+
let ObjectAndMachOData {
404+
object,
405+
macho_data,
406+
addr2line_context,
407+
} = self.0.get();
377408
let (function_starts, function_ends) = compute_function_addresses_macho(macho_data, object);
378409
let debug_id = debug_id_for_object(object)
379410
.ok_or(Error::InvalidInputError("debug ID cannot be read"))?;
380411
let symbol_map = ObjectSymbolMapInnerWrapper::new(
381412
object,
382-
None,
413+
addr2line_context
414+
.make_context(macho_data.data, object, None, None)
415+
.ok(),
383416
debug_id,
384417
function_starts.as_deref(),
385418
function_ends.as_deref(),
@@ -393,28 +426,32 @@ impl<T: FileContents + 'static> ObjectSymbolMapOuter<T> for FileDataAndObject<T>
393426
pub fn get_symbol_map_for_macho<H: FileAndPathHelper>(
394427
debug_file_location: H::FL,
395428
file_contents: FileContentsWrapper<H::F>,
429+
helper: Arc<H>,
396430
) -> Result<SymbolMap<H>, Error> {
397431
let owner = FileDataAndObject::new(Box::new(MachSymbolMapData(file_contents)))?;
398432
let symbol_map = ObjectSymbolMap::new(owner)?;
399-
Ok(SymbolMap::new_plain(
433+
Ok(SymbolMap::new_with_external_file_support(
400434
debug_file_location,
401435
Box::new(symbol_map),
436+
helper,
402437
))
403438
}
404439

405440
pub fn get_symbol_map_for_fat_archive_member<H: FileAndPathHelper>(
406441
debug_file_location: H::FL,
407442
file_contents: FileContentsWrapper<H::F>,
408443
member: FatArchiveMember,
444+
helper: Arc<H>,
409445
) -> Result<SymbolMap<H>, Error> {
410446
let (start_offset, range_size) = member.offset_and_size;
411447
let owner =
412448
MachOFatArchiveMemberData::new(file_contents, start_offset, range_size, member.arch);
413449
let owner = FileDataAndObject::new(Box::new(owner))?;
414450
let symbol_map = ObjectSymbolMap::new(owner)?;
415-
Ok(SymbolMap::new_plain(
451+
Ok(SymbolMap::new_with_external_file_support(
416452
debug_file_location,
417453
Box::new(symbol_map),
454+
helper,
418455
))
419456
}
420457

@@ -429,7 +466,7 @@ impl<T: FileContents + 'static> MakeMachObject<T> for MachSymbolMapData<T> {
429466
let file_data = self.file_data();
430467
let object = File::parse(file_data).map_err(Error::MachOHeaderParseError)?;
431468
let macho_data = MachOData::new(file_data, 0, object.is_64());
432-
Ok(ObjectAndMachOData { object, macho_data })
469+
Ok(ObjectAndMachOData::new(object, macho_data))
433470
}
434471
}
435472

@@ -473,7 +510,7 @@ impl<T: FileContents + 'static> MakeMachObject<T> for MachOFatArchiveMemberData<
473510
fn make_dependent_object(&self) -> Result<ObjectAndMachOData<'_, T>, Error> {
474511
let object = File::parse(self.file_data()).map_err(Error::MachOHeaderParseError)?;
475512
let macho_data = MachOData::new(self.file_data(), 0, object.is_64());
476-
Ok(ObjectAndMachOData { object, macho_data })
513+
Ok(ObjectAndMachOData::new(object, macho_data))
477514
}
478515
}
479516

samply-symbols/src/symbol_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl<H: FileAndPathHelper> SymbolMap<H> {
6262
}
6363
}
6464

65-
pub(crate) fn new_with(
65+
pub(crate) fn new_with_external_file_support(
6666
debug_file_location: H::FL,
6767
inner: Box<dyn GetInnerSymbolMapWithLookupFramesExt<H::F> + Send + Sync>,
6868
helper: Arc<H>,

samply-symbols/src/symbol_map_object.rs

+22-21
Original file line numberDiff line numberDiff line change
@@ -529,27 +529,28 @@ where
529529
name,
530530
};
531531

532-
let Some(context) = self.context.as_ref() else {
533-
let frames = self.frames_lookup_for_object_map_references(svma);
534-
return Some(AddressInfo { symbol, frames });
535-
};
536-
537-
let context = context.lock().unwrap();
538-
let lookup_result = context.find_frames(svma);
539-
let frames = match lookup_result {
540-
LookupResult::Load { load, .. } => Some(FramesLookupResult::External(
541-
ExternalFileAddressRef::with_split_dwarf_load(&load, svma),
542-
)),
543-
LookupResult::Output(Ok(frame_iter)) => {
544-
let mut path_mapper = self.path_mapper.lock().unwrap();
545-
convert_frames(frame_iter, &mut path_mapper).map(FramesLookupResult::Available)
546-
}
547-
LookupResult::Output(Err(_)) => {
548-
drop(lookup_result);
549-
drop(context);
550-
self.frames_lookup_for_object_map_references(svma)
551-
}
552-
};
532+
let mut frames = None;
533+
if let Some(context) = self.context.as_ref() {
534+
let context = context.lock().unwrap();
535+
let lookup_result = context.find_frames(svma);
536+
frames = match lookup_result {
537+
LookupResult::Load { load, .. } => Some(FramesLookupResult::External(
538+
ExternalFileAddressRef::with_split_dwarf_load(&load, svma),
539+
)),
540+
LookupResult::Output(Ok(frame_iter)) => {
541+
let mut path_mapper = self.path_mapper.lock().unwrap();
542+
convert_frames(frame_iter, &mut path_mapper).map(FramesLookupResult::Available)
543+
}
544+
LookupResult::Output(Err(_)) => {
545+
drop(lookup_result);
546+
drop(context);
547+
self.frames_lookup_for_object_map_references(svma)
548+
}
549+
};
550+
}
551+
if frames.is_none() {
552+
frames = self.frames_lookup_for_object_map_references(svma);
553+
}
553554
Some(AddressInfo { symbol, frames })
554555
}
555556

samply-symbols/src/windows.rs

+35-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::borrow::Cow;
22
use std::collections::HashMap;
33
use std::ops::Deref;
4-
use std::sync::Mutex;
4+
use std::sync::{Arc, Mutex};
55

66
use debugid::DebugId;
77
use nom::bytes::complete::{tag, take_until1};
@@ -15,6 +15,7 @@ use yoke_derive::Yokeable;
1515

1616
use crate::debugid_util::debug_id_for_object;
1717
use crate::demangle;
18+
use crate::dwarf::Addr2lineContextData;
1819
use crate::error::{Context, Error};
1920
use crate::mapped_path::MappedPath;
2021
use crate::path_mapper::{ExtraPathMapper, PathMapper};
@@ -66,14 +67,36 @@ pub fn get_symbol_map_for_pe<H: FileAndPathHelper>(
6667
file_contents: FileContentsWrapper<H::F>,
6768
file_kind: FileKind,
6869
file_location: H::FL,
70+
helper: Arc<H>,
6971
) -> Result<SymbolMap<H>, Error> {
7072
let owner = PeSymbolMapDataAndObject::new(file_contents, file_kind)?;
7173
let symbol_map = ObjectSymbolMap::new(owner)?;
72-
Ok(SymbolMap::new_plain(file_location, Box::new(symbol_map)))
74+
Ok(SymbolMap::new_with_external_file_support(
75+
file_location,
76+
Box::new(symbol_map),
77+
helper,
78+
))
7379
}
7480

7581
#[derive(Yokeable)]
76-
struct PeObject<'data, T: FileContents>(File<'data, &'data FileContentsWrapper<T>>);
82+
struct PeObject<'data, T: FileContents> {
83+
file_data: &'data FileContentsWrapper<T>,
84+
object: File<'data, &'data FileContentsWrapper<T>>,
85+
addr2line_context: Addr2lineContextData,
86+
}
87+
88+
impl<'data, T: FileContents> PeObject<'data, T> {
89+
pub fn new(
90+
file_data: &'data FileContentsWrapper<T>,
91+
object: File<'data, &'data FileContentsWrapper<T>>,
92+
) -> Self {
93+
Self {
94+
file_data,
95+
object,
96+
addr2line_context: Addr2lineContextData::new(),
97+
}
98+
}
99+
}
77100

78101
struct PeSymbolMapDataAndObject<T: FileContents + 'static>(
79102
Yoke<PeObject<'static, T>, Box<FileContentsWrapper<T>>>,
@@ -85,7 +108,7 @@ impl<T: FileContents + 'static> PeSymbolMapDataAndObject<T> {
85108
move |file_data| -> Result<PeObject<'_, T>, Error> {
86109
let object =
87110
File::parse(file_data).map_err(|e| Error::ObjectParseError(file_kind, e))?;
88-
Ok(PeObject(object))
111+
Ok(PeObject::new(file_data, object))
89112
},
90113
)?;
91114
Ok(Self(data_and_object))
@@ -94,13 +117,19 @@ impl<T: FileContents + 'static> PeSymbolMapDataAndObject<T> {
94117

95118
impl<T: FileContents + 'static> ObjectSymbolMapOuter<T> for PeSymbolMapDataAndObject<T> {
96119
fn make_symbol_map_inner(&self) -> Result<ObjectSymbolMapInnerWrapper<T>, Error> {
97-
let object = &self.0.get().0;
120+
let PeObject {
121+
file_data,
122+
object,
123+
addr2line_context,
124+
} = &self.0.get();
98125
let debug_id = debug_id_for_object(object)
99126
.ok_or(Error::InvalidInputError("debug ID cannot be read"))?;
100127
let (function_starts, function_ends) = compute_function_addresses_pe(object);
101128
let symbol_map = ObjectSymbolMapInnerWrapper::new(
102129
object,
103-
None,
130+
addr2line_context
131+
.make_context(*file_data, object, None, None)
132+
.ok(),
104133
debug_id,
105134
function_starts.as_deref(),
106135
function_ends.as_deref(),

0 commit comments

Comments
 (0)