1- use crate :: common:: { DebugInfoOffset , Encoding , SectionId } ;
1+ use crate :: common:: { DebugArangesOffset , DebugInfoOffset , Encoding , SectionId } ;
22use crate :: endianity:: Endianity ;
33use crate :: read:: { EndianSlice , Error , Reader , ReaderOffset , Result , Section } ;
44
@@ -42,8 +42,16 @@ impl<R: Reader> DebugAranges<R> {
4242 pub fn headers ( & self ) -> ArangeHeaderIter < R > {
4343 ArangeHeaderIter {
4444 input : self . section . clone ( ) ,
45+ offset : DebugArangesOffset ( R :: Offset :: from_u8 ( 0 ) ) ,
4546 }
4647 }
48+
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)
54+ }
4755}
4856
4957impl < T > DebugAranges < T > {
@@ -90,6 +98,7 @@ impl<R> From<R> for DebugAranges<R> {
9098#[ derive( Clone , Debug ) ]
9199pub struct ArangeHeaderIter < R : Reader > {
92100 input : R ,
101+ offset : DebugArangesOffset < R :: Offset > ,
93102}
94103
95104impl < R : Reader > ArangeHeaderIter < R > {
@@ -99,8 +108,12 @@ impl<R: Reader> ArangeHeaderIter<R> {
99108 return Ok ( None ) ;
100109 }
101110
102- match ArangeHeader :: parse ( & mut self . input ) {
103- Ok ( header) => Ok ( Some ( header) ) ,
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+ }
104117 Err ( e) => {
105118 self . input . empty ( ) ;
106119 Err ( e)
@@ -128,9 +141,10 @@ where
128141 R : Reader < Offset = Offset > ,
129142 Offset : ReaderOffset ,
130143{
144+ offset : DebugArangesOffset < Offset > ,
131145 encoding : Encoding ,
132146 length : Offset ,
133- offset : DebugInfoOffset < Offset > ,
147+ debug_info_offset : DebugInfoOffset < Offset > ,
134148 segment_size : u8 ,
135149 entries : R ,
136150}
@@ -140,7 +154,7 @@ where
140154 R : Reader < Offset = Offset > ,
141155 Offset : ReaderOffset ,
142156{
143- fn parse ( input : & mut R ) -> Result < Self > {
157+ fn parse ( input : & mut R , offset : DebugArangesOffset < Offset > ) -> Result < Self > {
144158 let ( length, format) = input. read_initial_length ( ) ?;
145159 let mut rest = input. split ( length) ?;
146160
@@ -149,7 +163,7 @@ where
149163 return Err ( Error :: UnknownVersion ( u64:: from ( version) ) ) ;
150164 }
151165
152- let offset = rest. read_offset ( format) . map ( DebugInfoOffset ) ?;
166+ let debug_info_offset = rest. read_offset ( format) . map ( DebugInfoOffset ) ?;
153167 let address_size = rest. read_u8 ( ) ?;
154168 let segment_size = rest. read_u8 ( ) ?;
155169
@@ -180,14 +194,21 @@ where
180194 // TODO: segment_size
181195 } ;
182196 Ok ( ArangeHeader {
197+ offset,
183198 encoding,
184199 length,
185- offset ,
200+ debug_info_offset ,
186201 segment_size,
187202 entries : rest,
188203 } )
189204 }
190205
206+ /// Return the offset of this header within the `.debug_aranges` section.
207+ #[ inline]
208+ pub fn offset ( & self ) -> DebugArangesOffset < Offset > {
209+ self . offset
210+ }
211+
191212 /// Return the length of this set of entries, including the header.
192213 #[ inline]
193214 pub fn length ( & self ) -> Offset {
@@ -209,7 +230,7 @@ where
209230 /// Return the offset into the .debug_info section for this set of arange entries.
210231 #[ inline]
211232 pub fn debug_info_offset ( & self ) -> DebugInfoOffset < Offset > {
212- self . offset
233+ self . debug_info_offset
213234 }
214235
215236 /// Return the arange entries in this set.
@@ -344,6 +365,60 @@ mod tests {
344365 use crate :: endianity:: LittleEndian ;
345366 use crate :: read:: EndianSlice ;
346367
368+ #[ test]
369+ fn test_iterate_headers ( ) {
370+ #[ rustfmt:: skip]
371+ let buf = [
372+ // 32-bit length = 28.
373+ 0x1c , 0x00 , 0x00 , 0x00 ,
374+ // Version.
375+ 0x02 , 0x00 ,
376+ // Offset.
377+ 0x01 , 0x02 , 0x03 , 0x04 ,
378+ // Address size.
379+ 0x04 ,
380+ // Segment size.
381+ 0x00 ,
382+ // Dummy padding and arange tuples.
383+ 0x00 , 0x00 , 0x00 , 0x00 ,
384+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
385+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
386+
387+ // 32-bit length = 36.
388+ 0x24 , 0x00 , 0x00 , 0x00 ,
389+ // Version.
390+ 0x02 , 0x00 ,
391+ // Offset.
392+ 0x11 , 0x12 , 0x13 , 0x14 ,
393+ // Address size.
394+ 0x04 ,
395+ // Segment size.
396+ 0x00 ,
397+ // Dummy padding and arange tuples.
398+ 0x00 , 0x00 , 0x00 , 0x00 ,
399+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
400+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
401+ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
402+ ] ;
403+
404+ let debug_aranges = DebugAranges :: new ( & buf, LittleEndian ) ;
405+ let mut headers = debug_aranges. headers ( ) ;
406+
407+ let header = headers
408+ . next ( )
409+ . expect ( "should parse header ok" )
410+ . expect ( "should have a header" ) ;
411+ assert_eq ! ( header. offset( ) , DebugArangesOffset ( 0 ) ) ;
412+ assert_eq ! ( header. debug_info_offset( ) , DebugInfoOffset ( 0x0403_0201 ) ) ;
413+
414+ let header = headers
415+ . next ( )
416+ . expect ( "should parse header ok" )
417+ . expect ( "should have a header" ) ;
418+ assert_eq ! ( header. offset( ) , DebugArangesOffset ( 0x20 ) ) ;
419+ assert_eq ! ( header. debug_info_offset( ) , DebugInfoOffset ( 0x1413_1211 ) ) ;
420+ }
421+
347422 #[ test]
348423 fn test_parse_header_ok ( ) {
349424 #[ rustfmt:: skip]
@@ -378,7 +453,8 @@ mod tests {
378453
379454 let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
380455
381- let header = ArangeHeader :: parse ( rest) . expect ( "should parse header ok" ) ;
456+ let header =
457+ ArangeHeader :: parse ( rest, DebugArangesOffset ( 0x10 ) ) . expect ( "should parse header ok" ) ;
382458
383459 assert_eq ! (
384460 * rest,
@@ -387,13 +463,14 @@ mod tests {
387463 assert_eq ! (
388464 header,
389465 ArangeHeader {
466+ offset: DebugArangesOffset ( 0x10 ) ,
390467 encoding: Encoding {
391468 format: Format :: Dwarf32 ,
392469 version: 2 ,
393470 address_size: 8 ,
394471 } ,
395472 length: 0x20 ,
396- offset : DebugInfoOffset ( 0x0403_0201 ) ,
473+ debug_info_offset : DebugInfoOffset ( 0x0403_0201 ) ,
397474 segment_size: 4 ,
398475 entries: EndianSlice :: new( & buf[ buf. len( ) - 32 ..buf. len( ) - 16 ] , LittleEndian ) ,
399476 }
@@ -434,7 +511,8 @@ mod tests {
434511
435512 let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
436513
437- let error = ArangeHeader :: parse ( rest) . expect_err ( "should fail to parse header" ) ;
514+ let error = ArangeHeader :: parse ( rest, DebugArangesOffset ( 0x10 ) )
515+ . expect_err ( "should fail to parse header" ) ;
438516 assert_eq ! ( error, Error :: InvalidAddressRange ) ;
439517 }
440518
@@ -473,7 +551,8 @@ mod tests {
473551
474552 let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
475553
476- let error = ArangeHeader :: parse ( rest) . expect_err ( "should fail to parse header" ) ;
554+ let error = ArangeHeader :: parse ( rest, DebugArangesOffset ( 0x10 ) )
555+ . expect_err ( "should fail to parse header" ) ;
477556 assert_eq ! ( error, Error :: InvalidAddressRange ) ;
478557 }
479558
0 commit comments