1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use File;
use Path;
use ;
use crate::;
/// Opaque read-only mapping used by [`MappedGsym`].
///
/// Obtain one through [`MappedGsym::into_inner`] when direct access to the
/// mapped bytes is needed.
;
/// GSYM reader backed directly by a read-only memory map.
///
/// This is the same reader as [`Gsym`] with opaque mapped-byte storage, so it
/// has the same query API. Mapping suits a large file with sparse lookups, where
/// reading the whole file into memory would cost more than the lookups do.
///
/// Both constructors are `unsafe` because a memory map is not a snapshot. If
/// any process truncates or rewrites the file while it is mapped, results
/// borrowed from it can observe changed bytes or become invalid.
/// [`Gsym::open`] reads an owned snapshot instead and carries no such
/// requirement.
///
/// ```no_run
/// use gsym::MappedGsym;
///
/// // SAFETY: this process controls the file and keeps it immutable while mapped.
/// let gsym = unsafe { MappedGsym::map("app.gsym")? };
/// if let Some(symbol) = gsym.lookup(0x401000)? {
/// println!("{}", String::from_utf8_lossy(symbol.frames()[0].name));
/// }
/// # Ok::<(), gsym::Error>(())
/// ```
///
/// A mapped reader and an owned one parse the same file identically:
///
/// ```no_run
/// use gsym::{Gsym, MappedGsym};
///
/// let snapshot = Gsym::open("app.gsym")?;
///
/// // SAFETY: this application owns the file and keeps it immutable while mapped.
/// let mapped = unsafe { MappedGsym::map("app.gsym")? };
/// let file = std::fs::File::open("app.gsym")?;
/// // SAFETY: the same file-stability guarantee applies to this mapping.
/// let mapped_file = unsafe { MappedGsym::map_file(&file)? };
///
/// assert_eq!(snapshot.header(), mapped.header());
/// assert_eq!(mapped.header(), mapped_file.header());
/// # Ok::<(), gsym::Error>(())
/// ```
pub type MappedGsym = ;