Skip to content

Commit e996d62

Browse files
authored
read/cfi: add parse_encoded_value (gimli-rs#725)
This directly parses an encoded value, instead of relying on parse_encoded_pointer to skip the pointer handling. This is preparation for changing parse_encoded_pointer to return a different address type. Also add more validation for the FDE count encoding, since it seems like the right thing to do, but this could be removed again if it is a problem.
1 parent cf9bfa1 commit e996d62

File tree

1 file changed

+18
-13
lines changed

1 file changed

+18
-13
lines changed

src/read/cfi.rs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ impl<R: Reader> EhFrameHdr<R> {
169169
if fde_count_enc == constants::DW_EH_PE_omit || table_enc == constants::DW_EH_PE_omit {
170170
fde_count = 0
171171
} else {
172-
fde_count = parse_encoded_pointer(fde_count_enc, &parameters, &mut reader)?.direct()?;
172+
if fde_count_enc != fde_count_enc.format() {
173+
return Err(Error::UnsupportedPointerEncoding);
174+
}
175+
fde_count = parse_encoded_value(fde_count_enc, &parameters, &mut reader)?;
173176
}
174177

175178
Ok(ParsedEhFrameHdr {
@@ -1716,15 +1719,10 @@ impl<R: Reader> FrameDescriptionEntry<R> {
17161719
) -> Result<(u64, u64)> {
17171720
let encoding = cie.augmentation().and_then(|a| a.fde_address_encoding);
17181721
if let Some(encoding) = encoding {
1719-
let initial_address = parse_encoded_pointer(encoding, parameters, input)?;
1720-
17211722
// Ignore indirection.
1722-
let initial_address = initial_address.pointer();
1723-
1724-
// Address ranges cannot be relative to anything, so just grab the
1725-
// data format bits from the encoding.
1726-
let address_range = parse_encoded_pointer(encoding.format(), parameters, input)?;
1727-
Ok((initial_address, address_range.pointer()))
1723+
let initial_address = parse_encoded_pointer(encoding, parameters, input)?.pointer();
1724+
let address_range = parse_encoded_value(encoding, parameters, input)?;
1725+
Ok((initial_address, address_range))
17281726
} else {
17291727
let initial_address = input.read_address(cie.address_size)?;
17301728
let address_range = input.read_address(cie.address_size)?;
@@ -3625,7 +3623,16 @@ fn parse_encoded_pointer<R: Reader>(
36253623
_ => unreachable!(),
36263624
};
36273625

3628-
let offset = match encoding.format() {
3626+
let offset = parse_encoded_value(encoding, parameters, input)?;
3627+
Ok(Pointer::new(encoding, base.wrapping_add(offset)))
3628+
}
3629+
3630+
fn parse_encoded_value<R: Reader>(
3631+
encoding: constants::DwEhPe,
3632+
parameters: &PointerEncodingParameters<'_, R>,
3633+
input: &mut R,
3634+
) -> Result<u64> {
3635+
match encoding.format() {
36293636
// Unsigned variants.
36303637
constants::DW_EH_PE_absptr => input.read_address(parameters.address_size),
36313638
constants::DW_EH_PE_uleb128 => input.read_uleb128(),
@@ -3644,9 +3651,7 @@ fn parse_encoded_pointer<R: Reader>(
36443651

36453652
// That was all of the valid encoding formats.
36463653
_ => unreachable!(),
3647-
}?;
3648-
3649-
Ok(Pointer::new(encoding, base.wrapping_add(offset)))
3654+
}
36503655
}
36513656

36523657
#[cfg(test)]

0 commit comments

Comments
 (0)