Skip to content

Commit 94e37ed

Browse files
committed
read: reorder aranges.rs
1 parent d36fcf1 commit 94e37ed

File tree

1 file changed

+143
-128
lines changed

1 file changed

+143
-128
lines changed

src/read/aranges.rs

Lines changed: 143 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,68 @@ use crate::read::{
88
parse_debug_info_offset, EndianSlice, Error, Reader, ReaderOffset, Result, Section,
99
};
1010

11-
#[derive(Debug, Clone, PartialEq, Eq)]
12-
struct ArangeHeader<T = usize> {
13-
encoding: Encoding,
14-
length: T,
15-
offset: DebugInfoOffset<T>,
16-
segment_size: u8,
17-
}
18-
19-
/// A single parsed arange.
20-
#[derive(Debug, Clone, PartialEq, Eq)]
21-
pub struct ArangeEntry<T: Copy = usize> {
22-
segment: Option<u64>,
23-
address: u64,
24-
length: u64,
25-
unit_header_offset: DebugInfoOffset<T>,
26-
}
27-
28-
impl<T: Copy> ArangeEntry<T> {
29-
/// Return the segment selector of this arange.
30-
#[inline]
31-
pub fn segment(&self) -> Option<u64> {
32-
self.segment
33-
}
11+
/// The `DebugAranges` struct represents the DWARF address range information
12+
/// found in the `.debug_aranges` section.
13+
#[derive(Debug, Clone)]
14+
pub struct DebugAranges<R: Reader>(DebugLookup<R, ArangeParser<R>>);
3415

35-
/// Return the beginning address of this arange.
36-
#[inline]
37-
pub fn address(&self) -> u64 {
38-
self.address
16+
impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>>
17+
where
18+
Endian: Endianity,
19+
{
20+
/// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
21+
/// section.
22+
///
23+
/// It is the caller's responsibility to read the `.debug_aranges` section and
24+
/// present it as a `&[u8]` slice. That means using some ELF loader on
25+
/// Linux, a Mach-O loader on OSX, etc.
26+
///
27+
/// ```
28+
/// use gimli::{DebugAranges, LittleEndian};
29+
///
30+
/// # let buf = [];
31+
/// # let read_debug_aranges_section = || &buf;
32+
/// let debug_aranges =
33+
/// DebugAranges::new(read_debug_aranges_section(), LittleEndian);
34+
/// ```
35+
pub fn new(debug_aranges_section: &'input [u8], endian: Endian) -> Self {
36+
Self::from(EndianSlice::new(debug_aranges_section, endian))
3937
}
38+
}
4039

41-
/// Return the length of this arange.
42-
#[inline]
43-
pub fn length(&self) -> u64 {
44-
self.length
40+
impl<R: Reader> DebugAranges<R> {
41+
/// Iterate the aranges in the `.debug_aranges` section.
42+
///
43+
/// ```
44+
/// use gimli::{DebugAranges, EndianSlice, LittleEndian};
45+
///
46+
/// # let buf = [];
47+
/// # let read_debug_aranges_section = || &buf;
48+
/// let debug_aranges = DebugAranges::new(read_debug_aranges_section(), LittleEndian);
49+
///
50+
/// let mut iter = debug_aranges.items();
51+
/// while let Some(arange) = iter.next().unwrap() {
52+
/// println!("arange starts at {}, has length {}", arange.address(), arange.length());
53+
/// }
54+
/// ```
55+
pub fn items(&self) -> ArangeEntryIter<R> {
56+
ArangeEntryIter(self.0.items())
4557
}
58+
}
4659

47-
/// Return the offset into the .debug_info section for this arange.
48-
#[inline]
49-
pub fn debug_info_offset(&self) -> DebugInfoOffset<T> {
50-
self.unit_header_offset
60+
impl<R: Reader> Section<R> for DebugAranges<R> {
61+
fn id() -> SectionId {
62+
SectionId::DebugAranges
5163
}
52-
}
5364

54-
impl<T: Copy + Ord> PartialOrd for ArangeEntry<T> {
55-
fn partial_cmp(&self, other: &ArangeEntry<T>) -> Option<Ordering> {
56-
Some(self.cmp(other))
65+
fn reader(&self) -> &R {
66+
self.0.reader()
5767
}
5868
}
5969

60-
impl<T: Copy + Ord> Ord for ArangeEntry<T> {
61-
fn cmp(&self, other: &ArangeEntry<T>) -> Ordering {
62-
// The expected comparison, but ignore header.
63-
self.segment
64-
.cmp(&other.segment)
65-
.then(self.address.cmp(&other.address))
66-
.then(self.length.cmp(&other.length))
70+
impl<R: Reader> From<R> for DebugAranges<R> {
71+
fn from(debug_aranges_section: R) -> Self {
72+
DebugAranges(DebugLookup::from(debug_aranges_section))
6773
}
6874
}
6975

@@ -77,9 +83,27 @@ impl<R: Reader> LookupParser<R> for ArangeParser<R> {
7783
type Header = ArangeHeader<R::Offset>;
7884
type Entry = ArangeEntry<R::Offset>;
7985

86+
fn parse_header(input: &mut R) -> Result<(R, Self::Header)> {
87+
ArangeHeader::parse(input)
88+
}
89+
90+
fn parse_entry(input: &mut R, header: &Self::Header) -> Result<Option<Self::Entry>> {
91+
ArangeEntry::parse(input, header)
92+
}
93+
}
94+
95+
#[derive(Debug, Clone, PartialEq, Eq)]
96+
struct ArangeHeader<T = usize> {
97+
encoding: Encoding,
98+
length: T,
99+
offset: DebugInfoOffset<T>,
100+
segment_size: u8,
101+
}
102+
103+
impl<T: ReaderOffset> ArangeHeader<T> {
80104
/// Parse an arange set header. Returns a tuple of the aranges to be
81105
/// parsed for this set, and the newly created ArangeHeader struct.
82-
fn parse_header(input: &mut R) -> Result<(R, Self::Header)> {
106+
fn parse<R: Reader<Offset = T>>(input: &mut R) -> Result<(R, Self)> {
83107
let (length, format) = input.read_initial_length()?;
84108
let mut rest = input.split(length)?;
85109

@@ -128,9 +152,52 @@ impl<R: Reader> LookupParser<R> for ArangeParser<R> {
128152
},
129153
))
130154
}
155+
}
156+
157+
/// An iterator over the aranges from a `.debug_aranges` section.
158+
///
159+
/// Can be [used with
160+
/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
161+
#[derive(Debug, Clone)]
162+
pub struct ArangeEntryIter<R: Reader>(LookupEntryIter<R, ArangeParser<R>>);
163+
164+
impl<R: Reader> ArangeEntryIter<R> {
165+
/// Advance the iterator and return the next arange.
166+
///
167+
/// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
168+
/// when iteration is complete and all aranges have already been parsed and
169+
/// yielded. If an error occurs while parsing the next arange, then this error
170+
/// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
171+
pub fn next(&mut self) -> Result<Option<ArangeEntry<R::Offset>>> {
172+
self.0.next()
173+
}
174+
}
175+
176+
#[cfg(feature = "fallible-iterator")]
177+
impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
178+
type Item = ArangeEntry<R::Offset>;
179+
type Error = Error;
131180

181+
fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
182+
self.0.next()
183+
}
184+
}
185+
186+
/// A single parsed arange.
187+
#[derive(Debug, Clone, PartialEq, Eq)]
188+
pub struct ArangeEntry<T: Copy = usize> {
189+
segment: Option<u64>,
190+
address: u64,
191+
length: u64,
192+
unit_header_offset: DebugInfoOffset<T>,
193+
}
194+
195+
impl<T: ReaderOffset> ArangeEntry<T> {
132196
/// Parse a single arange. Return `None` for the null arange, `Some` for an actual arange.
133-
fn parse_entry(input: &mut R, header: &Self::Header) -> Result<Option<Self::Entry>> {
197+
fn parse<R: Reader<Offset = T>>(
198+
input: &mut R,
199+
header: &ArangeHeader<T>,
200+
) -> Result<Option<Self>> {
134201
let address_size = header.encoding.address_size;
135202
let segment_size = header.segment_size; // May be zero!
136203

@@ -152,7 +219,7 @@ impl<R: Reader> LookupParser<R> for ArangeParser<R> {
152219
// There may be multiple sets of tuples, each terminated by a zero tuple.
153220
// It's not clear what purpose these zero tuples serve. For now, we
154221
// simply skip them.
155-
(0, 0, 0) => Self::parse_entry(input, header),
222+
(0, 0, 0) => Self::parse(input, header),
156223
_ => Ok(Some(ArangeEntry {
157224
segment: if segment_size != 0 {
158225
Some(segment)
@@ -167,97 +234,45 @@ impl<R: Reader> LookupParser<R> for ArangeParser<R> {
167234
}
168235
}
169236

170-
/// The `DebugAranges` struct represents the DWARF address range information
171-
/// found in the `.debug_aranges` section.
172-
#[derive(Debug, Clone)]
173-
pub struct DebugAranges<R: Reader>(DebugLookup<R, ArangeParser<R>>);
174-
175-
impl<'input, Endian> DebugAranges<EndianSlice<'input, Endian>>
176-
where
177-
Endian: Endianity,
178-
{
179-
/// Construct a new `DebugAranges` instance from the data in the `.debug_aranges`
180-
/// section.
181-
///
182-
/// It is the caller's responsibility to read the `.debug_aranges` section and
183-
/// present it as a `&[u8]` slice. That means using some ELF loader on
184-
/// Linux, a Mach-O loader on OSX, etc.
185-
///
186-
/// ```
187-
/// use gimli::{DebugAranges, LittleEndian};
188-
///
189-
/// # let buf = [];
190-
/// # let read_debug_aranges_section = || &buf;
191-
/// let debug_aranges =
192-
/// DebugAranges::new(read_debug_aranges_section(), LittleEndian);
193-
/// ```
194-
pub fn new(debug_aranges_section: &'input [u8], endian: Endian) -> Self {
195-
Self::from(EndianSlice::new(debug_aranges_section, endian))
196-
}
197-
}
198-
199-
impl<R: Reader> DebugAranges<R> {
200-
/// Iterate the aranges in the `.debug_aranges` section.
201-
///
202-
/// ```
203-
/// use gimli::{DebugAranges, EndianSlice, LittleEndian};
204-
///
205-
/// # let buf = [];
206-
/// # let read_debug_aranges_section = || &buf;
207-
/// let debug_aranges = DebugAranges::new(read_debug_aranges_section(), LittleEndian);
208-
///
209-
/// let mut iter = debug_aranges.items();
210-
/// while let Some(arange) = iter.next().unwrap() {
211-
/// println!("arange starts at {}, has length {}", arange.address(), arange.length());
212-
/// }
213-
/// ```
214-
pub fn items(&self) -> ArangeEntryIter<R> {
215-
ArangeEntryIter(self.0.items())
237+
impl<T: Copy> ArangeEntry<T> {
238+
/// Return the segment selector of this arange.
239+
#[inline]
240+
pub fn segment(&self) -> Option<u64> {
241+
self.segment
216242
}
217-
}
218243

219-
impl<R: Reader> Section<R> for DebugAranges<R> {
220-
fn id() -> SectionId {
221-
SectionId::DebugAranges
244+
/// Return the beginning address of this arange.
245+
#[inline]
246+
pub fn address(&self) -> u64 {
247+
self.address
222248
}
223249

224-
fn reader(&self) -> &R {
225-
self.0.reader()
250+
/// Return the length of this arange.
251+
#[inline]
252+
pub fn length(&self) -> u64 {
253+
self.length
226254
}
227-
}
228255

229-
impl<R: Reader> From<R> for DebugAranges<R> {
230-
fn from(debug_aranges_section: R) -> Self {
231-
DebugAranges(DebugLookup::from(debug_aranges_section))
256+
/// Return the offset into the .debug_info section for this arange.
257+
#[inline]
258+
pub fn debug_info_offset(&self) -> DebugInfoOffset<T> {
259+
self.unit_header_offset
232260
}
233261
}
234262

235-
/// An iterator over the aranges from a `.debug_aranges` section.
236-
///
237-
/// Can be [used with
238-
/// `FallibleIterator`](./index.html#using-with-fallibleiterator).
239-
#[derive(Debug, Clone)]
240-
pub struct ArangeEntryIter<R: Reader>(LookupEntryIter<R, ArangeParser<R>>);
241-
242-
impl<R: Reader> ArangeEntryIter<R> {
243-
/// Advance the iterator and return the next arange.
244-
///
245-
/// Returns the newly parsed arange as `Ok(Some(arange))`. Returns `Ok(None)`
246-
/// when iteration is complete and all aranges have already been parsed and
247-
/// yielded. If an error occurs while parsing the next arange, then this error
248-
/// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
249-
pub fn next(&mut self) -> Result<Option<ArangeEntry<R::Offset>>> {
250-
self.0.next()
263+
impl<T: Copy + Ord> PartialOrd for ArangeEntry<T> {
264+
fn partial_cmp(&self, other: &ArangeEntry<T>) -> Option<Ordering> {
265+
Some(self.cmp(other))
251266
}
252267
}
253268

254-
#[cfg(feature = "fallible-iterator")]
255-
impl<R: Reader> fallible_iterator::FallibleIterator for ArangeEntryIter<R> {
256-
type Item = ArangeEntry<R::Offset>;
257-
type Error = Error;
258-
259-
fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
260-
self.0.next()
269+
impl<T: Copy + Ord> Ord for ArangeEntry<T> {
270+
fn cmp(&self, other: &ArangeEntry<T>) -> Ordering {
271+
// The expected comparison, but ignore header.
272+
self.segment
273+
.cmp(&other.segment)
274+
.then(self.address.cmp(&other.address))
275+
.then(self.length.cmp(&other.length))
261276
}
262277
}
263278

0 commit comments

Comments
 (0)