1 use crate::common
::{DebugArangesOffset, DebugInfoOffset, Encoding, SectionId}
;
2 use crate::endianity
::Endianity
;
3 use crate::read
::{EndianSlice, Error, Range, Reader, ReaderOffset, Result, Section}
;
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
> {
12 impl<'input
, Endian
> DebugAranges
<EndianSlice
<'input
, Endian
>>
16 /// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
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.
24 /// use gimli::{DebugAranges, LittleEndian};
27 /// # let read_debug_aranges_section = || &buf;
28 /// let debug_aranges =
29 /// DebugAranges::new(read_debug_aranges_section(), LittleEndian);
31 pub fn new(section
: &'input
[u8], endian
: Endian
) -> Self {
33 section
: EndianSlice
::new(section
, endian
),
38 impl<R
: Reader
> DebugAranges
<R
> {
39 /// Iterate the sets of entries in the `.debug_aranges` section.
41 /// Each set of entries belongs to a single unit.
42 pub fn headers(&self) -> ArangeHeaderIter
<R
> {
44 input
: self.section
.clone(),
45 offset
: DebugArangesOffset(R
::Offset
::from_u8(0)),
49 /// Get the header at the given offset.
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
)
57 impl<T
> DebugAranges
<T
> {
58 /// Create a `DebugAranges` section that references the data in `self`.
60 /// This is useful when `R` implements `Reader` but `T` does not.
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)
73 pub fn borrow
<'a
, F
, R
>(&'a
self, mut borrow
: F
) -> DebugAranges
<R
>
77 borrow(&self.section
).into()
81 impl<R
> Section
<R
> for DebugAranges
<R
> {
82 fn id() -> SectionId
{
83 SectionId
::DebugAranges
86 fn reader(&self) -> &R
{
91 impl<R
> From
<R
> for DebugAranges
<R
> {
92 fn from(section
: R
) -> Self {
93 DebugAranges { section }
97 /// An iterator over the headers of a `.debug_aranges` section.
98 #[derive(Clone, Debug)]
99 pub struct ArangeHeaderIter
<R
: Reader
> {
101 offset
: DebugArangesOffset
<R
::Offset
>,
104 impl<R
: Reader
> ArangeHeaderIter
<R
> {
105 /// Advance the iterator to the next header.
106 pub fn next(&mut self) -> Result
<Option
<ArangeHeader
<R
>>> {
107 if self.input
.is_empty() {
111 let len
= self.input
.len();
112 match ArangeHeader
::parse(&mut self.input
, self.offset
) {
114 self.offset
.0 += len
- self.input
.len();
125 #[cfg(feature = "fallible-iterator")]
126 impl<R
: Reader
> fallible_iterator
::FallibleIterator
for ArangeHeaderIter
<R
> {
127 type Item
= ArangeHeader
<R
>;
130 fn next(&mut self) -> ::core
::result
::Result
<Option
<Self::Item
>, Self::Error
> {
131 ArangeHeaderIter
::next(self)
135 /// A header for a set of entries in the `.debug_arange` section.
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
>
141 R
: Reader
<Offset
= Offset
>,
142 Offset
: ReaderOffset
,
144 offset
: DebugArangesOffset
<Offset
>,
147 debug_info_offset
: DebugInfoOffset
<Offset
>,
152 impl<R
, Offset
> ArangeHeader
<R
, Offset
>
154 R
: Reader
<Offset
= Offset
>,
155 Offset
: ReaderOffset
,
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
)?
;
161 // Check the version. The DWARF 5 spec says that this is always 2, but version 3
162 // has been observed in the wild, potentially due to a bug; see
163 // https://github.com/gimli-rs/gimli/issues/559 for more information.
164 // lldb allows versions 2 through 5, possibly by mistake.
165 let version
= rest
.read_u16()?
;
166 if version
!= 2 && version
!= 3 {
167 return Err(Error
::UnknownVersion(u64::from(version
)));
170 let debug_info_offset
= rest
.read_offset(format
).map(DebugInfoOffset
)?
;
171 let address_size
= rest
.read_u8()?
;
172 let segment_size
= rest
.read_u8()?
;
174 // unit_length + version + offset + address_size + segment_size
175 let header_length
= format
.initial_length_size() + 2 + format
.word_size() + 1 + 1;
177 // The first tuple following the header in each set begins at an offset that is
178 // a multiple of the size of a single tuple (that is, the size of a segment selector
179 // plus twice the size of an address).
180 let tuple_length
= address_size
182 .and_then(|x
| x
.checked_add(segment_size
))
183 .ok_or(Error
::InvalidAddressRange
)?
;
184 if tuple_length
== 0 {
185 return Err(Error
::InvalidAddressRange
)?
;
187 let padding
= if header_length
% tuple_length
== 0 {
190 tuple_length
- header_length
% tuple_length
192 rest
.skip(R
::Offset
::from_u8(padding
))?
;
194 let encoding
= Encoding
{
198 // TODO: segment_size
210 /// Return the offset of this header within the `.debug_aranges` section.
212 pub fn offset(&self) -> DebugArangesOffset
<Offset
> {
216 /// Return the length of this set of entries, including the header.
218 pub fn length(&self) -> Offset
{
222 /// Return the encoding parameters for this set of entries.
224 pub fn encoding(&self) -> Encoding
{
228 /// Return the segment size for this set of entries.
230 pub fn segment_size(&self) -> u8 {
234 /// Return the offset into the .debug_info section for this set of arange entries.
236 pub fn debug_info_offset(&self) -> DebugInfoOffset
<Offset
> {
237 self.debug_info_offset
240 /// Return the arange entries in this set.
242 pub fn entries(&self) -> ArangeEntryIter
<R
> {
244 input
: self.entries
.clone(),
245 encoding
: self.encoding
,
246 segment_size
: self.segment_size
,
251 /// An iterator over the aranges from a `.debug_aranges` section.
253 /// Can be [used with
254 /// `FallibleIterator`](./index.html#using-with-fallibleiterator).
255 #[derive(Debug, Clone)]
256 pub struct ArangeEntryIter
<R
: Reader
> {
262 impl<R
: Reader
> ArangeEntryIter
<R
> {
263 /// Advance the iterator and return the next arange.
265 /// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
266 /// when iteration is complete and all aranges have already been parsed and
267 /// yielded. If an error occurs while parsing the next arange, then this error
268 /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
269 pub fn next(&mut self) -> Result
<Option
<ArangeEntry
>> {
270 if self.input
.is_empty() {
274 match ArangeEntry
::parse(&mut self.input
, self.encoding
, self.segment_size
) {
275 Ok(Some(entry
)) => Ok(Some(entry
)),
288 #[cfg(feature = "fallible-iterator")]
289 impl<R
: Reader
> fallible_iterator
::FallibleIterator
for ArangeEntryIter
<R
> {
290 type Item
= ArangeEntry
;
293 fn next(&mut self) -> ::core
::result
::Result
<Option
<Self::Item
>, Self::Error
> {
294 ArangeEntryIter
::next(self)
298 /// A single parsed arange.
299 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
300 pub struct ArangeEntry
{
301 segment
: Option
<u64>,
307 /// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
312 ) -> Result
<Option
<Self>> {
313 let address_size
= encoding
.address_size
;
315 let tuple_length
= R
::Offset
::from_u8(2 * address_size
+ segment_size
);
316 if tuple_length
> input
.len() {
321 let segment
= if segment_size
!= 0 {
322 input
.read_address(segment_size
)?
326 let address
= input
.read_address(address_size
)?
;
327 let length
= input
.read_address(address_size
)?
;
329 match (segment
, address
, length
) {
330 // This is meant to be a null terminator, but in practice it can occur
331 // before the end, possibly due to a linker omitting a function and
332 // leaving an unrelocated entry.
333 (0, 0, 0) => Self::parse(input
, encoding
, segment_size
),
334 _
=> Ok(Some(ArangeEntry
{
335 segment
: if segment_size
!= 0 {
346 /// Return the segment selector of this arange.
348 pub fn segment(&self) -> Option
<u64> {
352 /// Return the beginning address of this arange.
354 pub fn address(&self) -> u64 {
358 /// Return the length of this arange.
360 pub fn length(&self) -> u64 {
364 /// Return the range.
366 pub fn range(&self) -> Range
{
369 end
: self.address
.wrapping_add(self.length
),
377 use crate::common
::{DebugInfoOffset, Format}
;
378 use crate::endianity
::LittleEndian
;
379 use crate::read
::EndianSlice
;
382 fn test_iterate_headers() {
385 // 32-bit length = 28.
386 0x1c, 0x00, 0x00, 0x00,
390 0x01, 0x02, 0x03, 0x04,
395 // Dummy padding and arange tuples.
396 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 // 32-bit length = 36.
401 0x24, 0x00, 0x00, 0x00,
405 0x11, 0x12, 0x13, 0x14,
410 // Dummy padding and arange tuples.
411 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 let debug_aranges
= DebugAranges
::new(&buf
, LittleEndian
);
418 let mut headers
= debug_aranges
.headers();
422 .expect("should parse header ok")
423 .expect("should have a header");
424 assert_eq
!(header
.offset(), DebugArangesOffset(0));
425 assert_eq
!(header
.debug_info_offset(), DebugInfoOffset(0x0403_0201));
429 .expect("should parse header ok")
430 .expect("should have a header");
431 assert_eq
!(header
.offset(), DebugArangesOffset(0x20));
432 assert_eq
!(header
.debug_info_offset(), DebugInfoOffset(0x1413_1211));
436 fn test_parse_header_ok() {
439 // 32-bit length = 32.
440 0x20, 0x00, 0x00, 0x00,
444 0x01, 0x02, 0x03, 0x04,
449 // Length to here = 12, tuple length = 20.
450 // Padding to tuple length multiple = 4.
451 0x10, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00,
454 // Dummy arange tuple data.
455 0x20, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00,
458 0x00, 0x00, 0x00, 0x00,
460 // Dummy next arange.
461 0x30, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00,
467 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
470 ArangeHeader
::parse(rest
, DebugArangesOffset(0x10)).expect("should parse header ok");
474 EndianSlice
::new(&buf
[buf
.len() - 16..], LittleEndian
)
479 offset
: DebugArangesOffset(0x10),
481 format
: Format
::Dwarf32
,
486 debug_info_offset
: DebugInfoOffset(0x0403_0201),
488 entries
: EndianSlice
::new(&buf
[buf
.len() - 32..buf
.len() - 16], LittleEndian
),
494 fn test_parse_header_overflow_error() {
497 // 32-bit length = 32.
498 0x20, 0x00, 0x00, 0x00,
502 0x01, 0x02, 0x03, 0x04,
507 // Length to here = 12, tuple length = 20.
508 // Padding to tuple length multiple = 4.
509 0x10, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00,
512 // Dummy arange tuple data.
513 0x20, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00,
518 // Dummy next arange.
519 0x30, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00,
522 0x00, 0x00, 0x00, 0x00,
525 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
527 let error
= ArangeHeader
::parse(rest
, DebugArangesOffset(0x10))
528 .expect_err("should fail to parse header");
529 assert_eq
!(error
, Error
::InvalidAddressRange
);
533 fn test_parse_header_div_by_zero_error() {
536 // 32-bit length = 32.
537 0x20, 0x00, 0x00, 0x00,
541 0x01, 0x02, 0x03, 0x04,
542 // Address size = 0. Could cause a division by zero if we aren't
547 // Length to here = 12, tuple length = 20.
548 // Padding to tuple length multiple = 4.
549 0x10, 0x00, 0x00, 0x00,
550 0x00, 0x00, 0x00, 0x00,
552 // Dummy arange tuple data.
553 0x20, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00,
558 // Dummy next arange.
559 0x30, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00,
565 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
567 let error
= ArangeHeader
::parse(rest
, DebugArangesOffset(0x10))
568 .expect_err("should fail to parse header");
569 assert_eq
!(error
, Error
::InvalidAddressRange
);
573 fn test_parse_entry_ok() {
574 let encoding
= Encoding
{
575 format
: Format
::Dwarf32
,
579 let segment_size
= 0;
580 let buf
= [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09];
581 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
583 ArangeEntry
::parse(rest
, encoding
, segment_size
).expect("should parse entry ok");
584 assert_eq
!(*rest
, EndianSlice
::new(&buf
[buf
.len() - 1..], LittleEndian
));
589 address
: 0x0403_0201,
596 fn test_parse_entry_segment() {
597 let encoding
= Encoding
{
598 format
: Format
::Dwarf32
,
602 let segment_size
= 8;
606 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
608 0x01, 0x02, 0x03, 0x04,
610 0x05, 0x06, 0x07, 0x08,
614 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
616 ArangeEntry
::parse(rest
, encoding
, segment_size
).expect("should parse entry ok");
617 assert_eq
!(*rest
, EndianSlice
::new(&buf
[buf
.len() - 1..], LittleEndian
));
621 segment
: Some(0x1817_1615_1413_1211),
622 address
: 0x0403_0201,
629 fn test_parse_entry_zero() {
630 let encoding
= Encoding
{
631 format
: Format
::Dwarf32
,
635 let segment_size
= 0;
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x01, 0x02, 0x03, 0x04,
643 0x05, 0x06, 0x07, 0x08,
647 let rest
= &mut EndianSlice
::new(&buf
, LittleEndian
);
649 ArangeEntry
::parse(rest
, encoding
, segment_size
).expect("should parse entry ok");
650 assert_eq
!(*rest
, EndianSlice
::new(&buf
[buf
.len() - 1..], LittleEndian
));
655 address
: 0x0403_0201,