Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cfi: fix parsing of function relative pointers #402

Merged
merged 1 commit into from
Mar 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,9 @@ fn dump_eh_frame<R: Reader, W: Write>(
fde.len(),
fde.initial_address() + fde.len()
)?;
if let Some(gimli::Pointer::Direct(lsda)) = fde.lsda() {
writeln!(w, " lsda: {:#018x}", lsda)?;
}
dump_cfi_instructions(w, fde.instructions(), false, register_name)?;
writeln!(w)?;
}
Expand Down
31 changes: 13 additions & 18 deletions src/read/cfi.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::boxed::Box;
use arrayvec::ArrayVec;
use fallible_iterator::FallibleIterator;
use std::cell::RefCell;
use std::cmp::{Ord, Ordering};
use std::fmt::Debug;
use std::iter::FromIterator;
Expand Down Expand Up @@ -146,13 +145,15 @@ impl<R: Reader> EhFrameHdr<R> {
let eh_frame_ptr = parse_encoded_pointer(
eh_frame_ptr_enc,
&bases.eh_frame_hdr,
None,
address_size,
&self.0,
&mut reader,
)?;
let fde_count = parse_encoded_pointer(
fde_count_enc,
&bases.eh_frame_hdr,
None,
address_size,
&self.0,
&mut reader,
Expand Down Expand Up @@ -248,6 +249,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
let pivot = parse_encoded_pointer(
self.hdr.table_enc,
&bases.eh_frame_hdr,
None,
self.hdr.address_size,
&self.hdr.section,
&mut reader,
Expand Down Expand Up @@ -278,6 +280,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
parse_encoded_pointer(
self.hdr.table_enc,
&bases.eh_frame_hdr,
None,
self.hdr.address_size,
&self.hdr.section,
&mut reader,
Expand Down Expand Up @@ -867,10 +870,6 @@ pub struct SectionBaseAddresses {
/// For pointers in the `.eh_frame` section, this is generally the
/// global pointer, such as the address of the `.got` section.
pub data: Option<u64>,

// Unlike the others, the function base is managed internally to the parser
// as we enter and exit FDE parsing.
pub(crate) func: RefCell<Option<u64>>,
}

impl BaseAddresses {
Expand Down Expand Up @@ -966,10 +965,6 @@ where
return Ok(None);
}

// Clear any function relative base address, if one was set when parsing
// the last entry.
self.bases.eh_frame.func.borrow_mut().take();

match parse_cfi_entry(self.bases, &self.section, &mut self.input) {
Err(e) => {
self.input.empty();
Expand Down Expand Up @@ -1135,6 +1130,7 @@ impl Augmentation {
let personality = parse_encoded_pointer(
encoding,
&bases.eh_frame,
None,
address_size,
section.section(),
rest,
Expand Down Expand Up @@ -1164,6 +1160,7 @@ impl AugmentationData {
fn parse<Section, R>(
augmentation: &Augmentation,
bases: &BaseAddresses,
fde_address: u64,
address_size: u8,
section: &Section,
input: &mut R,
Expand All @@ -1185,6 +1182,7 @@ impl AugmentationData {
let lsda = parse_encoded_pointer(
encoding,
&bases.eh_frame,
Some(fde_address),
address_size,
section.section(),
rest,
Expand Down Expand Up @@ -1517,12 +1515,6 @@ impl<R: Reader> FrameDescriptionEntry<R> {
Section: UnwindSection<R>,
F: FnMut(&Section, &BaseAddresses, Section::Offset) -> Result<CommonInformationEntry<R>>,
{
{
let mut func = bases.eh_frame.func.borrow_mut();
let offset = rest.offset_from(section.section());
*func = Some(offset.into_u64());
}

let cie = get_cie(section, bases, cie_pointer)?;

let initial_segment = if cie.segment_size > 0 {
Expand All @@ -1538,6 +1530,7 @@ impl<R: Reader> FrameDescriptionEntry<R> {
Some(AugmentationData::parse(
augmentation,
bases,
initial_address,
cie.address_size,
section,
&mut rest,
Expand Down Expand Up @@ -1572,6 +1565,7 @@ impl<R: Reader> FrameDescriptionEntry<R> {
let initial_address = parse_encoded_pointer(
encoding,
&bases.eh_frame,
None,
cie.address_size,
section.section(),
input,
Expand All @@ -1585,6 +1579,7 @@ impl<R: Reader> FrameDescriptionEntry<R> {
let address_range = parse_encoded_pointer(
encoding.format(),
&bases.eh_frame,
None,
cie.address_size,
section.section(),
input,
Expand Down Expand Up @@ -6154,7 +6149,7 @@ mod tests {
initial_address: 0xfeed_face,
address_range: 9000,
augmentation: Some(AugmentationData {
lsda: Some(Pointer::Direct(1)),
lsda: Some(Pointer::Direct(0xbeef)),
}),
instructions: EndianSlice::new(&instrs, LittleEndian),
};
Expand All @@ -6171,8 +6166,8 @@ mod tests {
let section = kind.section(&section);
let input = &mut section.section().range_from(10..);

// Adjust the FDE's augmentation to be relative to the section.
fde.augmentation.as_mut().unwrap().lsda = Some(Pointer::Direct(19));
// Adjust the FDE's augmentation to be relative to the function.
fde.augmentation.as_mut().unwrap().lsda = Some(Pointer::Direct(0xfeed_face + 0xbeef));

let result = parse_fde(section, input, |_, _, _| Ok(cie.clone()));
assert_eq!(result, Ok(fde));
Expand Down
Loading