1#[cfg(feature = "read")]
2use alloc::borrow::Cow;
3use core::convert::TryInto;
4use core::fmt::Debug;
5use core::hash::Hash;
6use core::ops::{Add, AddAssign, Sub};
78use crate::common::Format;
9use crate::endianity::Endianity;
10use crate::leb128;
11use crate::read::{Error, Result};
1213/// 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)]
19pub struct ReaderOffsetId(pub u64);
2021/// A trait for offsets with a DWARF section.
22///
23/// This allows consumers to choose a size that is appropriate for their address space.
24pub trait ReaderOffset:
25 Debug + Copy + Eq + Ord + Hash + Add<Output = Self> + AddAssign + Sub<Output = Self>
26{
27/// Convert a u8 to an offset.
28fn from_u8(offset: u8) -> Self;
2930/// Convert a u16 to an offset.
31fn from_u16(offset: u16) -> Self;
3233/// Convert an i16 to an offset.
34fn from_i16(offset: i16) -> Self;
3536/// Convert a u32 to an offset.
37fn from_u32(offset: u32) -> Self;
3839/// Convert a u64 to an offset.
40 ///
41 /// Returns `Error::UnsupportedOffset` if the value is too large.
42fn from_u64(offset: u64) -> Result<Self>;
4344/// Convert an offset to a u64.
45fn into_u64(self) -> u64;
4647/// Wrapping (modular) addition. Computes `self + other`.
48fn wrapping_add(self, other: Self) -> Self;
4950/// Checked subtraction. Computes `self - other`.
51fn checked_sub(self, other: Self) -> Option<Self>;
52}
5354impl ReaderOffset for u64 {
55#[inline]
56fn from_u8(offset: u8) -> Self {
57 u64::from(offset)
58 }
5960#[inline]
61fn from_u16(offset: u16) -> Self {
62 u64::from(offset)
63 }
6465#[inline]
66fn from_i16(offset: i16) -> Self {
67 offset as u64
68 }
6970#[inline]
71fn from_u32(offset: u32) -> Self {
72 u64::from(offset)
73 }
7475#[inline]
76fn from_u64(offset: u64) -> Result<Self> {
77Ok(offset)
78 }
7980#[inline]
81fn into_u64(self) -> u64 {
82self
83}
8485#[inline]
86fn wrapping_add(self, other: Self) -> Self {
87self.wrapping_add(other)
88 }
8990#[inline]
91fn checked_sub(self, other: Self) -> Option<Self> {
92self.checked_sub(other)
93 }
94}
9596impl ReaderOffset for u32 {
97#[inline]
98fn from_u8(offset: u8) -> Self {
99 u32::from(offset)
100 }
101102#[inline]
103fn from_u16(offset: u16) -> Self {
104 u32::from(offset)
105 }
106107#[inline]
108fn from_i16(offset: i16) -> Self {
109 offset as u32
110 }
111112#[inline]
113fn from_u32(offset: u32) -> Self {
114 offset
115 }
116117#[inline]
118fn from_u64(offset64: u64) -> Result<Self> {
119let offset = offset64 as u32;
120if u64::from(offset) == offset64 {
121Ok(offset)
122 } else {
123Err(Error::UnsupportedOffset)
124 }
125 }
126127#[inline]
128fn into_u64(self) -> u64 {
129 u64::from(self)
130 }
131132#[inline]
133fn wrapping_add(self, other: Self) -> Self {
134self.wrapping_add(other)
135 }
136137#[inline]
138fn checked_sub(self, other: Self) -> Option<Self> {
139self.checked_sub(other)
140 }
141}
142143impl ReaderOffset for usize {
144#[inline]
145fn from_u8(offset: u8) -> Self {
146 offset as usize
147 }
148149#[inline]
150fn from_u16(offset: u16) -> Self {
151 offset as usize
152 }
153154#[inline]
155fn from_i16(offset: i16) -> Self {
156 offset as usize
157 }
158159#[inline]
160fn from_u32(offset: u32) -> Self {
161 offset as usize
162 }
163164#[inline]
165fn from_u64(offset64: u64) -> Result<Self> {
166let offset = offset64 as usize;
167if offset as u64 == offset64 {
168Ok(offset)
169 } else {
170Err(Error::UnsupportedOffset)
171 }
172 }
173174#[inline]
175fn into_u64(self) -> u64 {
176self as u64
177 }
178179#[inline]
180fn wrapping_add(self, other: Self) -> Self {
181self.wrapping_add(other)
182 }
183184#[inline]
185fn checked_sub(self, other: Self) -> Option<Self> {
186self.checked_sub(other)
187 }
188}
189190/// 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.
194pub(crate) trait ReaderAddress: Sized {
195/// Add a length to an address of the given size.
196 ///
197 /// Returns an error for overflow.
198fn add_sized(self, length: u64, size: u8) -> Result<Self>;
199200/// 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.
204fn wrapping_add_sized(self, length: u64, size: u8) -> Self;
205206/// The all-ones value of an address of the given size.
207fn ones_sized(size: u8) -> Self;
208}
209210impl ReaderAddress for u64 {
211#[inline]
212fn add_sized(self, length: u64, size: u8) -> Result<Self> {
213let address = self.checked_add(length).ok_or(Error::AddressOverflow)?;
214let mask = Self::ones_sized(size);
215if address & !mask != 0 {
216return Err(Error::AddressOverflow);
217 }
218Ok(address)
219 }
220221#[inline]
222fn wrapping_add_sized(self, length: u64, size: u8) -> Self {
223let mask = Self::ones_sized(size);
224self.wrapping_add(length) & mask
225 }
226227#[inline]
228fn ones_sized(size: u8) -> Self {
229 !0 >> (64 - size * 8)
230 }
231}
232233#[cfg(not(feature = "read"))]
234pub(crate) mod seal_if_no_alloc {
235#[derive(Debug)]
236pub struct Sealed;
237}
238239/// A trait for reading the data from a DWARF section.
240///
241/// All read operations advance the section offset of the reader
242/// unless specified otherwise.
243///
244/// ## Choosing a `Reader` Implementation
245///
246/// `gimli` comes with a few different `Reader` implementations and lets you
247/// choose the one that is right for your use case. A `Reader` is essentially a
248/// view into the raw bytes that make up some DWARF, but this view might borrow
249/// the underlying data or use reference counting ownership, and it might be
250/// thread safe or not.
251///
252/// | Implementation | Ownership | Thread Safe | Notes |
253/// |:------------------|:------------------|:------------|:------|
254/// | [`EndianSlice`](./struct.EndianSlice.html) | Borrowed | Yes | Fastest, but requires that all of your code work with borrows. |
255/// | [`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. |
256/// | [`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. |
257/// | [`EndianReader<T>`](./struct.EndianReader.html) | Same as `T` | Same as `T` | Escape hatch for easily defining your own type of `Reader`. |
258pub trait Reader: Debug + Clone {
259/// The endianity of bytes that are read.
260type Endian: Endianity;
261262/// The type used for offsets and lengths.
263type Offset: ReaderOffset;
264265/// Return the endianity of bytes that are read.
266fn endian(&self) -> Self::Endian;
267268/// Return the number of bytes remaining.
269fn len(&self) -> Self::Offset;
270271/// Set the number of bytes remaining to zero.
272fn empty(&mut self);
273274/// Set the number of bytes remaining to the specified length.
275fn truncate(&mut self, len: Self::Offset) -> Result<()>;
276277/// Return the offset of this reader's data relative to the start of
278 /// the given base reader's data.
279 ///
280 /// May panic if this reader's data is not contained within the given
281 /// base reader's data.
282fn offset_from(&self, base: &Self) -> Self::Offset;
283284/// Return an identifier for the current reader offset.
285fn offset_id(&self) -> ReaderOffsetId;
286287/// Return the offset corresponding to the given `id` if
288 /// it is associated with this reader.
289fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>;
290291/// Find the index of the first occurrence of the given byte.
292 /// The offset of the reader is not changed.
293fn find(&self, byte: u8) -> Result<Self::Offset>;
294295/// Discard the specified number of bytes.
296fn skip(&mut self, len: Self::Offset) -> Result<()>;
297298/// Split a reader in two.
299 ///
300 /// A new reader is returned that can be used to read the next
301 /// `len` bytes, and `self` is advanced so that it reads the remainder.
302fn split(&mut self, len: Self::Offset) -> Result<Self>;
303304/// This trait cannot be implemented if "read" feature is not enabled.
305 ///
306 /// `Reader` trait has a few methods that depend on `alloc` crate.
307 /// Disallowing `Reader` trait implementation prevents a crate that only depends on
308 /// "read-core" from being broken if another crate depending on `gimli` enables
309 /// "read" feature.
310#[cfg(not(feature = "read"))]
311fn cannot_implement() -> seal_if_no_alloc::Sealed;
312313/// Return all remaining data as a clone-on-write slice.
314 ///
315 /// The slice will be borrowed where possible, but some readers may
316 /// always return an owned vector.
317 ///
318 /// Does not advance the reader.
319#[cfg(feature = "read")]
320fn to_slice(&self) -> Result<Cow<'_, [u8]>>;
321322/// Convert all remaining data to a clone-on-write string.
323 ///
324 /// The string will be borrowed where possible, but some readers may
325 /// always return an owned string.
326 ///
327 /// Does not advance the reader.
328 ///
329 /// Returns an error if the data contains invalid characters.
330#[cfg(feature = "read")]
331fn to_string(&self) -> Result<Cow<'_, str>>;
332333/// Convert all remaining data to a clone-on-write string, including invalid characters.
334 ///
335 /// The string will be borrowed where possible, but some readers may
336 /// always return an owned string.
337 ///
338 /// Does not advance the reader.
339#[cfg(feature = "read")]
340fn to_string_lossy(&self) -> Result<Cow<'_, str>>;
341342/// Read exactly `buf.len()` bytes into `buf`.
343fn read_slice(&mut self, buf: &mut [u8]) -> Result<()>;
344345/// Read a u8 array.
346#[inline]
347fn read_u8_array<A>(&mut self) -> Result<A>
348where
349A: Sized + Default + AsMut<[u8]>,
350 {
351let mut val = Default::default();
352self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?;
353Ok(val)
354 }
355356/// Return true if the number of bytes remaining is zero.
357#[inline]
358fn is_empty(&self) -> bool {
359self.len() == Self::Offset::from_u8(0)
360 }
361362/// Read a u8.
363#[inline]
364fn read_u8(&mut self) -> Result<u8> {
365let a: [u8; 1] = self.read_u8_array()?;
366Ok(a[0])
367 }
368369/// Read an i8.
370#[inline]
371fn read_i8(&mut self) -> Result<i8> {
372let a: [u8; 1] = self.read_u8_array()?;
373Ok(a[0] as i8)
374 }
375376/// Read a u16.
377#[inline]
378fn read_u16(&mut self) -> Result<u16> {
379let a: [u8; 2] = self.read_u8_array()?;
380Ok(self.endian().read_u16(&a))
381 }
382383/// Read an i16.
384#[inline]
385fn read_i16(&mut self) -> Result<i16> {
386let a: [u8; 2] = self.read_u8_array()?;
387Ok(self.endian().read_i16(&a))
388 }
389390/// Read a u32.
391#[inline]
392fn read_u32(&mut self) -> Result<u32> {
393let a: [u8; 4] = self.read_u8_array()?;
394Ok(self.endian().read_u32(&a))
395 }
396397/// Read an i32.
398#[inline]
399fn read_i32(&mut self) -> Result<i32> {
400let a: [u8; 4] = self.read_u8_array()?;
401Ok(self.endian().read_i32(&a))
402 }
403404/// Read a u64.
405#[inline]
406fn read_u64(&mut self) -> Result<u64> {
407let a: [u8; 8] = self.read_u8_array()?;
408Ok(self.endian().read_u64(&a))
409 }
410411/// Read an i64.
412#[inline]
413fn read_i64(&mut self) -> Result<i64> {
414let a: [u8; 8] = self.read_u8_array()?;
415Ok(self.endian().read_i64(&a))
416 }
417418/// Read a f32.
419#[inline]
420fn read_f32(&mut self) -> Result<f32> {
421let a: [u8; 4] = self.read_u8_array()?;
422Ok(self.endian().read_f32(&a))
423 }
424425/// Read a f64.
426#[inline]
427fn read_f64(&mut self) -> Result<f64> {
428let a: [u8; 8] = self.read_u8_array()?;
429Ok(self.endian().read_f64(&a))
430 }
431432/// Read an unsigned n-bytes integer u64.
433 ///
434 /// # Panics
435 ///
436 /// Panics when nbytes < 1 or nbytes > 8
437#[inline]
438fn read_uint(&mut self, n: usize) -> Result<u64> {
439let mut buf = [0; 8];
440self.read_slice(&mut buf[..n])?;
441Ok(self.endian().read_uint(&buf[..n]))
442 }
443444/// Read a null-terminated slice, and return it (excluding the null).
445fn read_null_terminated_slice(&mut self) -> Result<Self> {
446let idx = self.find(0)?;
447let val = self.split(idx)?;
448self.skip(Self::Offset::from_u8(1))?;
449Ok(val)
450 }
451452/// Skip a LEB128 encoded integer.
453fn skip_leb128(&mut self) -> Result<()> {
454 leb128::read::skip(self)
455 }
456457/// Read an unsigned LEB128 encoded integer.
458fn read_uleb128(&mut self) -> Result<u64> {
459 leb128::read::unsigned(self)
460 }
461462/// Read an unsigned LEB128 encoded u32.
463fn read_uleb128_u32(&mut self) -> Result<u32> {
464 leb128::read::unsigned(self)?
465.try_into()
466 .map_err(|_| Error::BadUnsignedLeb128)
467 }
468469/// Read an unsigned LEB128 encoded u16.
470fn read_uleb128_u16(&mut self) -> Result<u16> {
471 leb128::read::u16(self)
472 }
473474/// Read a signed LEB128 encoded integer.
475fn read_sleb128(&mut self) -> Result<i64> {
476 leb128::read::signed(self)
477 }
478479/// Read an initial length field.
480 ///
481 /// This field is encoded as either a 32-bit length or
482 /// a 64-bit length, and the returned `Format` indicates which.
483fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> {
484const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0;
485const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff;
486487let val = self.read_u32()?;
488if val < MAX_DWARF_32_UNIT_LENGTH {
489Ok((Self::Offset::from_u32(val), Format::Dwarf32))
490 } else if val == DWARF_64_INITIAL_UNIT_LENGTH {
491let val = self.read_u64().and_then(Self::Offset::from_u64)?;
492Ok((val, Format::Dwarf64))
493 } else {
494Err(Error::UnknownReservedLength)
495 }
496 }
497498/// Read a byte and validate it as an address size.
499fn read_address_size(&mut self) -> Result<u8> {
500let size = self.read_u8()?;
501match size {
5021 | 2 | 4 | 8 => Ok(size),
503_ => Err(Error::UnsupportedAddressSize(size)),
504 }
505 }
506507/// Read an address-sized integer, and return it as a `u64`.
508fn read_address(&mut self, address_size: u8) -> Result<u64> {
509match address_size {
5101 => self.read_u8().map(u64::from),
5112 => self.read_u16().map(u64::from),
5124 => self.read_u32().map(u64::from),
5138 => self.read_u64(),
514 otherwise => Err(Error::UnsupportedAddressSize(otherwise)),
515 }
516 }
517518/// Parse a word-sized integer according to the DWARF format.
519 ///
520 /// These are always used to encode section offsets or lengths,
521 /// and so have a type of `Self::Offset`.
522fn read_word(&mut self, format: Format) -> Result<Self::Offset> {
523match format {
524 Format::Dwarf32 => self.read_u32().map(Self::Offset::from_u32),
525 Format::Dwarf64 => self.read_u64().and_then(Self::Offset::from_u64),
526 }
527 }
528529/// Parse a word-sized section length according to the DWARF format.
530#[inline]
531fn read_length(&mut self, format: Format) -> Result<Self::Offset> {
532self.read_word(format)
533 }
534535/// Parse a word-sized section offset according to the DWARF format.
536#[inline]
537fn read_offset(&mut self, format: Format) -> Result<Self::Offset> {
538self.read_word(format)
539 }
540541/// Parse a section offset of the given size.
542 ///
543 /// This is used for `DW_FORM_ref_addr` values in DWARF version 2.
544fn read_sized_offset(&mut self, size: u8) -> Result<Self::Offset> {
545match size {
5461 => self.read_u8().map(u64::from),
5472 => self.read_u16().map(u64::from),
5484 => self.read_u32().map(u64::from),
5498 => self.read_u64(),
550 otherwise => Err(Error::UnsupportedOffsetSize(otherwise)),
551 }
552 .and_then(Self::Offset::from_u64)
553 }
554}