@@ -249,6 +249,24 @@ impl<R: Reader> ArangeEntryIter<R> {
249249 /// yielded. If an error occurs while parsing the next arange, then this error
250250 /// is returned as `Err(e)`, and all subsequent calls return `Ok(None)`.
251251 pub fn next ( & mut self ) -> Result < Option < ArangeEntry > > {
252+ loop {
253+ let raw_entry = match self . next_raw ( ) ? {
254+ Some ( entry) => entry,
255+ None => return Ok ( None ) ,
256+ } ;
257+
258+ let entry = self . convert_raw ( raw_entry) ?;
259+ if entry. is_some ( ) {
260+ return Ok ( entry) ;
261+ }
262+ }
263+ }
264+
265+ /// Advance the iterator and return the next arange without validating it.
266+ ///
267+ /// The returned entry will have `range.end` set to 0.
268+ /// This will return tombstone entries as well.
269+ pub fn next_raw ( & mut self ) -> Result < Option < ArangeEntry > > {
252270 if self . input . is_empty ( ) {
253271 return Ok ( None ) ;
254272 }
@@ -265,6 +283,23 @@ impl<R: Reader> ArangeEntryIter<R> {
265283 }
266284 }
267285 }
286+
287+ /// Convert a raw range into a range.
288+ ///
289+ /// The raw range should have been obtained from `next_raw`.
290+ #[ doc( hidden) ]
291+ pub fn convert_raw ( & self , mut entry : ArangeEntry ) -> Result < Option < ArangeEntry > > {
292+ // Skip tombstone entries.
293+ let address_size = self . encoding . address_size ;
294+ let tombstone_address = !0 >> ( 64 - self . encoding . address_size * 8 ) ;
295+ if entry. range . begin == tombstone_address {
296+ return Ok ( None ) ;
297+ }
298+
299+ // Calculate end now so that we can handle overflow.
300+ entry. range . end = entry. range . begin . add_sized ( entry. length , address_size) ?;
301+ Ok ( Some ( entry) )
302+ }
268303}
269304
270305#[ cfg( feature = "fallible-iterator" ) ]
@@ -297,9 +332,7 @@ impl ArangeEntry {
297332
298333 let begin = input. read_address ( address_size) ?;
299334 let length = input. read_address ( address_size) ?;
300- // Calculate end now so that we can handle overflow.
301- let end = begin. add_sized ( length, address_size) ?;
302- let range = Range { begin, end } ;
335+ let range = Range { begin, end : 0 } ;
303336
304337 match ( begin, length) {
305338 // This is meant to be a null terminator, but in practice it can occur
@@ -533,9 +566,15 @@ mod tests {
533566 address_size : 4 ,
534567 } ;
535568 let buf = [ 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 ] ;
536- let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
537- let entry = ArangeEntry :: parse ( rest, encoding) . expect ( "should parse entry ok" ) ;
538- assert_eq ! ( * rest, EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian ) ) ;
569+ let mut iter = ArangeEntryIter {
570+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
571+ encoding,
572+ } ;
573+ let entry = iter. next ( ) . expect ( "should parse entry ok" ) ;
574+ assert_eq ! (
575+ iter. input,
576+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
577+ ) ;
539578 assert_eq ! (
540579 entry,
541580 Some ( ArangeEntry {
@@ -566,9 +605,15 @@ mod tests {
566605 // Next tuple.
567606 0x09
568607 ] ;
569- let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
570- let entry = ArangeEntry :: parse ( rest, encoding) . expect ( "should parse entry ok" ) ;
571- assert_eq ! ( * rest, EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian ) ) ;
608+ let mut iter = ArangeEntryIter {
609+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
610+ encoding,
611+ } ;
612+ let entry = iter. next ( ) . expect ( "should parse entry ok" ) ;
613+ assert_eq ! (
614+ iter. input,
615+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
616+ ) ;
572617 assert_eq ! (
573618 entry,
574619 Some ( ArangeEntry {
@@ -597,9 +642,15 @@ mod tests {
597642 // Next tuple.
598643 0x09
599644 ] ;
600- let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
601- let entry = ArangeEntry :: parse ( rest, encoding) ;
602- assert_eq ! ( * rest, EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian ) ) ;
645+ let mut iter = ArangeEntryIter {
646+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
647+ encoding,
648+ } ;
649+ let entry = iter. next ( ) ;
650+ assert_eq ! (
651+ iter. input,
652+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
653+ ) ;
603654 assert_eq ! ( entry, Err ( Error :: AddressOverflow ) ) ;
604655 }
605656
@@ -619,9 +670,139 @@ mod tests {
619670 // Next tuple.
620671 0x09
621672 ] ;
622- let rest = & mut EndianSlice :: new ( & buf, LittleEndian ) ;
623- let entry = ArangeEntry :: parse ( rest, encoding) ;
624- assert_eq ! ( * rest, EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian ) ) ;
673+ let mut iter = ArangeEntryIter {
674+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
675+ encoding,
676+ } ;
677+ let entry = iter. next ( ) ;
678+ assert_eq ! (
679+ iter. input,
680+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
681+ ) ;
625682 assert_eq ! ( entry, Err ( Error :: AddressOverflow ) ) ;
626683 }
684+
685+ #[ test]
686+ fn test_parse_entry_tombstone_32 ( ) {
687+ let encoding = Encoding {
688+ format : Format :: Dwarf32 ,
689+ version : 2 ,
690+ address_size : 4 ,
691+ } ;
692+ #[ rustfmt:: skip]
693+ let buf = [
694+ // Address.
695+ 0xff , 0xff , 0xff , 0xff ,
696+ // Length.
697+ 0x05 , 0x06 , 0x07 , 0x08 ,
698+ // Address.
699+ 0x01 , 0x02 , 0x03 , 0x04 ,
700+ // Length.
701+ 0x05 , 0x06 , 0x07 , 0x08 ,
702+ // Next tuple.
703+ 0x09
704+ ] ;
705+
706+ let mut iter = ArangeEntryIter {
707+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
708+ encoding,
709+ } ;
710+ let entry = iter. next_raw ( ) . unwrap ( ) ;
711+ assert_eq ! (
712+ iter. input,
713+ EndianSlice :: new( & buf[ buf. len( ) - 9 ..] , LittleEndian )
714+ ) ;
715+ assert_eq ! (
716+ entry,
717+ Some ( ArangeEntry {
718+ range: Range {
719+ begin: 0xffff_ffff ,
720+ end: 0 ,
721+ } ,
722+ length: 0x0807_0605 ,
723+ } )
724+ ) ;
725+
726+ let mut iter = ArangeEntryIter {
727+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
728+ encoding,
729+ } ;
730+ let entry = iter. next ( ) . unwrap ( ) ;
731+ assert_eq ! (
732+ iter. input,
733+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
734+ ) ;
735+ assert_eq ! (
736+ entry,
737+ Some ( ArangeEntry {
738+ range: Range {
739+ begin: 0x0403_0201 ,
740+ end: 0x0403_0201 + 0x0807_0605 ,
741+ } ,
742+ length: 0x0807_0605 ,
743+ } )
744+ ) ;
745+ }
746+
747+ #[ test]
748+ fn test_parse_entry_tombstone_64 ( ) {
749+ let encoding = Encoding {
750+ format : Format :: Dwarf32 ,
751+ version : 2 ,
752+ address_size : 8 ,
753+ } ;
754+ #[ rustfmt:: skip]
755+ let buf = [
756+ // Address.
757+ 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
758+ // Length.
759+ 0x05 , 0x06 , 0x07 , 0x08 , 0x00 , 0x00 , 0x00 , 0x00 ,
760+ // Address.
761+ 0x01 , 0x02 , 0x03 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 ,
762+ // Length.
763+ 0x05 , 0x06 , 0x07 , 0x08 , 0x00 , 0x00 , 0x00 , 0x00 ,
764+ // Next tuple.
765+ 0x09
766+ ] ;
767+
768+ let mut iter = ArangeEntryIter {
769+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
770+ encoding,
771+ } ;
772+ let entry = iter. next_raw ( ) . unwrap ( ) ;
773+ assert_eq ! (
774+ iter. input,
775+ EndianSlice :: new( & buf[ buf. len( ) - 17 ..] , LittleEndian )
776+ ) ;
777+ assert_eq ! (
778+ entry,
779+ Some ( ArangeEntry {
780+ range: Range {
781+ begin: 0xffff_ffff_ffff_ffff ,
782+ end: 0 ,
783+ } ,
784+ length: 0x0807_0605 ,
785+ } )
786+ ) ;
787+
788+ let mut iter = ArangeEntryIter {
789+ input : EndianSlice :: new ( & buf, LittleEndian ) ,
790+ encoding,
791+ } ;
792+ let entry = iter. next ( ) . unwrap ( ) ;
793+ assert_eq ! (
794+ iter. input,
795+ EndianSlice :: new( & buf[ buf. len( ) - 1 ..] , LittleEndian )
796+ ) ;
797+ assert_eq ! (
798+ entry,
799+ Some ( ArangeEntry {
800+ range: Range {
801+ begin: 0x0403_0201 ,
802+ end: 0x0403_0201 + 0x0807_0605 ,
803+ } ,
804+ length: 0x0807_0605 ,
805+ } )
806+ ) ;
807+ }
627808}
0 commit comments