@@ -656,7 +656,7 @@ pub trait UnwindSection<R: Reader>: Clone + Debug + _UnwindSectionPrivate<R> {
656656 let offset = UnwindOffset :: into ( offset) ;
657657 let input = & mut self . section ( ) . clone ( ) ;
658658 input. skip ( offset) ?;
659- CommonInformationEntry :: parse ( bases , self , input)
659+ CommonInformationEntry :: parse ( self , bases , input)
660660 }
661661
662662 /// Parse the `PartialFrameDescriptionEntry` at the given offset.
@@ -1011,7 +1011,7 @@ where
10111011 return Ok ( None ) ;
10121012 }
10131013
1014- match parse_cfi_entry ( self . bases , & self . section , & mut self . input ) {
1014+ match parse_cfi_entry ( & self . section , self . bases , & mut self . input ) {
10151015 Ok ( Some ( entry) ) => return Ok ( Some ( entry) ) ,
10161016 Err ( e) => {
10171017 self . input . empty ( ) ;
@@ -1076,10 +1076,45 @@ where
10761076}
10771077
10781078fn parse_cfi_entry < ' bases , Section , R > (
1079- bases : & ' bases BaseAddresses ,
10801079 section : & Section ,
1080+ bases : & ' bases BaseAddresses ,
10811081 input : & mut R ,
10821082) -> Result < Option < CieOrFde < ' bases , Section , R > > >
1083+ where
1084+ R : Reader ,
1085+ Section : UnwindSection < R > ,
1086+ {
1087+ let Some ( prefix) = parse_cfi_entry_prefix ( section, input) ? else {
1088+ return Ok ( None ) ;
1089+ } ;
1090+
1091+ if Section :: is_cie ( prefix. format , prefix. cie_id_or_offset ) {
1092+ let cie = CommonInformationEntry :: from_prefix ( section, bases, prefix) ?;
1093+ Ok ( Some ( CieOrFde :: Cie ( cie) ) )
1094+ } else {
1095+ let fde = PartialFrameDescriptionEntry :: from_prefix ( section, bases, prefix) ?;
1096+ Ok ( Some ( CieOrFde :: Fde ( fde) ) )
1097+ }
1098+ }
1099+
1100+ /// The common prefix of a CIE or FDE.
1101+ #[ derive( Clone , Debug , PartialEq , Eq ) ]
1102+ struct CfiEntryPrefix < R >
1103+ where
1104+ R : Reader ,
1105+ {
1106+ offset : R :: Offset ,
1107+ length : R :: Offset ,
1108+ format : Format ,
1109+ cie_offset_base : R :: Offset ,
1110+ cie_id_or_offset : u64 ,
1111+ rest : R ,
1112+ }
1113+
1114+ fn parse_cfi_entry_prefix < Section , R > (
1115+ section : & Section ,
1116+ input : & mut R ,
1117+ ) -> Result < Option < CfiEntryPrefix < R > > >
10831118where
10841119 R : Reader ,
10851120 Section : UnwindSection < R > ,
@@ -1097,28 +1132,14 @@ where
10971132 CieOffsetEncoding :: U64 => rest. read_u64 ( ) ?,
10981133 } ;
10991134
1100- if Section :: is_cie ( format, cie_id_or_offset) {
1101- let cie = CommonInformationEntry :: parse_rest ( offset, length, format, bases, section, rest) ?;
1102- Ok ( Some ( CieOrFde :: Cie ( cie) ) )
1103- } else {
1104- let cie_offset = R :: Offset :: from_u64 ( cie_id_or_offset) ?;
1105- let cie_offset = match section. resolve_cie_offset ( cie_offset_base, cie_offset) {
1106- None => return Err ( Error :: OffsetOutOfBounds ) ,
1107- Some ( cie_offset) => cie_offset,
1108- } ;
1109-
1110- let fde = PartialFrameDescriptionEntry {
1111- offset,
1112- length,
1113- format,
1114- cie_offset : cie_offset. into ( ) ,
1115- rest,
1116- section : section. clone ( ) ,
1117- bases,
1118- } ;
1119-
1120- Ok ( Some ( CieOrFde :: Fde ( fde) ) )
1121- }
1135+ Ok ( Some ( CfiEntryPrefix {
1136+ offset,
1137+ length,
1138+ format,
1139+ cie_offset_base,
1140+ cie_id_or_offset,
1141+ rest,
1142+ } ) )
11221143}
11231144
11241145/// We support the z-style augmentation [defined by `.eh_frame`][ehframe].
@@ -1313,25 +1334,25 @@ where
13131334
13141335impl < R : Reader > CommonInformationEntry < R > {
13151336 fn parse < Section : UnwindSection < R > > (
1316- bases : & BaseAddresses ,
13171337 section : & Section ,
1338+ bases : & BaseAddresses ,
13181339 input : & mut R ,
13191340 ) -> Result < CommonInformationEntry < R > > {
1320- match parse_cfi_entry ( bases, section, input) ? {
1321- Some ( CieOrFde :: Cie ( cie) ) => Ok ( cie) ,
1322- Some ( CieOrFde :: Fde ( _) ) => Err ( Error :: NotCieId ) ,
1323- None => Err ( Error :: NoEntryAtGivenOffset ) ,
1341+ let Some ( prefix) = parse_cfi_entry_prefix ( section, input) ? else {
1342+ return Err ( Error :: NoEntryAtGivenOffset ) ;
1343+ } ;
1344+ if !Section :: is_cie ( prefix. format , prefix. cie_id_or_offset ) {
1345+ return Err ( Error :: NotCieId ) ;
13241346 }
1347+ CommonInformationEntry :: from_prefix ( section, bases, prefix)
13251348 }
13261349
1327- fn parse_rest < Section : UnwindSection < R > > (
1328- offset : R :: Offset ,
1329- length : R :: Offset ,
1330- format : Format ,
1331- bases : & BaseAddresses ,
1350+ fn from_prefix < Section : UnwindSection < R > > (
13321351 section : & Section ,
1333- mut rest : R ,
1352+ bases : & BaseAddresses ,
1353+ prefix : CfiEntryPrefix < R > ,
13341354 ) -> Result < CommonInformationEntry < R > > {
1355+ let mut rest = prefix. rest ;
13351356 let version = rest. read_u8 ( ) ?;
13361357
13371358 // Version 1 of `.debug_frame` corresponds to DWARF 2, and then for
@@ -1377,9 +1398,9 @@ impl<R: Reader> CommonInformationEntry<R> {
13771398 } ;
13781399
13791400 let entry = CommonInformationEntry {
1380- offset,
1381- length,
1382- format,
1401+ offset : prefix . offset ,
1402+ length : prefix . length ,
1403+ format : prefix . format ,
13831404 version,
13841405 augmentation,
13851406 address_size,
@@ -1544,11 +1565,36 @@ where
15441565 bases : & ' bases BaseAddresses ,
15451566 input : & mut R ,
15461567 ) -> Result < PartialFrameDescriptionEntry < ' bases , Section , R > > {
1547- match parse_cfi_entry ( bases, section, input) ? {
1548- Some ( CieOrFde :: Cie ( _) ) => Err ( Error :: NotFdePointer ) ,
1549- Some ( CieOrFde :: Fde ( partial) ) => Ok ( partial) ,
1550- None => Err ( Error :: NoEntryAtGivenOffset ) ,
1568+ let Some ( prefix) = parse_cfi_entry_prefix ( section, input) ? else {
1569+ return Err ( Error :: NoEntryAtGivenOffset ) ;
1570+ } ;
1571+ if Section :: is_cie ( prefix. format , prefix. cie_id_or_offset ) {
1572+ return Err ( Error :: NotCiePointer ) ;
15511573 }
1574+ Self :: from_prefix ( section, bases, prefix)
1575+ }
1576+
1577+ fn from_prefix (
1578+ section : & Section ,
1579+ bases : & ' bases BaseAddresses ,
1580+ prefix : CfiEntryPrefix < R > ,
1581+ ) -> Result < PartialFrameDescriptionEntry < ' bases , Section , R > > {
1582+ let cie_offset = R :: Offset :: from_u64 ( prefix. cie_id_or_offset ) ?;
1583+ let Some ( cie_offset) = section. resolve_cie_offset ( prefix. cie_offset_base , cie_offset)
1584+ else {
1585+ return Err ( Error :: OffsetOutOfBounds ) ;
1586+ } ;
1587+
1588+ let fde = PartialFrameDescriptionEntry {
1589+ offset : prefix. offset ,
1590+ length : prefix. length ,
1591+ format : prefix. format ,
1592+ cie_offset : cie_offset. into ( ) ,
1593+ rest : prefix. rest ,
1594+ section : section. clone ( ) ,
1595+ bases,
1596+ } ;
1597+ Ok ( fde)
15521598 }
15531599
15541600 /// Fully parse this FDE.
@@ -3778,7 +3824,7 @@ mod tests {
37783824 F : FnMut ( & Section , & BaseAddresses , O ) -> Result < CommonInformationEntry < R > > ,
37793825 {
37803826 let bases = Default :: default ( ) ;
3781- match parse_cfi_entry ( & bases , & section , input) {
3827+ match parse_cfi_entry ( & section , & bases , input) {
37823828 Ok ( Some ( CieOrFde :: Fde ( partial) ) ) => partial. parse ( get_cie) ,
37833829 Ok ( _) => Err ( Error :: NoEntryAtGivenOffset ) ,
37843830 Err ( e) => Err ( e) ,
@@ -3984,7 +4030,7 @@ mod tests {
39844030 debug_frame. set_address_size ( address_size) ;
39854031 let input = & mut EndianSlice :: new ( & section, E :: default ( ) ) ;
39864032 let bases = Default :: default ( ) ;
3987- let result = CommonInformationEntry :: parse ( & bases , & debug_frame , input) ;
4033+ let result = CommonInformationEntry :: parse ( & debug_frame , & bases , input) ;
39884034 let result = result. map ( |cie| ( * input, cie) ) . map_eof ( & section) ;
39894035 assert_eq ! ( result, expected) ;
39904036 }
@@ -4177,8 +4223,8 @@ mod tests {
41774223 let bases = Default :: default ( ) ;
41784224 assert_eq ! (
41794225 CommonInformationEntry :: parse(
4180- & bases,
41814226 & debug_frame,
4227+ & bases,
41824228 & mut EndianSlice :: new( & contents, LittleEndian )
41834229 )
41844230 . map_eof( & contents) ,
@@ -4355,7 +4401,7 @@ mod tests {
43554401
43564402 let bases = Default :: default ( ) ;
43574403 assert_eq ! (
4358- parse_cfi_entry( & bases , & debug_frame , rest) ,
4404+ parse_cfi_entry( & debug_frame , & bases , rest) ,
43594405 Ok ( Some ( CieOrFde :: Cie ( cie) ) )
43604406 ) ;
43614407 assert_eq ! ( * rest, EndianSlice :: new( & expected_rest, BigEndian ) ) ;
@@ -4401,7 +4447,7 @@ mod tests {
44014447 let rest = & mut EndianSlice :: new ( & section, BigEndian ) ;
44024448
44034449 let bases = Default :: default ( ) ;
4404- match parse_cfi_entry ( & bases , & debug_frame , rest) {
4450+ match parse_cfi_entry ( & debug_frame , & bases , rest) {
44054451 Ok ( Some ( CieOrFde :: Fde ( partial) ) ) => {
44064452 assert_eq ! ( * rest, EndianSlice :: new( & expected_rest, BigEndian ) ) ;
44074453
@@ -6740,7 +6786,7 @@ mod tests {
67406786 let input = & mut EndianSlice :: new ( & section[ buf. len ( ) ..] , LittleEndian ) ;
67416787
67426788 let bases = Default :: default ( ) ;
6743- match parse_cfi_entry ( & bases , & eh_frame , input) {
6789+ match parse_cfi_entry ( & eh_frame , & bases , input) {
67446790 Ok ( Some ( CieOrFde :: Fde ( partial) ) ) => Ok ( partial. cie_offset . 0 ) ,
67456791 Err ( e) => Err ( e) ,
67466792 otherwise => panic ! ( "Unexpected result: {:#?}" , otherwise) ,
0 commit comments