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};
7
8use crate::common::Format;
9use crate::endianity::Endianity;
10use crate::leb128;
11use crate::read::{Error, Result};
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct ReaderOffsetId(pub u64);
20
21pub trait ReaderOffset:
25    Debug + Copy + Eq + Ord + Hash + Add<Output = Self> + AddAssign + Sub<Output = Self>
26{
27    fn from_u8(offset: u8) -> Self;
29
30    fn from_u16(offset: u16) -> Self;
32
33    fn from_i16(offset: i16) -> Self;
35
36    fn from_u32(offset: u32) -> Self;
38
39    fn from_u64(offset: u64) -> Result<Self>;
43
44    fn into_u64(self) -> u64;
46
47    fn wrapping_add(self, other: Self) -> Self;
49
50    fn checked_sub(self, other: Self) -> Option<Self>;
52}
53
54impl ReaderOffset for u64 {
55    #[inline]
56    fn from_u8(offset: u8) -> Self {
57        u64::from(offset)
58    }
59
60    #[inline]
61    fn from_u16(offset: u16) -> Self {
62        u64::from(offset)
63    }
64
65    #[inline]
66    fn from_i16(offset: i16) -> Self {
67        offset as u64
68    }
69
70    #[inline]
71    fn from_u32(offset: u32) -> Self {
72        u64::from(offset)
73    }
74
75    #[inline]
76    fn from_u64(offset: u64) -> Result<Self> {
77        Ok(offset)
78    }
79
80    #[inline]
81    fn into_u64(self) -> u64 {
82        self
83    }
84
85    #[inline]
86    fn wrapping_add(self, other: Self) -> Self {
87        self.wrapping_add(other)
88    }
89
90    #[inline]
91    fn checked_sub(self, other: Self) -> Option<Self> {
92        self.checked_sub(other)
93    }
94}
95
96impl ReaderOffset for u32 {
97    #[inline]
98    fn from_u8(offset: u8) -> Self {
99        u32::from(offset)
100    }
101
102    #[inline]
103    fn from_u16(offset: u16) -> Self {
104        u32::from(offset)
105    }
106
107    #[inline]
108    fn from_i16(offset: i16) -> Self {
109        offset as u32
110    }
111
112    #[inline]
113    fn from_u32(offset: u32) -> Self {
114        offset
115    }
116
117    #[inline]
118    fn from_u64(offset64: u64) -> Result<Self> {
119        let offset = offset64 as u32;
120        if u64::from(offset) == offset64 {
121            Ok(offset)
122        } else {
123            Err(Error::UnsupportedOffset)
124        }
125    }
126
127    #[inline]
128    fn into_u64(self) -> u64 {
129        u64::from(self)
130    }
131
132    #[inline]
133    fn wrapping_add(self, other: Self) -> Self {
134        self.wrapping_add(other)
135    }
136
137    #[inline]
138    fn checked_sub(self, other: Self) -> Option<Self> {
139        self.checked_sub(other)
140    }
141}
142
143impl ReaderOffset for usize {
144    #[inline]
145    fn from_u8(offset: u8) -> Self {
146        offset as usize
147    }
148
149    #[inline]
150    fn from_u16(offset: u16) -> Self {
151        offset as usize
152    }
153
154    #[inline]
155    fn from_i16(offset: i16) -> Self {
156        offset as usize
157    }
158
159    #[inline]
160    fn from_u32(offset: u32) -> Self {
161        offset as usize
162    }
163
164    #[inline]
165    fn from_u64(offset64: u64) -> Result<Self> {
166        let offset = offset64 as usize;
167        if offset as u64 == offset64 {
168            Ok(offset)
169        } else {
170            Err(Error::UnsupportedOffset)
171        }
172    }
173
174    #[inline]
175    fn into_u64(self) -> u64 {
176        self as u64
177    }
178
179    #[inline]
180    fn wrapping_add(self, other: Self) -> Self {
181        self.wrapping_add(other)
182    }
183
184    #[inline]
185    fn checked_sub(self, other: Self) -> Option<Self> {
186        self.checked_sub(other)
187    }
188}
189
190pub(crate) trait ReaderAddress: Sized {
195    fn add_sized(self, length: u64, size: u8) -> Result<Self>;
199
200    fn wrapping_add_sized(self, length: u64, size: u8) -> Self;
205
206    fn ones_sized(size: u8) -> Self;
208}
209
210impl ReaderAddress for u64 {
211    #[inline]
212    fn add_sized(self, length: u64, size: u8) -> Result<Self> {
213        let address = self.checked_add(length).ok_or(Error::AddressOverflow)?;
214        let mask = Self::ones_sized(size);
215        if address & !mask != 0 {
216            return Err(Error::AddressOverflow);
217        }
218        Ok(address)
219    }
220
221    #[inline]
222    fn wrapping_add_sized(self, length: u64, size: u8) -> Self {
223        let mask = Self::ones_sized(size);
224        self.wrapping_add(length) & mask
225    }
226
227    #[inline]
228    fn ones_sized(size: u8) -> Self {
229        !0 >> (64 - size * 8)
230    }
231}
232
233#[cfg(not(feature = "read"))]
234pub(crate) mod seal_if_no_alloc {
235    #[derive(Debug)]
236    pub struct Sealed;
237}
238
239pub trait Reader: Debug + Clone {
259    type Endian: Endianity;
261
262    type Offset: ReaderOffset;
264
265    fn endian(&self) -> Self::Endian;
267
268    fn len(&self) -> Self::Offset;
270
271    fn empty(&mut self);
273
274    fn truncate(&mut self, len: Self::Offset) -> Result<()>;
276
277    fn offset_from(&self, base: &Self) -> Self::Offset;
283
284    fn offset_id(&self) -> ReaderOffsetId;
286
287    fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>;
290
291    fn find(&self, byte: u8) -> Result<Self::Offset>;
294
295    fn skip(&mut self, len: Self::Offset) -> Result<()>;
297
298    fn split(&mut self, len: Self::Offset) -> Result<Self>;
303
304    #[cfg(not(feature = "read"))]
311    fn cannot_implement() -> seal_if_no_alloc::Sealed;
312
313    #[cfg(feature = "read")]
320    fn to_slice(&self) -> Result<Cow<'_, [u8]>>;
321
322    #[cfg(feature = "read")]
331    fn to_string(&self) -> Result<Cow<'_, str>>;
332
333    #[cfg(feature = "read")]
340    fn to_string_lossy(&self) -> Result<Cow<'_, str>>;
341
342    fn read_slice(&mut self, buf: &mut [u8]) -> Result<()>;
344
345    #[inline]
347    fn read_u8_array<A>(&mut self) -> Result<A>
348    where
349        A: Sized + Default + AsMut<[u8]>,
350    {
351        let mut val = Default::default();
352        self.read_slice(<A as AsMut<[u8]>>::as_mut(&mut val))?;
353        Ok(val)
354    }
355
356    #[inline]
358    fn is_empty(&self) -> bool {
359        self.len() == Self::Offset::from_u8(0)
360    }
361
362    #[inline]
364    fn read_u8(&mut self) -> Result<u8> {
365        let a: [u8; 1] = self.read_u8_array()?;
366        Ok(a[0])
367    }
368
369    #[inline]
371    fn read_i8(&mut self) -> Result<i8> {
372        let a: [u8; 1] = self.read_u8_array()?;
373        Ok(a[0] as i8)
374    }
375
376    #[inline]
378    fn read_u16(&mut self) -> Result<u16> {
379        let a: [u8; 2] = self.read_u8_array()?;
380        Ok(self.endian().read_u16(&a))
381    }
382
383    #[inline]
385    fn read_i16(&mut self) -> Result<i16> {
386        let a: [u8; 2] = self.read_u8_array()?;
387        Ok(self.endian().read_i16(&a))
388    }
389
390    #[inline]
392    fn read_u32(&mut self) -> Result<u32> {
393        let a: [u8; 4] = self.read_u8_array()?;
394        Ok(self.endian().read_u32(&a))
395    }
396
397    #[inline]
399    fn read_i32(&mut self) -> Result<i32> {
400        let a: [u8; 4] = self.read_u8_array()?;
401        Ok(self.endian().read_i32(&a))
402    }
403
404    #[inline]
406    fn read_u64(&mut self) -> Result<u64> {
407        let a: [u8; 8] = self.read_u8_array()?;
408        Ok(self.endian().read_u64(&a))
409    }
410
411    #[inline]
413    fn read_i64(&mut self) -> Result<i64> {
414        let a: [u8; 8] = self.read_u8_array()?;
415        Ok(self.endian().read_i64(&a))
416    }
417
418    #[inline]
420    fn read_f32(&mut self) -> Result<f32> {
421        let a: [u8; 4] = self.read_u8_array()?;
422        Ok(self.endian().read_f32(&a))
423    }
424
425    #[inline]
427    fn read_f64(&mut self) -> Result<f64> {
428        let a: [u8; 8] = self.read_u8_array()?;
429        Ok(self.endian().read_f64(&a))
430    }
431
432    #[inline]
438    fn read_uint(&mut self, n: usize) -> Result<u64> {
439        let mut buf = [0; 8];
440        self.read_slice(&mut buf[..n])?;
441        Ok(self.endian().read_uint(&buf[..n]))
442    }
443
444    fn read_null_terminated_slice(&mut self) -> Result<Self> {
446        let idx = self.find(0)?;
447        let val = self.split(idx)?;
448        self.skip(Self::Offset::from_u8(1))?;
449        Ok(val)
450    }
451
452    fn skip_leb128(&mut self) -> Result<()> {
454        leb128::read::skip(self)
455    }
456
457    fn read_uleb128(&mut self) -> Result<u64> {
459        leb128::read::unsigned(self)
460    }
461
462    fn read_uleb128_u32(&mut self) -> Result<u32> {
464        leb128::read::unsigned(self)?
465            .try_into()
466            .map_err(|_| Error::BadUnsignedLeb128)
467    }
468
469    fn read_uleb128_u16(&mut self) -> Result<u16> {
471        leb128::read::u16(self)
472    }
473
474    fn read_sleb128(&mut self) -> Result<i64> {
476        leb128::read::signed(self)
477    }
478
479    fn read_initial_length(&mut self) -> Result<(Self::Offset, Format)> {
484        const MAX_DWARF_32_UNIT_LENGTH: u32 = 0xffff_fff0;
485        const DWARF_64_INITIAL_UNIT_LENGTH: u32 = 0xffff_ffff;
486
487        let val = self.read_u32()?;
488        if val < MAX_DWARF_32_UNIT_LENGTH {
489            Ok((Self::Offset::from_u32(val), Format::Dwarf32))
490        } else if val == DWARF_64_INITIAL_UNIT_LENGTH {
491            let val = self.read_u64().and_then(Self::Offset::from_u64)?;
492            Ok((val, Format::Dwarf64))
493        } else {
494            Err(Error::UnknownReservedLength)
495        }
496    }
497
498    fn read_address_size(&mut self) -> Result<u8> {
500        let size = self.read_u8()?;
501        match size {
502            1 | 2 | 4 | 8 => Ok(size),
503            _ => Err(Error::UnsupportedAddressSize(size)),
504        }
505    }
506
507    fn read_address(&mut self, address_size: u8) -> Result<u64> {
509        match address_size {
510            1 => self.read_u8().map(u64::from),
511            2 => self.read_u16().map(u64::from),
512            4 => self.read_u32().map(u64::from),
513            8 => self.read_u64(),
514            otherwise => Err(Error::UnsupportedAddressSize(otherwise)),
515        }
516    }
517
518    fn read_word(&mut self, format: Format) -> Result<Self::Offset> {
523        match 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    }
528
529    #[inline]
531    fn read_length(&mut self, format: Format) -> Result<Self::Offset> {
532        self.read_word(format)
533    }
534
535    #[inline]
537    fn read_offset(&mut self, format: Format) -> Result<Self::Offset> {
538        self.read_word(format)
539    }
540
541    fn read_sized_offset(&mut self, size: u8) -> Result<Self::Offset> {
545        match size {
546            1 => self.read_u8().map(u64::from),
547            2 => self.read_u16().map(u64::from),
548            4 => self.read_u32().map(u64::from),
549            8 => self.read_u64(),
550            otherwise => Err(Error::UnsupportedOffsetSize(otherwise)),
551        }
552        .and_then(Self::Offset::from_u64)
553    }
554}