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