From 75996bf9aebd5cfc48376bdf06f4a0b4d7e4f8ce Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Thu, 19 Sep 2019 16:43:44 +0200 Subject: [PATCH 1/2] Support CFI augmentation without data --- src/read/cfi.rs | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 5d3e89ca0..94d08f362 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -1107,24 +1107,29 @@ impl Augmentation { "Augmentation::parse should only be called if we have an augmentation" ); - let first = augmentation_str.read_u8()?; - if first != b'z' { - return Err(Error::UnknownAugmentation); - } - let mut augmentation = Augmentation::default(); - let augmentation_length = input.read_uleb128().and_then(R::Offset::from_u64)?; - let rest = &mut input.split(augmentation_length)?; + let mut parsed_first = false; + let mut data = None; while !augmentation_str.is_empty() { let ch = augmentation_str.read_u8()?; match ch { + b'z' => { + if parsed_first { + return Err(Error::UnknownAugmentation); + } + + let augmentation_length = input.read_uleb128().and_then(R::Offset::from_u64)?; + data = Some(input.split(augmentation_length)?); + } b'L' => { + let rest = data.as_mut().ok_or(Error::UnknownAugmentation)?; let encoding = parse_pointer_encoding(rest)?; augmentation.lsda = Some(encoding); } b'P' => { + let rest = data.as_mut().ok_or(Error::UnknownAugmentation)?; let encoding = parse_pointer_encoding(rest)?; let parameters = PointerEncodingParameters { bases: &bases.eh_frame, @@ -1137,12 +1142,15 @@ impl Augmentation { augmentation.personality = Some((encoding, personality)); } b'R' => { + let rest = data.as_mut().ok_or(Error::UnknownAugmentation)?; let encoding = parse_pointer_encoding(rest)?; augmentation.fde_address_encoding = Some(encoding); } b'S' => augmentation.is_signal_trampoline = true, _ => return Err(Error::UnknownAugmentation), } + + parsed_first = true; } Ok(augmentation) @@ -6158,6 +6166,23 @@ mod tests { ); } + #[test] + fn test_augmentation_parse_just_signal_trampoline() { + let aug_str = &mut EndianSlice::new(b"S", LittleEndian); + let bases = Default::default(); + let address_size = 8; + let section = EhFrame::new(&[], NativeEndian); + let input = &mut EndianSlice::new(&[], NativeEndian); + + let mut augmentation = Augmentation::default(); + augmentation.is_signal_trampoline = true; + + assert_eq!( + Augmentation::parse(aug_str, &bases, address_size, §ion, input), + Ok(augmentation) + ); + } + #[test] fn test_augmentation_parse_unknown_part_of_z_augmentation() { // The 'Z' character is not defined by the z-style augmentation. From cef06d33b90f4038877b6c8bdf54e535c175b66a Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Thu, 19 Sep 2019 21:26:47 +0200 Subject: [PATCH 2/2] Fix test on big endian host --- src/read/cfi.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/read/cfi.rs b/src/read/cfi.rs index 94d08f362..137feb02e 100644 --- a/src/read/cfi.rs +++ b/src/read/cfi.rs @@ -6171,8 +6171,8 @@ mod tests { let aug_str = &mut EndianSlice::new(b"S", LittleEndian); let bases = Default::default(); let address_size = 8; - let section = EhFrame::new(&[], NativeEndian); - let input = &mut EndianSlice::new(&[], NativeEndian); + let section = EhFrame::new(&[], LittleEndian); + let input = &mut EndianSlice::new(&[], LittleEndian); let mut augmentation = Augmentation::default(); augmentation.is_signal_trampoline = true;