]> git.proxmox.com Git - rustc.git/blob - vendor/gimli/src/read/reader.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / vendor / gimli / src / read / reader.rs
1 use alloc::borrow::Cow;
2 use core::convert::TryInto;
3 use core::fmt::Debug;
4 use core::hash::Hash;
5 use core::ops::{Add, AddAssign, Sub};
6
7 use crate::common::Format;
8 use crate::endianity::Endianity;
9 use crate::leb128;
10 use crate::read::{Error, Result};
11
12 /// An identifier for an offset within a section reader.
13 ///
14 /// This is used for error reporting. The meaning of this value is specific to
15 /// each reader implementation. The values should be chosen to be unique amongst
16 /// all readers. If values are not unique then errors may point to the wrong reader.
17 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
18 pub struct ReaderOffsetId(pub u64);
19
20 /// A trait for offsets with a DWARF section.
21 ///
22 /// This allows consumers to choose a size that is appropriate for their address space.
23 pub trait ReaderOffset:
24 Debug + Copy + Eq + Ord + Hash + Add<Output = Self> + AddAssign + Sub<Output = Self>
25 {
26 /// Convert a u8 to an offset.
27 fn from_u8(offset: u8) -> Self;
28
29 /// Convert a u16 to an offset.
30 fn from_u16(offset: u16) -> Self;
31
32 /// Convert an i16 to an offset.
33 fn from_i16(offset: i16) -> Self;
34
35 /// Convert a u32 to an offset.
36 fn from_u32(offset: u32) -> Self;
37
38 /// Convert a u64 to an offset.
39 ///
40 /// Returns `Error::UnsupportedOffset` if the value is too large.
41 fn from_u64(offset: u64) -> Result<Self>;
42
43 /// Convert an offset to a u64.
44 fn into_u64(self) -> u64;
45
46 /// Wrapping (modular) addition. Computes `self + other`.
47 fn wrapping_add(self, other: Self) -> Self;
48
49 /// Checked subtraction. Computes `self - other`.
50 fn checked_sub(self, other: Self) -> Option<Self>;
51 }
52
53 impl ReaderOffset for u64 {
54 #[inline]
55 fn from_u8(offset: u8) -> Self {
56 u64::from(offset)
57 }
58
59 #[inline]
60 fn from_u16(offset: u16) -> Self {
61 u64::from(offset)
62 }
63
64 #[inline]
65 fn from_i16(offset: i16) -> Self {
66 offset as u64
67 }
68
69 #[inline]
70 fn from_u32(offset: u32) -> Self {
71 u64::from(offset)
72 }
73
74 #[inline]
75 fn from_u64(offset: u64) -> Result<Self> {
76 Ok(offset)
77 }
78
79 #[inline]
80 fn into_u64(self) -> u64 {
81 self
82 }
83
84 #[inline]
85 fn wrapping_add(self, other: Self) -> Self {
86 self.wrapping_add(other)
87 }
88
89 #[inline]
90 fn checked_sub(self, other: Self) -> Option<Self> {
91 self.checked_sub(other)
92 }
93 }
94
95 impl ReaderOffset for u32 {
96 #[inline]
97 fn from_u8(offset: u8) -> Self {
98 u32::from(offset)
99 }
100
101 #[inline]
102 fn from_u16(offset: u16) -> Self {
103 u32::from(offset)
104 }
105
106 #[inline]
107 fn from_i16(offset: i16) -> Self {
108 offset as u32
109 }
110
111 #[inline]
112 fn from_u32(offset: u32) -> Self {
113 offset
114 }
115
116 #[inline]
117 fn from_u64(offset64: u64) -> Result<Self> {
118 let offset = offset64 as u32;
119 if u64::from(offset) == offset64 {
120 Ok(offset)
121 } else {
122 Err(Error::UnsupportedOffset)
123 }
124 }
125
126 #[inline]
127 fn into_u64(self) -> u64 {
128 u64::from(self)
129 }
130
131 #[inline]
132 fn wrapping_add(self, other: Self) -> Self {
133 self.wrapping_add(other)
134 }
135
136 #[inline]
137 fn checked_sub(self, other: Self) -> Option<Self> {
138 self.checked_sub(other)
139 }
140 }
141
142 impl ReaderOffset for usize {
143 #[inline]
144 fn from_u8(offset: u8) -> Self {
145 offset as usize
146 }
147
148 #[inline]
149 fn from_u16(offset: u16) -> Self {
150 offset as usize
151 }
152
153 #[inline]
154 fn from_i16(offset: i16) -> Self {
155 offset as usize
156 }
157
158 #[inline]
159 fn from_u32(offset: u32) -> Self {
160 offset as usize
161 }
162
163 #[inline]
164 fn from_u64(offset64: u64) -> Result<Self> {
165 let offset = offset64 as usize;
166 if offset as u64 == offset64 {
167 Ok(offset)
168 } else {
169 Err(Error::UnsupportedOffset)
170 }
171 }
172
173 #[inline]
174 fn into_u64(self) -> u64 {
175 self as u64
176 }
177
178 #[inline]
179 fn wrapping_add(self, other: Self) -> Self {
180 self.wrapping_add(other)
181 }
182
183 #[inline]
184 fn checked_sub(self, other: Self) -> Option<Self> {
185 self.checked_sub(other)
186 }
187 }
188
189 /// A trait for reading the data from a DWARF section.
190 ///
191 /// All read operations advance the section offset of the reader
192 /// unless specified otherwise.
193 ///
194 /// ## Choosing a `Reader` Implementation
195 ///
196 /// `gimli` comes with a few different `Reader` implementations and lets you
197 /// choose the one that is right for your use case. A `Reader` is essentially a
198 /// view into the raw bytes that make up some DWARF, but this view might borrow
199 /// the underlying data or use reference counting ownership, and it might be
200 /// thread safe or not.
201 ///
202 /// | Implementation | Ownership | Thread Safe | Notes |
203 /// |:------------------|:------------------|:------------|:------|
204 /// | [`EndianSlice`](./struct.EndianSlice.html) | Borrowed | Yes | Fastest, but requires that all of your code work with borrows. |
205 /// | [`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. |
206 /// | [`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. |
207 /// | [`EndianReader<T>`](./struct.EndianReader.html) | Same as `T` | Same as `T` | Escape hatch for easily defining your own type of `Reader`. |
208 pub trait Reader: Debug + Clone {
209 /// The endianity of bytes that are read.
210 type Endian: Endianity;
211
212 /// The type used for offsets and lengths.
213 type Offset: ReaderOffset;
214
215 /// Return the endianity of bytes that are read.
216 fn endian(&self) -> Self::Endian;
217
218 /// Return the number of bytes remaining.
219 fn len(&self) -> Self::Offset;
220
221 /// Set the number of bytes remaining to zero.
222 fn empty(&mut self);
223
224 /// Set the number of bytes remaining to the specified length.
225 fn truncate(&mut self, len: Self::Offset) -> Result<()>;
226
227 /// Return the offset of this reader's data relative to the start of
228 /// the given base reader's data.
229 ///
230 /// May panic if this reader's data is not contained within the given
231 /// base reader's data.
232 fn offset_from(&self, base: &Self) -> Self::Offset;
233
234 /// Return an identifier for the current reader offset.
235 fn offset_id(&self) -> ReaderOffsetId;
236
237 /// Return the offset corresponding to the given `id` if
238 /// it is associated with this reader.
239 fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>;
240
241 /// Find the index of the first occurence of the given byte.
242 /// The offset of the reader is not changed.
243 fn find(&self, byte: u8) -> Result<Self::Offset>;
244
245 /// Discard the specified number of bytes.
246 fn skip(&mut self, len: Self::Offset) -> Result<()>;
247
248 /// Split a reader in two.
249 ///
250 /// A new reader is returned that can be used to read the next
251 /// `len` bytes, and `self` is advanced so that it reads the remainder.
252 fn split(&mut self, len: Self::Offset) -> Result<Self>;
253
254 /// Return all remaining data as a clone-on-write slice.
255 ///
256 /// The slice will be borrowed where possible, but some readers may
257 /// always return an owned vector.
258 ///
259 /// Does not advance the reader.
260 fn to_slice(&self) -> Result<Cow<[u8]>>;
261
262 /// Convert all remaining data to a clone-on-write string.
263 ///
264 /// The string will be borrowed where possible, but some readers may
265 /// always return an owned string.
266 ///
267 /// Does not advance the reader.
268 ///
269 /// Returns an error if the data contains invalid characters.
270 fn to_string(&self) -> Result<Cow<str>>;
271
272 /// Convert all remaining data to a clone-on-write string, including invalid characters.
273 ///
274 /// The string will be borrowed where possible, but some readers may
275 /// always return an owned string.
276 ///
277 /// Does not advance the reader.
278 fn to_string_lossy(&self) -> Result<Cow<str>>;
279
280 /// Read exactly `buf.len()` bytes into `buf`.
281 fn read_slice(&mut self, buf: &mut [u8]) -> Result<()>;
282
283 /// Read a u8 array.
284 #[inline]
285 fn read_u8_array<A>(&mut self) -> Result<A>
286 where
287 A: Sized + Default + AsMut<[u8]>,
288 {
289 let mut val = Default::default();
290 self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?;
291 Ok(val)
292 }
293
294 /// Return true if the number of bytes remaining is zero.
295 #[inline]
296 fn is_empty(&self) -> bool {
297 self.len() == Self::Offset::from_u8(0)
298 }
299
300 /// Read a u8.
301 #[inline]
302 fn read_u8(&mut self) -> Result<u8> {
303 let a: [u8; 1] = self.read_u8_array()?;
304 Ok(a[0])
305 }
306
307 /// Read an i8.
308 #[inline]
309 fn read_i8(&mut self) -> Result<i8> {
310 let a: [u8; 1] = self.read_u8_array()?;
311 Ok(a[0] as i8)
312 }
313
314 /// Read a u16.
315 #[inline]
316 fn read_u16(&mut self) -> Result<u16> {
317 let a: [u8; 2] = self.read_u8_array()?;
318 Ok(self.endian().read_u16(&a))
319 }
320
321 /// Read an i16.
322 #[inline]
323 fn read_i16(&mut self) -> Result<i16> {
324 let a: [u8; 2] = self.read_u8_array()?;
325 Ok(self.endian().read_i16(&a))
326 }
327
328 /// Read a u32.
329 #[inline]
330 fn read_u32(&mut self) -> Result<u32> {
331 let a: [u8; 4] = self.read_u8_array()?;
332 Ok(self.endian().read_u32(&a))
333 }
334
335 /// Read an i32.
336 #[inline]
337 fn read_i32(&mut self) -> Result<i32> {
338 let a: [u8; 4] = self.read_u8_array()?;
339 Ok(self.endian().read_i32(&a))
340 }
341
342 /// Read a u64.
343 #[inline]
344 fn read_u64(&mut self) -> Result<u64> {
345 let a: [u8; 8] = self.read_u8_array()?;
346 Ok(self.endian().read_u64(&a))
347 }
348
349 /// Read an i64.
350 #[inline]
351 fn read_i64(&mut self) -> Result<i64> {
352 let a: [u8; 8] = self.read_u8_array()?;
353 Ok(self.endian().read_i64(&a))
354 }
355
356 /// Read a f32.
357 #[inline]
358 fn read_f32(&mut self) -> Result<f32> {
359 let a: [u8; 4] = self.read_u8_array()?;
360 Ok(self.endian().read_f32(&a))
361 }
362
363 /// Read a f64.
364 #[inline]
365 fn read_f64(&mut self) -> Result<f64> {
366 let a: [u8; 8] = self.read_u8_array()?;
367 Ok(self.endian().read_f64(&a))
368 }
369
370 /// Read an unsigned n-bytes integer u64.
371 ///
372 /// # Panics
373 ///
374 /// Panics when nbytes < 1 or nbytes > 8
375 #[inline]
376 fn read_uint(&mut self, n: usize) -> Result<u64> {
377 let mut buf = [0; 8];
378 self.read_slice(&mut buf[..n])?;
379 Ok(self.endian().read_uint(&buf[..n]))
380 }
381
382 /// Read a null-terminated slice, and return it (excluding the null).
383 fn read_null_terminated_slice(&mut self) -> Result<Self> {
384 let idx = self.find(0)?;
385 let val = self.split(idx)?;
386 self.skip(Self::Offset::from_u8(1))?;
387 Ok(val)
388 }
389
390 /// Read an unsigned LEB128 encoded integer.
391 fn read_uleb128(&mut self) -> Result<u64> {
392 leb128::read::unsigned(self)
393 }
394
395 /// Read an unsigned LEB128 encoded u32.
396 fn read_uleb128_u32(&mut self) -> Result<u32> {
397 leb128::read::unsigned(self)?
398 .try_into()
399 .map_err(|_| Error::BadUnsignedLeb128)
400 }
401
402 /// Read an unsigned LEB128 encoded u16.
403 fn read_uleb128_u16(&mut self) -> Result<u16> {
404 leb128::read::u16(self)
405 }
406
407 /// Read a signed LEB128 encoded integer.
408 fn read_sleb128(&mut self) -> Result<i64> {
409 leb128::read::signed(self)
410 }
411
412 /// Read an initial length field.
413 ///
414 /// This field is encoded as either a 32-bit length or
415 /// a 64-bit length, and the returned `Format` indicates which.
416 fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> {
417 const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0;
418 const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff;
419
420 let val = self.read_u32()?;
421 if val < MAX_DWARF_32_UNIT_LENGTH {
422 Ok((Self::Offset::from_u32(val), Format::Dwarf32))
423 } else if val == DWARF_64_INITIAL_UNIT_LENGTH {
424 let val = self.read_u64().and_then(Self::Offset::from_u64)?;
425 Ok((val, Format::Dwarf64))
426 } else {
427 Err(Error::UnknownReservedLength)
428 }
429 }
430
431 /// Read an address-sized integer, and return it as a `u64`.
432 fn read_address(&mut self, address_size: u8) -> Result<u64> {
433 match address_size {
434 1 => self.read_u8().map(u64::from),
435 2 => self.read_u16().map(u64::from),
436 4 => self.read_u32().map(u64::from),
437 8 => self.read_u64(),
438 otherwise => Err(Error::UnsupportedAddressSize(otherwise)),
439 }
440 }
441
442 /// Parse a word-sized integer according to the DWARF format.
443 ///
444 /// These are always used to encode section offsets or lengths,
445 /// and so have a type of `Self::Offset`.
446 fn read_word(&mut self, format: Format) -> Result<Self::Offset> {
447 match format {
448 Format::Dwarf32 => self.read_u32().map(Self::Offset::from_u32),
449 Format::Dwarf64 => self.read_u64().and_then(Self::Offset::from_u64),
450 }
451 }
452
453 /// Parse a word-sized section length according to the DWARF format.
454 #[inline]
455 fn read_length(&mut self, format: Format) -> Result<Self::Offset> {
456 self.read_word(format)
457 }
458
459 /// Parse a word-sized section offset according to the DWARF format.
460 #[inline]
461 fn read_offset(&mut self, format: Format) -> Result<Self::Offset> {
462 self.read_word(format)
463 }
464
465 /// Parse a section offset of the given size.
466 ///
467 /// This is used for `DW_FORM_ref_addr` values in DWARF version 2.
468 fn read_sized_offset(&mut self, size: u8) -> Result<Self::Offset> {
469 match size {
470 1 => self.read_u8().map(u64::from),
471 2 => self.read_u16().map(u64::from),
472 4 => self.read_u32().map(u64::from),
473 8 => self.read_u64(),
474 otherwise => Err(Error::UnsupportedOffsetSize(otherwise)),
475 }
476 .and_then(Self::Offset::from_u64)
477 }
478 }