/rust/registry/src/index.crates.io-1949cf8c6b5b557f/gimli-0.33.0/src/read/reader.rs
Line | Count | Source |
1 | | #[cfg(feature = "read")] |
2 | | use alloc::borrow::Cow; |
3 | | use core::convert::TryInto; |
4 | | use core::fmt::Debug; |
5 | | use core::hash::Hash; |
6 | | use core::ops::{Add, AddAssign, Sub}; |
7 | | |
8 | | use crate::common::Format; |
9 | | use crate::endianity::Endianity; |
10 | | use crate::leb128; |
11 | | use crate::read::{Error, Result}; |
12 | | |
13 | | /// An identifier for an offset within a section reader. |
14 | | /// |
15 | | /// This is used for error reporting. The meaning of this value is specific to |
16 | | /// each reader implementation. The values should be chosen to be unique amongst |
17 | | /// all readers. If values are not unique then errors may point to the wrong reader. |
18 | | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
19 | | pub struct ReaderOffsetId(pub u64); |
20 | | |
21 | | /// A trait for offsets with a DWARF section. |
22 | | /// |
23 | | /// This allows consumers to choose a size that is appropriate for their address space. |
24 | | pub trait ReaderOffset: |
25 | | Debug + Copy + Eq + Ord + Hash + Add<Output = Self> + AddAssign + Sub<Output = Self> |
26 | | { |
27 | | /// Convert a u8 to an offset. |
28 | | fn from_u8(offset: u8) -> Self; |
29 | | |
30 | | /// Convert a u16 to an offset. |
31 | | fn from_u16(offset: u16) -> Self; |
32 | | |
33 | | /// Convert an i16 to an offset. |
34 | | fn from_i16(offset: i16) -> Self; |
35 | | |
36 | | /// Convert a u32 to an offset. |
37 | | fn from_u32(offset: u32) -> Self; |
38 | | |
39 | | /// Convert a u64 to an offset. |
40 | | /// |
41 | | /// Returns `Error::UnsupportedOffset` if the value is too large. |
42 | | fn from_u64(offset: u64) -> Result<Self>; |
43 | | |
44 | | /// Convert an offset to a u64. |
45 | | fn into_u64(self) -> u64; |
46 | | |
47 | | /// Wrapping (modular) addition. Computes `self + other`. |
48 | | fn wrapping_add(self, other: Self) -> Self; |
49 | | |
50 | | /// Checked subtraction. Computes `self - other`. |
51 | | fn checked_sub(self, other: Self) -> Option<Self>; |
52 | | } |
53 | | |
54 | | impl ReaderOffset for u64 { |
55 | | #[inline] |
56 | 0 | fn from_u8(offset: u8) -> Self { |
57 | 0 | u64::from(offset) |
58 | 0 | } |
59 | | |
60 | | #[inline] |
61 | 0 | fn from_u16(offset: u16) -> Self { |
62 | 0 | u64::from(offset) |
63 | 0 | } |
64 | | |
65 | | #[inline] |
66 | 0 | fn from_i16(offset: i16) -> Self { |
67 | 0 | offset as u64 |
68 | 0 | } |
69 | | |
70 | | #[inline] |
71 | 0 | fn from_u32(offset: u32) -> Self { |
72 | 0 | u64::from(offset) |
73 | 0 | } |
74 | | |
75 | | #[inline] |
76 | 0 | fn from_u64(offset: u64) -> Result<Self> { |
77 | 0 | Ok(offset) |
78 | 0 | } |
79 | | |
80 | | #[inline] |
81 | 0 | fn into_u64(self) -> u64 { |
82 | 0 | self |
83 | 0 | } |
84 | | |
85 | | #[inline] |
86 | 0 | fn wrapping_add(self, other: Self) -> Self { |
87 | 0 | self.wrapping_add(other) |
88 | 0 | } |
89 | | |
90 | | #[inline] |
91 | 0 | fn checked_sub(self, other: Self) -> Option<Self> { |
92 | 0 | self.checked_sub(other) |
93 | 0 | } |
94 | | } |
95 | | |
96 | | impl ReaderOffset for u32 { |
97 | | #[inline] |
98 | 0 | fn from_u8(offset: u8) -> Self { |
99 | 0 | u32::from(offset) |
100 | 0 | } |
101 | | |
102 | | #[inline] |
103 | 0 | fn from_u16(offset: u16) -> Self { |
104 | 0 | u32::from(offset) |
105 | 0 | } |
106 | | |
107 | | #[inline] |
108 | 0 | fn from_i16(offset: i16) -> Self { |
109 | 0 | offset as u32 |
110 | 0 | } |
111 | | |
112 | | #[inline] |
113 | 0 | fn from_u32(offset: u32) -> Self { |
114 | 0 | offset |
115 | 0 | } |
116 | | |
117 | | #[inline] |
118 | 0 | fn from_u64(offset64: u64) -> Result<Self> { |
119 | 0 | let offset = offset64 as u32; |
120 | 0 | if u64::from(offset) == offset64 { |
121 | 0 | Ok(offset) |
122 | | } else { |
123 | 0 | Err(Error::UnsupportedOffset) |
124 | | } |
125 | 0 | } |
126 | | |
127 | | #[inline] |
128 | 0 | fn into_u64(self) -> u64 { |
129 | 0 | u64::from(self) |
130 | 0 | } |
131 | | |
132 | | #[inline] |
133 | 0 | fn wrapping_add(self, other: Self) -> Self { |
134 | 0 | self.wrapping_add(other) |
135 | 0 | } |
136 | | |
137 | | #[inline] |
138 | 0 | fn checked_sub(self, other: Self) -> Option<Self> { |
139 | 0 | self.checked_sub(other) |
140 | 0 | } |
141 | | } |
142 | | |
143 | | impl ReaderOffset for usize { |
144 | | #[inline] |
145 | 29.5M | fn from_u8(offset: u8) -> Self { |
146 | 29.5M | offset as usize |
147 | 29.5M | } <usize as gimli::read::reader::ReaderOffset>::from_u8 Line | Count | Source | 145 | 28.6M | fn from_u8(offset: u8) -> Self { | 146 | 28.6M | offset as usize | 147 | 28.6M | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::from_u8 <usize as gimli::read::reader::ReaderOffset>::from_u8 Line | Count | Source | 145 | 974k | fn from_u8(offset: u8) -> Self { | 146 | 974k | offset as usize | 147 | 974k | } |
|
148 | | |
149 | | #[inline] |
150 | 933k | fn from_u16(offset: u16) -> Self { |
151 | 933k | offset as usize |
152 | 933k | } <usize as gimli::read::reader::ReaderOffset>::from_u16 Line | Count | Source | 150 | 907k | fn from_u16(offset: u16) -> Self { | 151 | 907k | offset as usize | 152 | 907k | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::from_u16 <usize as gimli::read::reader::ReaderOffset>::from_u16 Line | Count | Source | 150 | 26.2k | fn from_u16(offset: u16) -> Self { | 151 | 26.2k | offset as usize | 152 | 26.2k | } |
|
153 | | |
154 | | #[inline] |
155 | 0 | fn from_i16(offset: i16) -> Self { |
156 | 0 | offset as usize |
157 | 0 | } |
158 | | |
159 | | #[inline] |
160 | 9.38M | fn from_u32(offset: u32) -> Self { |
161 | 9.38M | offset as usize |
162 | 9.38M | } <usize as gimli::read::reader::ReaderOffset>::from_u32 Line | Count | Source | 160 | 9.05M | fn from_u32(offset: u32) -> Self { | 161 | 9.05M | offset as usize | 162 | 9.05M | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::from_u32 <usize as gimli::read::reader::ReaderOffset>::from_u32 Line | Count | Source | 160 | 332k | fn from_u32(offset: u32) -> Self { | 161 | 332k | offset as usize | 162 | 332k | } |
|
163 | | |
164 | | #[inline] |
165 | 692k | fn from_u64(offset64: u64) -> Result<Self> { |
166 | 692k | let offset = offset64 as usize; |
167 | 692k | if offset as u64 == offset64 { |
168 | 692k | Ok(offset) |
169 | | } else { |
170 | 0 | Err(Error::UnsupportedOffset) |
171 | | } |
172 | 692k | } <usize as gimli::read::reader::ReaderOffset>::from_u64 Line | Count | Source | 165 | 662k | fn from_u64(offset64: u64) -> Result<Self> { | 166 | 662k | let offset = offset64 as usize; | 167 | 662k | if offset as u64 == offset64 { | 168 | 662k | Ok(offset) | 169 | | } else { | 170 | 0 | Err(Error::UnsupportedOffset) | 171 | | } | 172 | 662k | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::from_u64 <usize as gimli::read::reader::ReaderOffset>::from_u64 Line | Count | Source | 165 | 29.8k | fn from_u64(offset64: u64) -> Result<Self> { | 166 | 29.8k | let offset = offset64 as usize; | 167 | 29.8k | if offset as u64 == offset64 { | 168 | 29.8k | Ok(offset) | 169 | | } else { | 170 | 0 | Err(Error::UnsupportedOffset) | 171 | | } | 172 | 29.8k | } |
|
173 | | |
174 | | #[inline] |
175 | 8.41k | fn into_u64(self) -> u64 { |
176 | 8.41k | self as u64 |
177 | 8.41k | } <usize as gimli::read::reader::ReaderOffset>::into_u64 Line | Count | Source | 175 | 8.28k | fn into_u64(self) -> u64 { | 176 | 8.28k | self as u64 | 177 | 8.28k | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::into_u64 <usize as gimli::read::reader::ReaderOffset>::into_u64 Line | Count | Source | 175 | 139 | fn into_u64(self) -> u64 { | 176 | 139 | self as u64 | 177 | 139 | } |
|
178 | | |
179 | | #[inline] |
180 | 0 | fn wrapping_add(self, other: Self) -> Self { |
181 | 0 | self.wrapping_add(other) |
182 | 0 | } Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::wrapping_add Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::wrapping_add Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::wrapping_add |
183 | | |
184 | | #[inline] |
185 | 687k | fn checked_sub(self, other: Self) -> Option<Self> { |
186 | 687k | self.checked_sub(other) |
187 | 687k | } <usize as gimli::read::reader::ReaderOffset>::checked_sub Line | Count | Source | 185 | 682k | fn checked_sub(self, other: Self) -> Option<Self> { | 186 | 682k | self.checked_sub(other) | 187 | 682k | } |
Unexecuted instantiation: <usize as gimli::read::reader::ReaderOffset>::checked_sub <usize as gimli::read::reader::ReaderOffset>::checked_sub Line | Count | Source | 185 | 4.35k | fn checked_sub(self, other: Self) -> Option<Self> { | 186 | 4.35k | self.checked_sub(other) | 187 | 4.35k | } |
|
188 | | } |
189 | | |
190 | | /// A trait for addresses within a DWARF section. |
191 | | /// |
192 | | /// Currently this is a simple extension trait for `u64`, but it may be expanded |
193 | | /// in the future to support user-defined address types. |
194 | | pub(crate) trait ReaderAddress: Sized { |
195 | | /// Add a length to an address of the given size. |
196 | | /// |
197 | | /// Returns an error for overflow. |
198 | | fn add_sized(self, length: u64, size: u8) -> Result<Self>; |
199 | | |
200 | | /// Add a length to an address of the given size. |
201 | | /// |
202 | | /// Wraps the result to the size of the address to allow for the possibility |
203 | | /// that the length is a negative value. |
204 | | fn wrapping_add_sized(self, length: u64, size: u8) -> Self; |
205 | | |
206 | | /// The all-zeros value of an address. |
207 | | fn zeros() -> Self; |
208 | | |
209 | | /// The all-ones value of an address of the given size. |
210 | | fn ones_sized(size: u8) -> Self; |
211 | | |
212 | | /// Return the minimum value for a tombstone address. |
213 | | /// |
214 | | /// A variety of values may be used as tombstones in DWARF data. DWARF 6 specifies a |
215 | | /// tombstone value of -1, and this is compatible with most sections in earlier DWARF |
216 | | /// versions. However, for .debug_loc and .debug_ranges in DWARF 4 and earlier, the |
217 | | /// tombstone value is -2, because -1 already has a special meaning. -2 has also been |
218 | | /// seen in .debug_line, possibly from a proprietary fork of lld. |
219 | | /// |
220 | | /// So this function returns -2 (cast to an unsigned value), and callers can consider |
221 | | /// addresses greater than or equal to this value to be tombstones. |
222 | | /// |
223 | | /// Prior to the use of -1 or -2 for tombstones, it was common to use 0 or 1. |
224 | | /// Additionally, gold may leave the relocation addend in place. These values are not |
225 | | /// handled by this function, so callers will need to handle them separately if they |
226 | | /// want to. |
227 | 6.05M | fn min_tombstone(size: u8) -> Self { |
228 | 6.05M | Self::zeros().wrapping_add_sized(-2i64 as u64, size) |
229 | 6.05M | } <u64 as gimli::read::reader::ReaderAddress>::min_tombstone Line | Count | Source | 227 | 5.94M | fn min_tombstone(size: u8) -> Self { | 228 | 5.94M | Self::zeros().wrapping_add_sized(-2i64 as u64, size) | 229 | 5.94M | } |
Unexecuted instantiation: <_ as gimli::read::reader::ReaderAddress>::min_tombstone <u64 as gimli::read::reader::ReaderAddress>::min_tombstone Line | Count | Source | 227 | 100k | fn min_tombstone(size: u8) -> Self { | 228 | 100k | Self::zeros().wrapping_add_sized(-2i64 as u64, size) | 229 | 100k | } |
|
230 | | } |
231 | | |
232 | | impl ReaderAddress for u64 { |
233 | | #[inline] |
234 | 5.14M | fn add_sized(self, length: u64, size: u8) -> Result<Self> { |
235 | 5.14M | let address = self.checked_add(length).ok_or(Error::AddressOverflow)?; |
236 | 5.14M | let mask = Self::ones_sized(size); |
237 | 5.14M | if address & !mask != 0 { |
238 | 0 | return Err(Error::AddressOverflow); |
239 | 5.14M | } |
240 | 5.14M | Ok(address) |
241 | 5.14M | } <u64 as gimli::read::reader::ReaderAddress>::add_sized Line | Count | Source | 234 | 5.05M | fn add_sized(self, length: u64, size: u8) -> Result<Self> { | 235 | 5.05M | let address = self.checked_add(length).ok_or(Error::AddressOverflow)?; | 236 | 5.05M | let mask = Self::ones_sized(size); | 237 | 5.05M | if address & !mask != 0 { | 238 | 0 | return Err(Error::AddressOverflow); | 239 | 5.05M | } | 240 | 5.05M | Ok(address) | 241 | 5.05M | } |
Unexecuted instantiation: <u64 as gimli::read::reader::ReaderAddress>::add_sized <u64 as gimli::read::reader::ReaderAddress>::add_sized Line | Count | Source | 234 | 95.1k | fn add_sized(self, length: u64, size: u8) -> Result<Self> { | 235 | 95.1k | let address = self.checked_add(length).ok_or(Error::AddressOverflow)?; | 236 | 95.1k | let mask = Self::ones_sized(size); | 237 | 95.1k | if address & !mask != 0 { | 238 | 0 | return Err(Error::AddressOverflow); | 239 | 95.1k | } | 240 | 95.1k | Ok(address) | 241 | 95.1k | } |
|
242 | | |
243 | | #[inline] |
244 | 11.9M | fn wrapping_add_sized(self, length: u64, size: u8) -> Self { |
245 | 11.9M | let mask = Self::ones_sized(size); |
246 | 11.9M | self.wrapping_add(length) & mask |
247 | 11.9M | } <u64 as gimli::read::reader::ReaderAddress>::wrapping_add_sized Line | Count | Source | 244 | 11.7M | fn wrapping_add_sized(self, length: u64, size: u8) -> Self { | 245 | 11.7M | let mask = Self::ones_sized(size); | 246 | 11.7M | self.wrapping_add(length) & mask | 247 | 11.7M | } |
Unexecuted instantiation: <u64 as gimli::read::reader::ReaderAddress>::wrapping_add_sized <u64 as gimli::read::reader::ReaderAddress>::wrapping_add_sized Line | Count | Source | 244 | 199k | fn wrapping_add_sized(self, length: u64, size: u8) -> Self { | 245 | 199k | let mask = Self::ones_sized(size); | 246 | 199k | self.wrapping_add(length) & mask | 247 | 199k | } |
|
248 | | |
249 | | #[inline] |
250 | 6.05M | fn zeros() -> Self { |
251 | 6.05M | 0 |
252 | 6.05M | } <u64 as gimli::read::reader::ReaderAddress>::zeros Line | Count | Source | 250 | 5.94M | fn zeros() -> Self { | 251 | 5.94M | 0 | 252 | 5.94M | } |
Unexecuted instantiation: <u64 as gimli::read::reader::ReaderAddress>::zeros <u64 as gimli::read::reader::ReaderAddress>::zeros Line | Count | Source | 250 | 100k | fn zeros() -> Self { | 251 | 100k | 0 | 252 | 100k | } |
|
253 | | |
254 | | #[inline] |
255 | 17.1M | fn ones_sized(size: u8) -> Self { |
256 | 17.1M | !0 >> (64 - size * 8) |
257 | 17.1M | } <u64 as gimli::read::reader::ReaderAddress>::ones_sized Line | Count | Source | 255 | 16.8M | fn ones_sized(size: u8) -> Self { | 256 | 16.8M | !0 >> (64 - size * 8) | 257 | 16.8M | } |
Unexecuted instantiation: <u64 as gimli::read::reader::ReaderAddress>::ones_sized <u64 as gimli::read::reader::ReaderAddress>::ones_sized Line | Count | Source | 255 | 294k | fn ones_sized(size: u8) -> Self { | 256 | 294k | !0 >> (64 - size * 8) | 257 | 294k | } |
|
258 | | } |
259 | | |
260 | | #[cfg(not(feature = "read"))] |
261 | | pub(crate) mod seal_if_no_alloc { |
262 | | #[derive(Debug)] |
263 | | pub struct Sealed; |
264 | | } |
265 | | |
266 | | /// A trait for reading the data from a DWARF section. |
267 | | /// |
268 | | /// All read operations advance the section offset of the reader |
269 | | /// unless specified otherwise. |
270 | | /// |
271 | | /// ## Choosing a `Reader` Implementation |
272 | | /// |
273 | | /// `gimli` comes with a few different `Reader` implementations and lets you |
274 | | /// choose the one that is right for your use case. A `Reader` is essentially a |
275 | | /// view into the raw bytes that make up some DWARF, but this view might borrow |
276 | | /// the underlying data or use reference counting ownership, and it might be |
277 | | /// thread safe or not. |
278 | | /// |
279 | | /// | Implementation | Ownership | Thread Safe | Notes | |
280 | | /// |:------------------|:------------------|:------------|:------| |
281 | | /// | [`EndianSlice`](./struct.EndianSlice.html) | Borrowed | Yes | Fastest, but requires that all of your code work with borrows. | |
282 | | /// | [`EndianRcSlice`](./struct.EndianRcSlice.html) | Reference counted | No | Shared ownership via reference counting, which alleviates the borrow restrictions of `EndianSlice` but imposes reference counting increments and decrements. Cannot be sent across threads, because the reference count is not atomic. | |
283 | | /// | [`EndianArcSlice`](./struct.EndianArcSlice.html) | Reference counted | Yes | The same as `EndianRcSlice`, but uses atomic reference counting, and therefore reference counting operations are slower but `EndianArcSlice`s may be sent across threads. | |
284 | | /// | [`EndianReader<T>`](./struct.EndianReader.html) | Same as `T` | Same as `T` | Escape hatch for easily defining your own type of `Reader`. | |
285 | | pub trait Reader: Debug + Clone { |
286 | | /// The endianity of bytes that are read. |
287 | | type Endian: Endianity; |
288 | | |
289 | | /// The type used for offsets and lengths. |
290 | | type Offset: ReaderOffset; |
291 | | |
292 | | /// Return the endianity of bytes that are read. |
293 | | fn endian(&self) -> Self::Endian; |
294 | | |
295 | | /// Return the number of bytes remaining. |
296 | | fn len(&self) -> Self::Offset; |
297 | | |
298 | | /// Set the number of bytes remaining to zero. |
299 | | fn empty(&mut self); |
300 | | |
301 | | /// Set the number of bytes remaining to the specified length. |
302 | | fn truncate(&mut self, len: Self::Offset) -> Result<()>; |
303 | | |
304 | | /// Return the offset of this reader's data relative to the start of |
305 | | /// the given base reader's data. |
306 | | /// |
307 | | /// May panic if this reader's data is not contained within the given |
308 | | /// base reader's data. |
309 | | fn offset_from(&self, base: &Self) -> Self::Offset; |
310 | | |
311 | | /// Return an identifier for the current reader offset. |
312 | | fn offset_id(&self) -> ReaderOffsetId; |
313 | | |
314 | | /// Return the offset corresponding to the given `id` if |
315 | | /// it is associated with this reader. |
316 | | fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>; |
317 | | |
318 | | /// Find the index of the first occurrence of the given byte. |
319 | | /// The offset of the reader is not changed. |
320 | | fn find(&self, byte: u8) -> Result<Self::Offset>; |
321 | | |
322 | | /// Discard the specified number of bytes. |
323 | | fn skip(&mut self, len: Self::Offset) -> Result<()>; |
324 | | |
325 | | /// Split a reader in two. |
326 | | /// |
327 | | /// A new reader is returned that can be used to read the next |
328 | | /// `len` bytes, and `self` is advanced so that it reads the remainder. |
329 | | fn split(&mut self, len: Self::Offset) -> Result<Self>; |
330 | | |
331 | | /// This trait cannot be implemented if "read" feature is not enabled. |
332 | | /// |
333 | | /// `Reader` trait has a few methods that depend on `alloc` crate. |
334 | | /// Disallowing `Reader` trait implementation prevents a crate that only depends on |
335 | | /// "read-core" from being broken if another crate depending on `gimli` enables |
336 | | /// "read" feature. |
337 | | #[cfg(not(feature = "read"))] |
338 | | fn cannot_implement() -> seal_if_no_alloc::Sealed; |
339 | | |
340 | | /// Return all remaining data as a clone-on-write slice. |
341 | | /// |
342 | | /// The slice will be borrowed where possible, but some readers may |
343 | | /// always return an owned vector. |
344 | | /// |
345 | | /// Does not advance the reader. |
346 | | #[cfg(feature = "read")] |
347 | | fn to_slice(&self) -> Result<Cow<'_, [u8]>>; |
348 | | |
349 | | /// Convert all remaining data to a clone-on-write string. |
350 | | /// |
351 | | /// The string will be borrowed where possible, but some readers may |
352 | | /// always return an owned string. |
353 | | /// |
354 | | /// Does not advance the reader. |
355 | | /// |
356 | | /// Returns an error if the data contains invalid characters. |
357 | | #[cfg(feature = "read")] |
358 | | fn to_string(&self) -> Result<Cow<'_, str>>; |
359 | | |
360 | | /// Convert all remaining data to a clone-on-write string, including invalid characters. |
361 | | /// |
362 | | /// The string will be borrowed where possible, but some readers may |
363 | | /// always return an owned string. |
364 | | /// |
365 | | /// Does not advance the reader. |
366 | | #[cfg(feature = "read")] |
367 | | fn to_string_lossy(&self) -> Result<Cow<'_, str>>; |
368 | | |
369 | | /// Read exactly `buf.len()` bytes into `buf`. |
370 | | fn read_slice(&mut self, buf: &mut [u8]) -> Result<()>; |
371 | | |
372 | | /// Read a u8 array. |
373 | | #[inline] |
374 | 68.8M | fn read_u8_array<A>(&mut self) -> Result<A> |
375 | 68.8M | where |
376 | 68.8M | A: Sized + Default + AsMut<[u8]>, |
377 | | { |
378 | 68.8M | let mut val = Default::default(); |
379 | 68.8M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; |
380 | 68.8M | Ok(val) |
381 | 68.8M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 16]> Line | Count | Source | 374 | 40 | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 40 | where | 376 | 40 | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 40 | let mut val = Default::default(); | 379 | 40 | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 40 | Ok(val) | 381 | 40 | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 1]> Line | Count | Source | 374 | 46.7M | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 46.7M | where | 376 | 46.7M | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 46.7M | let mut val = Default::default(); | 379 | 46.7M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 46.7M | Ok(val) | 381 | 46.7M | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 2]> Line | Count | Source | 374 | 2.59M | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 2.59M | where | 376 | 2.59M | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 2.59M | let mut val = Default::default(); | 379 | 2.59M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 2.59M | Ok(val) | 381 | 2.59M | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 4]> Line | Count | Source | 374 | 9.63M | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 9.63M | where | 376 | 9.63M | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 9.63M | let mut val = Default::default(); | 379 | 9.63M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 9.63M | Ok(val) | 381 | 9.63M | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 8]> Line | Count | Source | 374 | 7.75M | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 7.75M | where | 376 | 7.75M | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 7.75M | let mut val = Default::default(); | 379 | 7.75M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 7.75M | Ok(val) | 381 | 7.75M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u8_array::<_> <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 16]> Line | Count | Source | 374 | 2 | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 2 | where | 376 | 2 | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 2 | let mut val = Default::default(); | 379 | 2 | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 2 | Ok(val) | 381 | 2 | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 1]> Line | Count | Source | 374 | 1.40M | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 1.40M | where | 376 | 1.40M | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 1.40M | let mut val = Default::default(); | 379 | 1.40M | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 1.40M | Ok(val) | 381 | 1.40M | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 2]> Line | Count | Source | 374 | 117k | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 117k | where | 376 | 117k | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 117k | let mut val = Default::default(); | 379 | 117k | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 117k | Ok(val) | 381 | 117k | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 4]> Line | Count | Source | 374 | 362k | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 362k | where | 376 | 362k | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 362k | let mut val = Default::default(); | 379 | 362k | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 362k | Ok(val) | 381 | 362k | } |
<gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8_array::<[u8; 8]> Line | Count | Source | 374 | 171k | fn read_u8_array<A>(&mut self) -> Result<A> | 375 | 171k | where | 376 | 171k | A: Sized + Default + AsMut<[u8]>, | 377 | | { | 378 | 171k | let mut val = Default::default(); | 379 | 171k | self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?; | 380 | 171k | Ok(val) | 381 | 171k | } |
|
382 | | |
383 | | /// Return true if the number of bytes remaining is zero. |
384 | | #[inline] |
385 | 0 | fn is_empty(&self) -> bool { |
386 | 0 | self.len() == Self::Offset::from_u8(0) |
387 | 0 | } |
388 | | |
389 | | /// Read a u8. |
390 | | #[inline] |
391 | 48.1M | fn read_u8(&mut self) -> Result<u8> { |
392 | 48.1M | let a: [u8; 1] = self.read_u8_array()?; |
393 | 48.1M | Ok(a[0]) |
394 | 48.1M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8 Line | Count | Source | 391 | 46.7M | fn read_u8(&mut self) -> Result<u8> { | 392 | 46.7M | let a: [u8; 1] = self.read_u8_array()?; | 393 | 46.7M | Ok(a[0]) | 394 | 46.7M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u8 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u8 Line | Count | Source | 391 | 1.40M | fn read_u8(&mut self) -> Result<u8> { | 392 | 1.40M | let a: [u8; 1] = self.read_u8_array()?; | 393 | 1.40M | Ok(a[0]) | 394 | 1.40M | } |
|
395 | | |
396 | | /// Read an i8. |
397 | | #[inline] |
398 | 10.2k | fn read_i8(&mut self) -> Result<i8> { |
399 | 10.2k | let a: [u8; 1] = self.read_u8_array()?; |
400 | 10.2k | Ok(a[0] as i8) |
401 | 10.2k | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i8 Line | Count | Source | 398 | 9.84k | fn read_i8(&mut self) -> Result<i8> { | 399 | 9.84k | let a: [u8; 1] = self.read_u8_array()?; | 400 | 9.84k | Ok(a[0] as i8) | 401 | 9.84k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_i8 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i8 Line | Count | Source | 398 | 430 | fn read_i8(&mut self) -> Result<i8> { | 399 | 430 | let a: [u8; 1] = self.read_u8_array()?; | 400 | 430 | Ok(a[0] as i8) | 401 | 430 | } |
|
402 | | |
403 | | /// Read a u16. |
404 | | #[inline] |
405 | 2.70M | fn read_u16(&mut self) -> Result<u16> { |
406 | 2.70M | let a: [u8; 2] = self.read_u8_array()?; |
407 | 2.70M | Ok(self.endian().read_u16(&a)) |
408 | 2.70M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u16 Line | Count | Source | 405 | 2.59M | fn read_u16(&mut self) -> Result<u16> { | 406 | 2.59M | let a: [u8; 2] = self.read_u8_array()?; | 407 | 2.59M | Ok(self.endian().read_u16(&a)) | 408 | 2.59M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u16 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u16 Line | Count | Source | 405 | 117k | fn read_u16(&mut self) -> Result<u16> { | 406 | 117k | let a: [u8; 2] = self.read_u8_array()?; | 407 | 117k | Ok(self.endian().read_u16(&a)) | 408 | 117k | } |
|
409 | | |
410 | | /// Read an i16. |
411 | | #[inline] |
412 | 24 | fn read_i16(&mut self) -> Result<i16> { |
413 | 24 | let a: [u8; 2] = self.read_u8_array()?; |
414 | 24 | Ok(self.endian().read_i16(&a)) |
415 | 24 | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i16 Line | Count | Source | 412 | 20 | fn read_i16(&mut self) -> Result<i16> { | 413 | 20 | let a: [u8; 2] = self.read_u8_array()?; | 414 | 20 | Ok(self.endian().read_i16(&a)) | 415 | 20 | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_i16 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i16 Line | Count | Source | 412 | 4 | fn read_i16(&mut self) -> Result<i16> { | 413 | 4 | let a: [u8; 2] = self.read_u8_array()?; | 414 | 4 | Ok(self.endian().read_i16(&a)) | 415 | 4 | } |
|
416 | | |
417 | | /// Read a u32. |
418 | | #[inline] |
419 | 9.99M | fn read_u32(&mut self) -> Result<u32> { |
420 | 9.99M | let a: [u8; 4] = self.read_u8_array()?; |
421 | 9.99M | Ok(self.endian().read_u32(&a)) |
422 | 9.99M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u32 Line | Count | Source | 419 | 9.63M | fn read_u32(&mut self) -> Result<u32> { | 420 | 9.63M | let a: [u8; 4] = self.read_u8_array()?; | 421 | 9.63M | Ok(self.endian().read_u32(&a)) | 422 | 9.63M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u32 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u32 Line | Count | Source | 419 | 362k | fn read_u32(&mut self) -> Result<u32> { | 420 | 362k | let a: [u8; 4] = self.read_u8_array()?; | 421 | 362k | Ok(self.endian().read_u32(&a)) | 422 | 362k | } |
|
423 | | |
424 | | /// Read an i32. |
425 | | #[inline] |
426 | 2 | fn read_i32(&mut self) -> Result<i32> { |
427 | 2 | let a: [u8; 4] = self.read_u8_array()?; |
428 | 2 | Ok(self.endian().read_i32(&a)) |
429 | 2 | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i32 Line | Count | Source | 426 | 2 | fn read_i32(&mut self) -> Result<i32> { | 427 | 2 | let a: [u8; 4] = self.read_u8_array()?; | 428 | 2 | Ok(self.endian().read_i32(&a)) | 429 | 2 | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_i32 Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i32 |
430 | | |
431 | | /// Read a u64. |
432 | | #[inline] |
433 | 7.92M | fn read_u64(&mut self) -> Result<u64> { |
434 | 7.92M | let a: [u8; 8] = self.read_u8_array()?; |
435 | 7.92M | Ok(self.endian().read_u64(&a)) |
436 | 7.92M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u64 Line | Count | Source | 433 | 7.75M | fn read_u64(&mut self) -> Result<u64> { | 434 | 7.75M | let a: [u8; 8] = self.read_u8_array()?; | 435 | 7.75M | Ok(self.endian().read_u64(&a)) | 436 | 7.75M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u64 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u64 Line | Count | Source | 433 | 171k | fn read_u64(&mut self) -> Result<u64> { | 434 | 171k | let a: [u8; 8] = self.read_u8_array()?; | 435 | 171k | Ok(self.endian().read_u64(&a)) | 436 | 171k | } |
|
437 | | |
438 | | /// Read a u128. |
439 | | #[inline] |
440 | 0 | fn read_u128(&mut self) -> Result<u128> { |
441 | 0 | let a: [u8; 16] = self.read_u8_array()?; |
442 | 0 | Ok(self.endian().read_u128(&a)) |
443 | 0 | } Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u128 Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_u128 Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_u128 |
444 | | |
445 | | /// Read an i64. |
446 | | #[inline] |
447 | 16 | fn read_i64(&mut self) -> Result<i64> { |
448 | 16 | let a: [u8; 8] = self.read_u8_array()?; |
449 | 16 | Ok(self.endian().read_i64(&a)) |
450 | 16 | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i64 Line | Count | Source | 447 | 16 | fn read_i64(&mut self) -> Result<i64> { | 448 | 16 | let a: [u8; 8] = self.read_u8_array()?; | 449 | 16 | Ok(self.endian().read_i64(&a)) | 450 | 16 | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_i64 Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_i64 |
451 | | |
452 | | /// Read a f32. |
453 | | #[inline] |
454 | 0 | fn read_f32(&mut self) -> Result<f32> { |
455 | 0 | let a: [u8; 4] = self.read_u8_array()?; |
456 | 0 | Ok(self.endian().read_f32(&a)) |
457 | 0 | } |
458 | | |
459 | | /// Read a f64. |
460 | | #[inline] |
461 | 0 | fn read_f64(&mut self) -> Result<f64> { |
462 | 0 | let a: [u8; 8] = self.read_u8_array()?; |
463 | 0 | Ok(self.endian().read_f64(&a)) |
464 | 0 | } |
465 | | |
466 | | /// Read an unsigned n-bytes integer u64. |
467 | | /// |
468 | | /// # Panics |
469 | | /// |
470 | | /// Panics when nbytes < 1 or nbytes > 8 |
471 | | #[inline] |
472 | 4 | fn read_uint(&mut self, n: usize) -> Result<u64> { |
473 | 4 | let mut buf = [0; 8]; |
474 | 4 | self.read_slice(&mut buf[..n])?; |
475 | 4 | Ok(self.endian().read_uint(&buf[..n])) |
476 | 4 | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uint Line | Count | Source | 472 | 4 | fn read_uint(&mut self, n: usize) -> Result<u64> { | 473 | 4 | let mut buf = [0; 8]; | 474 | 4 | self.read_slice(&mut buf[..n])?; | 475 | 4 | Ok(self.endian().read_uint(&buf[..n])) | 476 | 4 | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_uint Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uint |
477 | | |
478 | | /// Read a null-terminated slice, and return it (excluding the null). |
479 | 1.03M | fn read_null_terminated_slice(&mut self) -> Result<Self> { |
480 | 1.03M | let idx = self.find(0)?; |
481 | 1.03M | let val = self.split(idx)?; |
482 | 1.03M | self.skip(Self::Offset::from_u8(1))?; |
483 | 1.03M | Ok(val) |
484 | 1.03M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_null_terminated_slice Line | Count | Source | 479 | 993k | fn read_null_terminated_slice(&mut self) -> Result<Self> { | 480 | 993k | let idx = self.find(0)?; | 481 | 992k | let val = self.split(idx)?; | 482 | 992k | self.skip(Self::Offset::from_u8(1))?; | 483 | 992k | Ok(val) | 484 | 993k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_null_terminated_slice <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_null_terminated_slice Line | Count | Source | 479 | 46.3k | fn read_null_terminated_slice(&mut self) -> Result<Self> { | 480 | 46.3k | let idx = self.find(0)?; | 481 | 46.3k | let val = self.split(idx)?; | 482 | 46.3k | self.skip(Self::Offset::from_u8(1))?; | 483 | 46.3k | Ok(val) | 484 | 46.3k | } |
|
485 | | |
486 | | /// Skip a LEB128 encoded integer. |
487 | 30.1k | fn skip_leb128(&mut self) -> Result<()> { |
488 | 30.1k | leb128::read::skip(self) |
489 | 30.1k | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::skip_leb128 Line | Count | Source | 487 | 29.9k | fn skip_leb128(&mut self) -> Result<()> { | 488 | 29.9k | leb128::read::skip(self) | 489 | 29.9k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::skip_leb128 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::skip_leb128 Line | Count | Source | 487 | 246 | fn skip_leb128(&mut self) -> Result<()> { | 488 | 246 | leb128::read::skip(self) | 489 | 246 | } |
|
490 | | |
491 | | /// Read an unsigned LEB128 encoded integer. |
492 | 17.7M | fn read_uleb128(&mut self) -> Result<u64> { |
493 | 17.7M | leb128::read::unsigned(self) |
494 | 17.7M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128 Line | Count | Source | 492 | 17.2M | fn read_uleb128(&mut self) -> Result<u64> { | 493 | 17.2M | leb128::read::unsigned(self) | 494 | 17.2M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_uleb128 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128 Line | Count | Source | 492 | 513k | fn read_uleb128(&mut self) -> Result<u64> { | 493 | 513k | leb128::read::unsigned(self) | 494 | 513k | } |
|
495 | | |
496 | | /// Read an unsigned LEB128 encoded u32. |
497 | 330 | fn read_uleb128_u32(&mut self) -> Result<u32> { |
498 | 330 | leb128::read::unsigned(self)? |
499 | 330 | .try_into() |
500 | 330 | .map_err(|_| Error::BadUnsignedLeb128) |
501 | 330 | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128_u32 Line | Count | Source | 497 | 330 | fn read_uleb128_u32(&mut self) -> Result<u32> { | 498 | 330 | leb128::read::unsigned(self)? | 499 | 330 | .try_into() | 500 | 330 | .map_err(|_| Error::BadUnsignedLeb128) | 501 | 330 | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_uleb128_u32 Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128_u32 |
502 | | |
503 | | /// Read an unsigned LEB128 encoded u16. |
504 | 3.52M | fn read_uleb128_u16(&mut self) -> Result<u16> { |
505 | 3.52M | leb128::read::u16(self) |
506 | 3.52M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128_u16 Line | Count | Source | 504 | 3.43M | fn read_uleb128_u16(&mut self) -> Result<u16> { | 505 | 3.43M | leb128::read::u16(self) | 506 | 3.43M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_uleb128_u16 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_uleb128_u16 Line | Count | Source | 504 | 85.9k | fn read_uleb128_u16(&mut self) -> Result<u16> { | 505 | 85.9k | leb128::read::u16(self) | 506 | 85.9k | } |
|
507 | | |
508 | | /// Read a signed LEB128 encoded integer. |
509 | 2.47M | fn read_sleb128(&mut self) -> Result<i64> { |
510 | 2.47M | leb128::read::signed(self) |
511 | 2.47M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_sleb128 Line | Count | Source | 509 | 2.40M | fn read_sleb128(&mut self) -> Result<i64> { | 510 | 2.40M | leb128::read::signed(self) | 511 | 2.40M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_sleb128 <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_sleb128 Line | Count | Source | 509 | 70.5k | fn read_sleb128(&mut self) -> Result<i64> { | 510 | 70.5k | leb128::read::signed(self) | 511 | 70.5k | } |
|
512 | | |
513 | | /// Read an initial length field. |
514 | | /// |
515 | | /// This field is encoded as either a 32-bit length or |
516 | | /// a 64-bit length, and the returned `Format` indicates which. |
517 | 21.2k | fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> { |
518 | | const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0; |
519 | | const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff; |
520 | | |
521 | 21.2k | let val = self.read_u32()?; |
522 | 21.2k | if val < MAX_DWARF_32_UNIT_LENGTH { |
523 | 21.2k | Ok((Self::Offset::from_u32(val), Format::Dwarf32)) |
524 | 8 | } else if val == DWARF_64_INITIAL_UNIT_LENGTH { |
525 | 8 | let val = self.read_u64().and_then(Self::Offset::from_u64)?; |
526 | 8 | Ok((val, Format::Dwarf64)) |
527 | | } else { |
528 | 0 | Err(Error::UnknownReservedLength(val)) |
529 | | } |
530 | 21.2k | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_initial_length Line | Count | Source | 517 | 20.8k | fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> { | 518 | | const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0; | 519 | | const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff; | 520 | | | 521 | 20.8k | let val = self.read_u32()?; | 522 | 20.8k | if val < MAX_DWARF_32_UNIT_LENGTH { | 523 | 20.8k | Ok((Self::Offset::from_u32(val), Format::Dwarf32)) | 524 | 8 | } else if val == DWARF_64_INITIAL_UNIT_LENGTH { | 525 | 8 | let val = self.read_u64().and_then(Self::Offset::from_u64)?; | 526 | 8 | Ok((val, Format::Dwarf64)) | 527 | | } else { | 528 | 0 | Err(Error::UnknownReservedLength(val)) | 529 | | } | 530 | 20.8k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_initial_length <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_initial_length Line | Count | Source | 517 | 378 | fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> { | 518 | | const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0; | 519 | | const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff; | 520 | | | 521 | 378 | let val = self.read_u32()?; | 522 | 378 | if val < MAX_DWARF_32_UNIT_LENGTH { | 523 | 378 | Ok((Self::Offset::from_u32(val), Format::Dwarf32)) | 524 | 0 | } else if val == DWARF_64_INITIAL_UNIT_LENGTH { | 525 | 0 | let val = self.read_u64().and_then(Self::Offset::from_u64)?; | 526 | 0 | Ok((val, Format::Dwarf64)) | 527 | | } else { | 528 | 0 | Err(Error::UnknownReservedLength(val)) | 529 | | } | 530 | 378 | } |
|
531 | | |
532 | | /// Read a byte and validate it as an address size. |
533 | 14.1k | fn read_address_size(&mut self) -> Result<u8> { |
534 | 14.1k | let size = self.read_u8()?; |
535 | 14.1k | match size { |
536 | 14.1k | 1 | 2 | 4 | 8 => Ok(size), |
537 | 4 | _ => Err(Error::UnsupportedAddressSize(size)), |
538 | | } |
539 | 14.1k | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_address_size Line | Count | Source | 533 | 13.8k | fn read_address_size(&mut self) -> Result<u8> { | 534 | 13.8k | let size = self.read_u8()?; | 535 | 13.8k | match size { | 536 | 13.8k | 1 | 2 | 4 | 8 => Ok(size), | 537 | 4 | _ => Err(Error::UnsupportedAddressSize(size)), | 538 | | } | 539 | 13.8k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_address_size <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_address_size Line | Count | Source | 533 | 296 | fn read_address_size(&mut self) -> Result<u8> { | 534 | 296 | let size = self.read_u8()?; | 535 | 296 | match size { | 536 | 296 | 1 | 2 | 4 | 8 => Ok(size), | 537 | 0 | _ => Err(Error::UnsupportedAddressSize(size)), | 538 | | } | 539 | 296 | } |
|
540 | | |
541 | | /// Read an address-sized integer, and return it as a `u64`. |
542 | 7.86M | fn read_address(&mut self, address_size: u8) -> Result<u64> { |
543 | 7.86M | match address_size { |
544 | 4 | 1 => self.read_u8().map(u64::from), |
545 | 0 | 2 => self.read_u16().map(u64::from), |
546 | 5.75k | 4 => self.read_u32().map(u64::from), |
547 | 7.85M | 8 => self.read_u64(), |
548 | 0 | otherwise => Err(Error::UnsupportedAddressSize(otherwise)), |
549 | | } |
550 | 7.86M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_address Line | Count | Source | 542 | 7.69M | fn read_address(&mut self, address_size: u8) -> Result<u64> { | 543 | 7.69M | match address_size { | 544 | 4 | 1 => self.read_u8().map(u64::from), | 545 | 0 | 2 => self.read_u16().map(u64::from), | 546 | 5.74k | 4 => self.read_u32().map(u64::from), | 547 | 7.69M | 8 => self.read_u64(), | 548 | 0 | otherwise => Err(Error::UnsupportedAddressSize(otherwise)), | 549 | | } | 550 | 7.69M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_address <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_address Line | Count | Source | 542 | 167k | fn read_address(&mut self, address_size: u8) -> Result<u64> { | 543 | 167k | match address_size { | 544 | 0 | 1 => self.read_u8().map(u64::from), | 545 | 0 | 2 => self.read_u16().map(u64::from), | 546 | 3 | 4 => self.read_u32().map(u64::from), | 547 | 167k | 8 => self.read_u64(), | 548 | 0 | otherwise => Err(Error::UnsupportedAddressSize(otherwise)), | 549 | | } | 550 | 167k | } |
|
551 | | |
552 | | /// Parse a word-sized integer according to the DWARF format. |
553 | | /// |
554 | | /// These are always used to encode section offsets or lengths, |
555 | | /// and so have a type of `Self::Offset`. |
556 | 6.45M | fn read_word(&mut self, format: Format) -> Result<Self::Offset> { |
557 | 6.45M | match format { |
558 | 6.45M | Format::Dwarf32 => self.read_u32().map(Self::Offset::from_u32), |
559 | 0 | Format::Dwarf64 => self.read_u64().and_then(Self::Offset::from_u64), |
560 | | } |
561 | 6.45M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_word Line | Count | Source | 556 | 6.26M | fn read_word(&mut self, format: Format) -> Result<Self::Offset> { | 557 | 6.26M | match format { | 558 | 6.26M | Format::Dwarf32 => self.read_u32().map(Self::Offset::from_u32), | 559 | 0 | Format::Dwarf64 => self.read_u64().and_then(Self::Offset::from_u64), | 560 | | } | 561 | 6.26M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_word <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_word Line | Count | Source | 556 | 190k | fn read_word(&mut self, format: Format) -> Result<Self::Offset> { | 557 | 190k | match format { | 558 | 190k | Format::Dwarf32 => self.read_u32().map(Self::Offset::from_u32), | 559 | 0 | Format::Dwarf64 => self.read_u64().and_then(Self::Offset::from_u64), | 560 | | } | 561 | 190k | } |
|
562 | | |
563 | | /// Parse a word-sized section length according to the DWARF format. |
564 | | #[inline] |
565 | 5.93k | fn read_length(&mut self, format: Format) -> Result<Self::Offset> { |
566 | 5.93k | self.read_word(format) |
567 | 5.93k | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_length Line | Count | Source | 565 | 5.81k | fn read_length(&mut self, format: Format) -> Result<Self::Offset> { | 566 | 5.81k | self.read_word(format) | 567 | 5.81k | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_length <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_length Line | Count | Source | 565 | 126 | fn read_length(&mut self, format: Format) -> Result<Self::Offset> { | 566 | 126 | self.read_word(format) | 567 | 126 | } |
|
568 | | |
569 | | /// Parse a word-sized section offset according to the DWARF format. |
570 | | #[inline] |
571 | 6.45M | fn read_offset(&mut self, format: Format) -> Result<Self::Offset> { |
572 | 6.45M | self.read_word(format) |
573 | 6.45M | } <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_offset Line | Count | Source | 571 | 6.25M | fn read_offset(&mut self, format: Format) -> Result<Self::Offset> { | 572 | 6.25M | self.read_word(format) | 573 | 6.25M | } |
Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_offset <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_offset Line | Count | Source | 571 | 190k | fn read_offset(&mut self, format: Format) -> Result<Self::Offset> { | 572 | 190k | self.read_word(format) | 573 | 190k | } |
|
574 | | |
575 | | /// Parse a section offset of the given size. |
576 | | /// |
577 | | /// This is used for `DW_FORM_ref_addr` values in DWARF version 2. |
578 | 0 | fn read_sized_offset(&mut self, size: u8) -> Result<Self::Offset> { |
579 | 0 | match size { |
580 | 0 | 1 => self.read_u8().map(u64::from), |
581 | 0 | 2 => self.read_u16().map(u64::from), |
582 | 0 | 4 => self.read_u32().map(u64::from), |
583 | 0 | 8 => self.read_u64(), |
584 | 0 | otherwise => Err(Error::UnsupportedOffsetSize(otherwise)), |
585 | | } |
586 | 0 | .and_then(Self::Offset::from_u64) |
587 | 0 | } Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_sized_offset Unexecuted instantiation: <_ as gimli::read::reader::Reader>::read_sized_offset Unexecuted instantiation: <gimli::read::endian_slice::EndianSlice<gimli::endianity::RunTimeEndian> as gimli::read::reader::Reader>::read_sized_offset |
588 | | } |
589 | | |
590 | | #[cfg(test)] |
591 | | mod test { |
592 | | use super::*; |
593 | | |
594 | | #[test] |
595 | | fn test_min_tombstone() { |
596 | | assert_eq!(u64::min_tombstone(1), 0xfe); |
597 | | assert_eq!(u64::min_tombstone(2), 0xfffe); |
598 | | assert_eq!(u64::min_tombstone(4), 0xffff_fffe); |
599 | | assert_eq!(u64::min_tombstone(8), 0xffff_ffff_ffff_fffe); |
600 | | } |
601 | | } |