1 use crate::common::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId}; 2 use crate::endianity::Endianity; 3 use crate::read::{EndianSlice, Error, Range, Reader, ReaderOffset, Result, Section}; 4 5 /// The `DebugAranges` struct represents the DWARF address range information 6 /// found in the `.debug_aranges` section. 7 #[derive(Debug, Default, Clone, Copy)] 8 pub struct DebugAranges<R> { 9 section: R, 10 } 11 12 impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>> 13 where 14 Endian: Endianity, 15 { 16 /// Construct a new `DebugAranges` instance from the data in the `.debug_aranges` 17 /// section. 18 /// 19 /// It is the caller's responsibility to read the `.debug_aranges` section and 20 /// present it as a `&[u8]` slice. That means using some ELF loader on 21 /// Linux, a Mach-O loader on OSX, etc. 22 /// 23 /// ``` 24 /// use gimli::{DebugAranges, LittleEndian}; 25 /// 26 /// # let buf = []; 27 /// # let read_debug_aranges_section = || &buf; 28 /// let debug_aranges = 29 /// DebugAranges::new(read_debug_aranges_section(), LittleEndian); 30 /// ``` new(section: &'input [u8], endian: Endian) -> Self31 pub fn new(section: &'input [u8], endian: Endian) -> Self { 32 DebugAranges { 33 section: EndianSlice::new(section, endian), 34 } 35 } 36 } 37 38 impl<R: Reader> DebugAranges<R> { 39 /// Iterate the sets of entries in the `.debug_aranges` section. 40 /// 41 /// Each set of entries belongs to a single unit. headers(&self) -> ArangeHeaderIter<R>42 pub fn headers(&self) -> ArangeHeaderIter<R> { 43 ArangeHeaderIter { 44 input: self.section.clone(), 45 offset: DebugArangesOffset(R::Offset::from_u8(0)), 46 } 47 } 48 49 /// Get the header at the given offset. header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>>50 pub fn header(&self, offset: DebugArangesOffset<R::Offset>) -> Result<ArangeHeader<R>> { 51 let mut input = self.section.clone(); 52 input.skip(offset.0)?; 53 ArangeHeader::parse(&mut input, offset) 54 } 55 } 56 57 impl<T> DebugAranges<T> { 58 /// Create a `DebugAranges` section that references the data in `self`. 59 /// 60 /// This is useful when `R` implements `Reader` but `T` does not. 61 /// 62 /// ## Example Usage 63 /// 64 /// ```rust,no_run 65 /// # let load_section = || unimplemented!(); 66 /// // Read the DWARF section into a `Vec` with whatever object loader you're using. 67 /// let owned_section: gimli::DebugAranges<Vec<u8>> = load_section(); 68 /// // Create a reference to the DWARF section. 69 /// let section = owned_section.borrow(|section| { 70 /// gimli::EndianSlice::new(§ion, gimli::LittleEndian) 71 /// }); 72 /// ``` borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R> where F: FnMut(&'a T) -> R,73 pub fn borrow<'a, F, R>(&'a self, mut borrow: F) -> DebugAranges<R> 74 where 75 F: FnMut(&'a T) -> R, 76 { 77 borrow(&self.section).into() 78 } 79 } 80 81 impl<R> Section<R> for DebugAranges<R> { id() -> SectionId82 fn id() -> SectionId { 83 SectionId::DebugAranges 84 } 85 reader(&self) -> &R86 fn reader(&self) -> &R { 87 &self.section 88 } 89 } 90 91 impl<R> From<R> for DebugAranges<R> { from(section: R) -> Self92 fn from(section: R) -> Self { 93 DebugAranges { section } 94 } 95 } 96 97 /// An iterator over the headers of a `.debug_aranges` section. 98 #[derive(Clone, Debug)] 99 pub struct ArangeHeaderIter<R: Reader> { 100 input: R, 101 offset: DebugArangesOffset<R::Offset>, 102 } 103 104 impl<R: Reader> ArangeHeaderIter<R> { 105 /// Advance the iterator to the next header. next(&mut self) -> Result<Option<ArangeHeader<R>>>106 pub fn next(&mut self) -> Result<Option<ArangeHeader<R>>> { 107 if self.input.is_empty() { 108 return Ok(None); 109 } 110 111 let len = self.input.len(); 112 match ArangeHeader::parse(&mut self.input, self.offset) { 113 Ok(header) => { 114 self.offset.0 += len - self.input.len(); 115 Ok(Some(header)) 116 } 117 Err(e) => { 118 self.input.empty(); 119 Err(e) 120 } 121 } 122 } 123 } 124 125 #[cfg(feature = "fallible-iterator")] 126 impl<R: Reader> fallible_iterator::FallibleIterator for ArangeHeaderIter<R> { 127 type Item = ArangeHeader<R>; 128 type Error = Error; 129 next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>130 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> { 131 ArangeHeaderIter::next(self) 132 } 133 } 134 135 /// A header for a set of entries in the `.debug_arange` section. 136 /// 137 /// These entries all belong to a single unit. 138 #[derive(Debug, Clone, PartialEq, Eq)] 139 pub struct ArangeHeader<R, Offset = <R as Reader>::Offset> 140 where 141 R: Reader<Offset = Offset>, 142 Offset: ReaderOffset, 143 { 144 offset: DebugArangesOffset<Offset>, 145 encoding: Encoding, 146 length: Offset, 147 debug_info_offset: DebugInfoOffset<Offset>, 148 segment_size: u8, 149 entries: R, 150 } 151 152 impl<R, Offset> ArangeHeader<R, Offset> 153 where 154 R: Reader<Offset = Offset>, 155 Offset: ReaderOffset, 156 { parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self>157 fn parse(input: &mut R, offset: DebugArangesOffset<Offset>) -> Result<Self> { 158 let (length, format) = input.read_initial_length()?; 159 let mut rest = input.split(length)?; 160 161 let version = rest.read_u16()?; 162 if version != 2 { 163 return Err(Error::UnknownVersion(u64::from(version))); 164 } 165 166 let debug_info_offset = rest.read_offset(format).map(DebugInfoOffset)?; 167 let address_size = rest.read_u8()?; 168 let segment_size = rest.read_u8()?; 169 170 // unit_length + version + offset + address_size + segment_size 171 let header_length = format.initial_length_size() + 2 + format.word_size() + 1 + 1; 172 173 // The first tuple following the header in each set begins at an offset that is 174 // a multiple of the size of a single tuple (that is, the size of a segment selector 175 // plus twice the size of an address). 176 let tuple_length = address_size 177 .checked_mul(2) 178 .and_then(|x| x.checked_add(segment_size)) 179 .ok_or(Error::InvalidAddressRange)?; 180 if tuple_length == 0 { 181 return Err(Error::InvalidAddressRange)?; 182 } 183 let padding = if header_length % tuple_length == 0 { 184 0 185 } else { 186 tuple_length - header_length % tuple_length 187 }; 188 rest.skip(R::Offset::from_u8(padding))?; 189 190 let encoding = Encoding { 191 format, 192 version, 193 address_size, 194 // TODO: segment_size 195 }; 196 Ok(ArangeHeader { 197 offset, 198 encoding, 199 length, 200 debug_info_offset, 201 segment_size, 202 entries: rest, 203 }) 204 } 205 206 /// Return the offset of this header within the `.debug_aranges` section. 207 #[inline] offset(&self) -> DebugArangesOffset<Offset>208 pub fn offset(&self) -> DebugArangesOffset<Offset> { 209 self.offset 210 } 211 212 /// Return the length of this set of entries, including the header. 213 #[inline] length(&self) -> Offset214 pub fn length(&self) -> Offset { 215 self.length 216 } 217 218 /// Return the encoding parameters for this set of entries. 219 #[inline] encoding(&self) -> Encoding220 pub fn encoding(&self) -> Encoding { 221 self.encoding 222 } 223 224 /// Return the segment size for this set of entries. 225 #[inline] segment_size(&self) -> u8226 pub fn segment_size(&self) -> u8 { 227 self.segment_size 228 } 229 230 /// Return the offset into the .debug_info section for this set of arange entries. 231 #[inline] debug_info_offset(&self) -> DebugInfoOffset<Offset>232 pub fn debug_info_offset(&self) -> DebugInfoOffset<Offset> { 233 self.debug_info_offset 234 } 235 236 /// Return the arange entries in this set. 237 #[inline] entries(&self) -> ArangeEntryIter<R>238 pub fn entries(&self) -> ArangeEntryIter<R> { 239 ArangeEntryIter { 240 input: self.entries.clone(), 241 encoding: self.encoding, 242 segment_size: self.segment_size, 243 } 244 } 245 } 246 247 /// An iterator over the aranges from a `.debug_aranges` section. 248 /// 249 /// Can be [used with 250 /// `FallibleIterator`](./index.html#using-with-fallibleiterator). 251 #[derive(Debug, Clone)] 252 pub struct ArangeEntryIter<R: Reader> { 253 input: R, 254 encoding: Encoding, 255 segment_size: u8, 256 } 257 258 impl<R: Reader> ArangeEntryIter<R> { 259 /// Advance the iterator and return the next arange. 260 /// 261 /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)` 262 /// when iteration is complete and all aranges have already been parsed and 263 /// yielded. If an error occurs while parsing the next arange, then this error 264 /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`. next(&mut self) -> Result<Option<ArangeEntry>>265 pub fn next(&mut self) -> Result<Option<ArangeEntry>> { 266 if self.input.is_empty() { 267 return Ok(None); 268 } 269 270 match ArangeEntry::parse(&mut self.input, self.encoding, self.segment_size) { 271 Ok(Some(entry)) => Ok(Some(entry)), 272 Ok(None) => { 273 self.input.empty(); 274 Ok(None) 275 } 276 Err(e) => { 277 self.input.empty(); 278 Err(e) 279 } 280 } 281 } 282 } 283 284 #[cfg(feature = "fallible-iterator")] 285 impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> { 286 type Item = ArangeEntry; 287 type Error = Error; 288 next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error>289 fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> { 290 ArangeEntryIter::next(self) 291 } 292 } 293 294 /// A single parsed arange. 295 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] 296 pub struct ArangeEntry { 297 segment: Option<u64>, 298 address: u64, 299 length: u64, 300 } 301 302 impl ArangeEntry { 303 /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange. parse<R: Reader>( input: &mut R, encoding: Encoding, segment_size: u8, ) -> Result<Option<Self>>304 fn parse<R: Reader>( 305 input: &mut R, 306 encoding: Encoding, 307 segment_size: u8, 308 ) -> Result<Option<Self>> { 309 let address_size = encoding.address_size; 310 311 let tuple_length = R::Offset::from_u8(2 * address_size + segment_size); 312 if tuple_length > input.len() { 313 input.empty(); 314 return Ok(None); 315 } 316 317 let segment = if segment_size != 0 { 318 input.read_address(segment_size)? 319 } else { 320 0 321 }; 322 let address = input.read_address(address_size)?; 323 let length = input.read_address(address_size)?; 324 325 match (segment, address, length) { 326 // This is meant to be a null terminator, but in practice it can occur 327 // before the end, possibly due to a linker omitting a function and 328 // leaving an unrelocated entry. 329 (0, 0, 0) => Self::parse(input, encoding, segment_size), 330 _ => Ok(Some(ArangeEntry { 331 segment: if segment_size != 0 { 332 Some(segment) 333 } else { 334 None 335 }, 336 address, 337 length, 338 })), 339 } 340 } 341 342 /// Return the segment selector of this arange. 343 #[inline] segment(&self) -> Option<u64>344 pub fn segment(&self) -> Option<u64> { 345 self.segment 346 } 347 348 /// Return the beginning address of this arange. 349 #[inline] address(&self) -> u64350 pub fn address(&self) -> u64 { 351 self.address 352 } 353 354 /// Return the length of this arange. 355 #[inline] length(&self) -> u64356 pub fn length(&self) -> u64 { 357 self.length 358 } 359 360 /// Return the range. 361 #[inline] range(&self) -> Range362 pub fn range(&self) -> Range { 363 Range { 364 begin: self.address, 365 end: self.address.wrapping_add(self.length), 366 } 367 } 368 } 369 370 #[cfg(test)] 371 mod tests { 372 use super::*; 373 use crate::common::{DebugInfoOffset, Format}; 374 use crate::endianity::LittleEndian; 375 use crate::read::EndianSlice; 376 377 #[test] test_iterate_headers()378 fn test_iterate_headers() { 379 #[rustfmt::skip] 380 let buf = [ 381 // 32-bit length = 28. 382 0x1c, 0x00, 0x00, 0x00, 383 // Version. 384 0x02, 0x00, 385 // Offset. 386 0x01, 0x02, 0x03, 0x04, 387 // Address size. 388 0x04, 389 // Segment size. 390 0x00, 391 // Dummy padding and arange tuples. 392 0x00, 0x00, 0x00, 0x00, 393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 395 396 // 32-bit length = 36. 397 0x24, 0x00, 0x00, 0x00, 398 // Version. 399 0x02, 0x00, 400 // Offset. 401 0x11, 0x12, 0x13, 0x14, 402 // Address size. 403 0x04, 404 // Segment size. 405 0x00, 406 // Dummy padding and arange tuples. 407 0x00, 0x00, 0x00, 0x00, 408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 411 ]; 412 413 let debug_aranges = DebugAranges::new(&buf, LittleEndian); 414 let mut headers = debug_aranges.headers(); 415 416 let header = headers 417 .next() 418 .expect("should parse header ok") 419 .expect("should have a header"); 420 assert_eq!(header.offset(), DebugArangesOffset(0)); 421 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x0403_0201)); 422 423 let header = headers 424 .next() 425 .expect("should parse header ok") 426 .expect("should have a header"); 427 assert_eq!(header.offset(), DebugArangesOffset(0x20)); 428 assert_eq!(header.debug_info_offset(), DebugInfoOffset(0x1413_1211)); 429 } 430 431 #[test] test_parse_header_ok()432 fn test_parse_header_ok() { 433 #[rustfmt::skip] 434 let buf = [ 435 // 32-bit length = 32. 436 0x20, 0x00, 0x00, 0x00, 437 // Version. 438 0x02, 0x00, 439 // Offset. 440 0x01, 0x02, 0x03, 0x04, 441 // Address size. 442 0x08, 443 // Segment size. 444 0x04, 445 // Length to here = 12, tuple length = 20. 446 // Padding to tuple length multiple = 4. 447 0x10, 0x00, 0x00, 0x00, 448 0x00, 0x00, 0x00, 0x00, 449 450 // Dummy arange tuple data. 451 0x20, 0x00, 0x00, 0x00, 452 0x00, 0x00, 0x00, 0x00, 453 0x00, 0x00, 0x00, 0x00, 454 0x00, 0x00, 0x00, 0x00, 455 456 // Dummy next arange. 457 0x30, 0x00, 0x00, 0x00, 458 0x00, 0x00, 0x00, 0x00, 459 0x00, 0x00, 0x00, 0x00, 460 0x00, 0x00, 0x00, 0x00, 461 ]; 462 463 let rest = &mut EndianSlice::new(&buf, LittleEndian); 464 465 let header = 466 ArangeHeader::parse(rest, DebugArangesOffset(0x10)).expect("should parse header ok"); 467 468 assert_eq!( 469 *rest, 470 EndianSlice::new(&buf[buf.len() - 16..], LittleEndian) 471 ); 472 assert_eq!( 473 header, 474 ArangeHeader { 475 offset: DebugArangesOffset(0x10), 476 encoding: Encoding { 477 format: Format::Dwarf32, 478 version: 2, 479 address_size: 8, 480 }, 481 length: 0x20, 482 debug_info_offset: DebugInfoOffset(0x0403_0201), 483 segment_size: 4, 484 entries: EndianSlice::new(&buf[buf.len() - 32..buf.len() - 16], LittleEndian), 485 } 486 ); 487 } 488 489 #[test] test_parse_header_overflow_error()490 fn test_parse_header_overflow_error() { 491 #[rustfmt::skip] 492 let buf = [ 493 // 32-bit length = 32. 494 0x20, 0x00, 0x00, 0x00, 495 // Version. 496 0x02, 0x00, 497 // Offset. 498 0x01, 0x02, 0x03, 0x04, 499 // Address size. 500 0xff, 501 // Segment size. 502 0xff, 503 // Length to here = 12, tuple length = 20. 504 // Padding to tuple length multiple = 4. 505 0x10, 0x00, 0x00, 0x00, 506 0x00, 0x00, 0x00, 0x00, 507 508 // Dummy arange tuple data. 509 0x20, 0x00, 0x00, 0x00, 510 0x00, 0x00, 0x00, 0x00, 511 0x00, 0x00, 0x00, 0x00, 512 0x00, 0x00, 0x00, 0x00, 513 514 // Dummy next arange. 515 0x30, 0x00, 0x00, 0x00, 516 0x00, 0x00, 0x00, 0x00, 517 0x00, 0x00, 0x00, 0x00, 518 0x00, 0x00, 0x00, 0x00, 519 ]; 520 521 let rest = &mut EndianSlice::new(&buf, LittleEndian); 522 523 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10)) 524 .expect_err("should fail to parse header"); 525 assert_eq!(error, Error::InvalidAddressRange); 526 } 527 528 #[test] test_parse_header_div_by_zero_error()529 fn test_parse_header_div_by_zero_error() { 530 #[rustfmt::skip] 531 let buf = [ 532 // 32-bit length = 32. 533 0x20, 0x00, 0x00, 0x00, 534 // Version. 535 0x02, 0x00, 536 // Offset. 537 0x01, 0x02, 0x03, 0x04, 538 // Address size = 0. Could cause a division by zero if we aren't 539 // careful. 540 0x00, 541 // Segment size. 542 0x00, 543 // Length to here = 12, tuple length = 20. 544 // Padding to tuple length multiple = 4. 545 0x10, 0x00, 0x00, 0x00, 546 0x00, 0x00, 0x00, 0x00, 547 548 // Dummy arange tuple data. 549 0x20, 0x00, 0x00, 0x00, 550 0x00, 0x00, 0x00, 0x00, 551 0x00, 0x00, 0x00, 0x00, 552 0x00, 0x00, 0x00, 0x00, 553 554 // Dummy next arange. 555 0x30, 0x00, 0x00, 0x00, 556 0x00, 0x00, 0x00, 0x00, 557 0x00, 0x00, 0x00, 0x00, 558 0x00, 0x00, 0x00, 0x00, 559 ]; 560 561 let rest = &mut EndianSlice::new(&buf, LittleEndian); 562 563 let error = ArangeHeader::parse(rest, DebugArangesOffset(0x10)) 564 .expect_err("should fail to parse header"); 565 assert_eq!(error, Error::InvalidAddressRange); 566 } 567 568 #[test] test_parse_entry_ok()569 fn test_parse_entry_ok() { 570 let encoding = Encoding { 571 format: Format::Dwarf32, 572 version: 2, 573 address_size: 4, 574 }; 575 let segment_size = 0; 576 let buf = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]; 577 let rest = &mut EndianSlice::new(&buf, LittleEndian); 578 let entry = 579 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); 580 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); 581 assert_eq!( 582 entry, 583 Some(ArangeEntry { 584 segment: None, 585 address: 0x0403_0201, 586 length: 0x0807_0605, 587 }) 588 ); 589 } 590 591 #[test] test_parse_entry_segment()592 fn test_parse_entry_segment() { 593 let encoding = Encoding { 594 format: Format::Dwarf32, 595 version: 2, 596 address_size: 4, 597 }; 598 let segment_size = 8; 599 #[rustfmt::skip] 600 let buf = [ 601 // Segment. 602 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 603 // Address. 604 0x01, 0x02, 0x03, 0x04, 605 // Length. 606 0x05, 0x06, 0x07, 0x08, 607 // Next tuple. 608 0x09 609 ]; 610 let rest = &mut EndianSlice::new(&buf, LittleEndian); 611 let entry = 612 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); 613 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); 614 assert_eq!( 615 entry, 616 Some(ArangeEntry { 617 segment: Some(0x1817_1615_1413_1211), 618 address: 0x0403_0201, 619 length: 0x0807_0605, 620 }) 621 ); 622 } 623 624 #[test] test_parse_entry_zero()625 fn test_parse_entry_zero() { 626 let encoding = Encoding { 627 format: Format::Dwarf32, 628 version: 2, 629 address_size: 4, 630 }; 631 let segment_size = 0; 632 #[rustfmt::skip] 633 let buf = [ 634 // Zero tuple. 635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 636 // Address. 637 0x01, 0x02, 0x03, 0x04, 638 // Length. 639 0x05, 0x06, 0x07, 0x08, 640 // Next tuple. 641 0x09 642 ]; 643 let rest = &mut EndianSlice::new(&buf, LittleEndian); 644 let entry = 645 ArangeEntry::parse(rest, encoding, segment_size).expect("should parse entry ok"); 646 assert_eq!(*rest, EndianSlice::new(&buf[buf.len() - 1..], LittleEndian)); 647 assert_eq!( 648 entry, 649 Some(ArangeEntry { 650 segment: None, 651 address: 0x0403_0201, 652 length: 0x0807_0605, 653 }) 654 ); 655 } 656 } 657