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