@@ -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