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}