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.
from_u8(offset: u8) -> Self27     fn from_u8(offset: u8) -> Self;
28 
29     /// Convert a u16 to an offset.
from_u16(offset: u16) -> Self30     fn from_u16(offset: u16) -> Self;
31 
32     /// Convert an i16 to an offset.
from_i16(offset: i16) -> Self33     fn from_i16(offset: i16) -> Self;
34 
35     /// Convert a u32 to an offset.
from_u32(offset: u32) -> Self36     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.
from_u64(offset: u64) -> Result<Self>41     fn from_u64(offset: u64) -> Result<Self>;
42 
43     /// Convert an offset to a u64.
into_u64(self) -> u6444     fn into_u64(self) -> u64;
45 
46     /// Wrapping (modular) addition. Computes `self + other`.
wrapping_add(self, other: Self) -> Self47     fn wrapping_add(self, other: Self) -> Self;
48 
49     /// Checked subtraction. Computes `self - other`.
checked_sub(self, other: Self) -> Option<Self>50     fn checked_sub(self, other: Self) -> Option<Self>;
51 }
52 
53 impl ReaderOffset for u64 {
54     #[inline]
from_u8(offset: u8) -> Self55     fn from_u8(offset: u8) -> Self {
56         u64::from(offset)
57     }
58 
59     #[inline]
from_u16(offset: u16) -> Self60     fn from_u16(offset: u16) -> Self {
61         u64::from(offset)
62     }
63 
64     #[inline]
from_i16(offset: i16) -> Self65     fn from_i16(offset: i16) -> Self {
66         offset as u64
67     }
68 
69     #[inline]
from_u32(offset: u32) -> Self70     fn from_u32(offset: u32) -> Self {
71         u64::from(offset)
72     }
73 
74     #[inline]
from_u64(offset: u64) -> Result<Self>75     fn from_u64(offset: u64) -> Result<Self> {
76         Ok(offset)
77     }
78 
79     #[inline]
into_u64(self) -> u6480     fn into_u64(self) -> u64 {
81         self
82     }
83 
84     #[inline]
wrapping_add(self, other: Self) -> Self85     fn wrapping_add(self, other: Self) -> Self {
86         self.wrapping_add(other)
87     }
88 
89     #[inline]
checked_sub(self, other: Self) -> Option<Self>90     fn checked_sub(self, other: Self) -> Option<Self> {
91         self.checked_sub(other)
92     }
93 }
94 
95 impl ReaderOffset for u32 {
96     #[inline]
from_u8(offset: u8) -> Self97     fn from_u8(offset: u8) -> Self {
98         u32::from(offset)
99     }
100 
101     #[inline]
from_u16(offset: u16) -> Self102     fn from_u16(offset: u16) -> Self {
103         u32::from(offset)
104     }
105 
106     #[inline]
from_i16(offset: i16) -> Self107     fn from_i16(offset: i16) -> Self {
108         offset as u32
109     }
110 
111     #[inline]
from_u32(offset: u32) -> Self112     fn from_u32(offset: u32) -> Self {
113         offset
114     }
115 
116     #[inline]
from_u64(offset64: u64) -> Result<Self>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]
into_u64(self) -> u64127     fn into_u64(self) -> u64 {
128         u64::from(self)
129     }
130 
131     #[inline]
wrapping_add(self, other: Self) -> Self132     fn wrapping_add(self, other: Self) -> Self {
133         self.wrapping_add(other)
134     }
135 
136     #[inline]
checked_sub(self, other: Self) -> Option<Self>137     fn checked_sub(self, other: Self) -> Option<Self> {
138         self.checked_sub(other)
139     }
140 }
141 
142 impl ReaderOffset for usize {
143     #[inline]
from_u8(offset: u8) -> Self144     fn from_u8(offset: u8) -> Self {
145         offset as usize
146     }
147 
148     #[inline]
from_u16(offset: u16) -> Self149     fn from_u16(offset: u16) -> Self {
150         offset as usize
151     }
152 
153     #[inline]
from_i16(offset: i16) -> Self154     fn from_i16(offset: i16) -> Self {
155         offset as usize
156     }
157 
158     #[inline]
from_u32(offset: u32) -> Self159     fn from_u32(offset: u32) -> Self {
160         offset as usize
161     }
162 
163     #[inline]
from_u64(offset64: u64) -> Result<Self>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]
into_u64(self) -> u64174     fn into_u64(self) -> u64 {
175         self as u64
176     }
177 
178     #[inline]
wrapping_add(self, other: Self) -> Self179     fn wrapping_add(self, other: Self) -> Self {
180         self.wrapping_add(other)
181     }
182 
183     #[inline]
checked_sub(self, other: Self) -> Option<Self>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.
endian(&self) -> Self::Endian216     fn endian(&self) -> Self::Endian;
217 
218     /// Return the number of bytes remaining.
len(&self) -> Self::Offset219     fn len(&self) -> Self::Offset;
220 
221     /// Set the number of bytes remaining to zero.
empty(&mut self)222     fn empty(&mut self);
223 
224     /// Set the number of bytes remaining to the specified length.
truncate(&mut self, len: Self::Offset) -> Result<()>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.
offset_from(&self, base: &Self) -> Self::Offset232     fn offset_from(&self, base: &Self) -> Self::Offset;
233 
234     /// Return an identifier for the current reader offset.
offset_id(&self) -> ReaderOffsetId235     fn offset_id(&self) -> ReaderOffsetId;
236 
237     /// Return the offset corresponding to the given `id` if
238     /// it is associated with this reader.
lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>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.
find(&self, byte: u8) -> Result<Self::Offset>243     fn find(&self, byte: u8) -> Result<Self::Offset>;
244 
245     /// Discard the specified number of bytes.
skip(&mut self, len: Self::Offset) -> Result<()>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.
split(&mut self, len: Self::Offset) -> Result<Self>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.
to_slice(&self) -> Result<Cow<[u8]>>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.
to_string(&self) -> Result<Cow<str>>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.
to_string_lossy(&self) -> Result<Cow<str>>278     fn to_string_lossy(&self) -> Result<Cow<str>>;
279 
280     /// Read exactly `buf.len()` bytes into `buf`.
read_slice(&mut self, buf: &mut [u8]) -> Result<()>281     fn read_slice(&mut self, buf: &mut [u8]) -> Result<()>;
282 
283     /// Read a u8 array.
284     #[inline]
read_u8_array<A>(&mut self) -> Result<A> where A: Sized + Default + AsMut<[u8]>,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]
is_empty(&self) -> bool296     fn is_empty(&self) -> bool {
297         self.len() == Self::Offset::from_u8(0)
298     }
299 
300     /// Read a u8.
301     #[inline]
read_u8(&mut self) -> Result<u8>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]
read_i8(&mut self) -> Result<i8>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]
read_u16(&mut self) -> Result<u16>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]
read_i16(&mut self) -> Result<i16>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]
read_u32(&mut self) -> Result<u32>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]
read_i32(&mut self) -> Result<i32>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]
read_u64(&mut self) -> Result<u64>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]
read_i64(&mut self) -> Result<i64>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]
read_f32(&mut self) -> Result<f32>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]
read_f64(&mut self) -> Result<f64>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]
read_uint(&mut self, n: usize) -> Result<u64>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).
read_null_terminated_slice(&mut self) -> Result<Self>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.
read_uleb128(&mut self) -> Result<u64>391     fn read_uleb128(&mut self) -> Result<u64> {
392         leb128::read::unsigned(self)
393     }
394 
395     /// Read an unsigned LEB128 encoded u32.
read_uleb128_u32(&mut self) -> Result<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.
read_uleb128_u16(&mut self) -> Result<u16>403     fn read_uleb128_u16(&mut self) -> Result<u16> {
404         leb128::read::u16(self)
405     }
406 
407     /// Read a signed LEB128 encoded integer.
read_sleb128(&mut self) -> Result<i64>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.
read_initial_length(&mut self) -> Result<(Self::Offset, Format)>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`.
read_address(&mut self, address_size: u8) -> Result<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`.
read_word(&mut self, format: Format) -> Result<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]
read_length(&mut self, format: Format) -> Result<Self::Offset>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]
read_offset(&mut self, format: Format) -> Result<Self::Offset>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.
read_sized_offset(&mut self, size: u8) -> Result<Self::Offset>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 }
479