summaryrefslogtreecommitdiffstats
path: root/vendor/gimli/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gimli/src')
-rw-r--r--vendor/gimli/src/arch.rs21
-rw-r--r--vendor/gimli/src/common.rs10
-rw-r--r--vendor/gimli/src/constants.rs14
-rw-r--r--vendor/gimli/src/lib.rs4
-rw-r--r--vendor/gimli/src/read/cfi.rs226
-rw-r--r--vendor/gimli/src/read/endian_slice.rs33
-rw-r--r--vendor/gimli/src/read/line.rs2
-rw-r--r--vendor/gimli/src/read/mod.rs6
-rw-r--r--vendor/gimli/src/read/op.rs10
-rw-r--r--vendor/gimli/src/read/reader.rs2
-rw-r--r--vendor/gimli/src/read/unit.rs2
-rw-r--r--vendor/gimli/src/read/value.rs6
-rw-r--r--vendor/gimli/src/write/cfi.rs91
-rw-r--r--vendor/gimli/src/write/unit.rs8
14 files changed, 309 insertions, 126 deletions
diff --git a/vendor/gimli/src/arch.rs b/vendor/gimli/src/arch.rs
index abc872d83..adb405280 100644
--- a/vendor/gimli/src/arch.rs
+++ b/vendor/gimli/src/arch.rs
@@ -44,7 +44,8 @@ macro_rules! registers {
/// ARM architecture specific definitions.
///
-/// See [DWARF for the ARM Architecture](https://developer.arm.com/documentation/ihi0040/c/).
+/// See [DWARF for the ARM Architecture](
+/// https://github.com/ARM-software/abi-aa/blob/main/aadwarf32/aadwarf32.rst).
#[derive(Debug, Clone, Copy)]
pub struct Arm;
@@ -99,6 +100,8 @@ registers!(Arm, {
SPSR_UND = (132, "SPSR_UND"),
SPSR_SVC = (133, "SPSR_SVC"),
+ RA_AUTH_CODE = (143, "RA_AUTH_CODE"),
+
R8_USR = (144, "R8_USR"),
R9_USR = (145, "R9_USR"),
R10_USR = (146, "R10_USR"),
@@ -168,6 +171,11 @@ registers!(Arm, {
D29 = (285, "D29"),
D30 = (286, "D30"),
D31 = (287, "D31"),
+
+ TPIDRURO = (320, "TPIDRURO"),
+ TPIDRURW = (321, "TPIDRURW"),
+ TPIDPR = (322, "TPIDPR"),
+ HTPIDPR = (323, "HTPIDPR"),
},
aliases {
SP = (13, "SP"),
@@ -219,7 +227,8 @@ aliases {
/// ARM 64-bit (AArch64) architecture specific definitions.
///
-/// See [DWARF for the ARM 64-bit Architecture](https://developer.arm.com/documentation/ihi0057/b/).
+/// See [DWARF for the ARM 64-bit Architecture](
+/// https://github.com/ARM-software/abi-aa/blob/main/aadwarf64/aadwarf64.rst).
#[derive(Debug, Clone, Copy)]
pub struct AArch64;
@@ -256,6 +265,14 @@ registers!(AArch64, {
X29 = (29, "X29"),
X30 = (30, "X30"),
SP = (31, "SP"),
+ PC = (32, "PC"),
+ ELR_MODE = (33, "ELR_mode"),
+ RA_SIGN_STATE = (34, "RA_SIGN_STATE"),
+ TPIDRRO_EL0 = (35, "TPIDRRO_EL0"),
+ TPIDR_EL0 = (36, "TPIDR_EL0"),
+ TPIDR_EL1 = (37, "TPIDR_EL1"),
+ TPIDR_EL2 = (38, "TPIDR_EL2"),
+ TPIDR_EL3 = (39, "TPIDR_EL3"),
V0 = (64, "V0"),
V1 = (65, "V1"),
diff --git a/vendor/gimli/src/common.rs b/vendor/gimli/src/common.rs
index 3c8073622..fc6693d1c 100644
--- a/vendor/gimli/src/common.rs
+++ b/vendor/gimli/src/common.rs
@@ -27,6 +27,16 @@ impl Format {
}
}
+/// Which vendor extensions to support.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+#[non_exhaustive]
+pub enum Vendor {
+ /// A default set of extensions, including some common GNU extensions.
+ Default,
+ /// AAarch64 extensions.
+ AArch64,
+}
+
/// Encoding parameters that are commonly used for multiple DWARF sections.
///
/// This is intended to be small enough to pass by value.
diff --git a/vendor/gimli/src/constants.rs b/vendor/gimli/src/constants.rs
index c617f4e2e..e58050ba0 100644
--- a/vendor/gimli/src/constants.rs
+++ b/vendor/gimli/src/constants.rs
@@ -56,7 +56,10 @@ use core::fmt;
// }
// }
macro_rules! dw {
- ($(#[$meta:meta])* $struct_name:ident($struct_type:ty) { $($name:ident = $val:expr),+ $(,)? }) => {
+ ($(#[$meta:meta])* $struct_name:ident($struct_type:ty)
+ { $($name:ident = $val:expr),+ $(,)? }
+ $(, aliases { $($alias_name:ident = $alias_val:expr),+ $(,)? })?
+ ) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct $struct_name(pub $struct_type);
@@ -64,6 +67,9 @@ macro_rules! dw {
$(
pub const $name: $struct_name = $struct_name($val);
)+
+ $($(
+ pub const $alias_name: $struct_name = $struct_name($alias_val);
+ )+)*
impl $struct_name {
pub fn static_string(&self) -> Option<&'static str> {
@@ -182,6 +188,9 @@ DwCfa(u8) {
DW_CFA_GNU_window_save = 0x2d,
DW_CFA_GNU_args_size = 0x2e,
DW_CFA_GNU_negative_offset_extended = 0x2f,
+},
+aliases {
+ DW_CFA_AARCH64_negate_ra_state = 0x2d,
});
dw!(
@@ -529,6 +538,7 @@ DwAt(u16) {
DW_AT_GNU_all_call_sites = 0x2117,
DW_AT_GNU_all_source_call_sites = 0x2118,
DW_AT_GNU_macros = 0x2119,
+ DW_AT_GNU_deleted = 0x211a,
// Extensions for Fission proposal.
DW_AT_GNU_dwo_name = 0x2130,
@@ -1276,7 +1286,7 @@ dw!(
/// format of the pointer, the upper four bits describe how the encoding should
/// be applied.
///
-/// Defined in https://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html
+/// Defined in `<https://refspecs.linuxfoundation.org/LSB_4.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html>`
DwEhPe(u8) {
// Format of pointer encoding.
diff --git a/vendor/gimli/src/lib.rs b/vendor/gimli/src/lib.rs
index db30375aa..5dea34439 100644
--- a/vendor/gimli/src/lib.rs
+++ b/vendor/gimli/src/lib.rs
@@ -48,7 +48,7 @@ extern crate alloc;
#[macro_use]
extern crate std;
-#[cfg(feature = "stable_deref_trait")]
+#[cfg(feature = "endian-reader")]
pub use stable_deref_trait::{CloneStableDeref, StableDeref};
mod common;
@@ -62,7 +62,7 @@ pub mod constants;
pub use crate::constants::*;
mod endianity;
-pub use crate::endianity::{BigEndian, Endianity, LittleEndian, NativeEndian, RunTimeEndian};
+pub use crate::endianity::*;
pub mod leb128;
diff --git a/vendor/gimli/src/read/cfi.rs b/vendor/gimli/src/read/cfi.rs
index 5e9befac1..6ac019f10 100644
--- a/vendor/gimli/src/read/cfi.rs
+++ b/vendor/gimli/src/read/cfi.rs
@@ -8,7 +8,9 @@ use core::mem;
use core::num::Wrapping;
use super::util::{ArrayLike, ArrayVec};
-use crate::common::{DebugFrameOffset, EhFrameOffset, Encoding, Format, Register, SectionId};
+use crate::common::{
+ DebugFrameOffset, EhFrameOffset, Encoding, Format, Register, SectionId, Vendor,
+};
use crate::constants::{self, DwEhPe};
use crate::endianity::Endianity;
use crate::read::{
@@ -34,6 +36,7 @@ pub struct DebugFrame<R: Reader> {
section: R,
address_size: u8,
segment_size: u8,
+ vendor: Vendor,
}
impl<R: Reader> DebugFrame<R> {
@@ -52,6 +55,13 @@ impl<R: Reader> DebugFrame<R> {
pub fn set_segment_size(&mut self, segment_size: u8) {
self.segment_size = segment_size
}
+
+ /// Set the vendor extensions to use.
+ ///
+ /// This defaults to `Vendor::Default`.
+ pub fn set_vendor(&mut self, vendor: Vendor) {
+ self.vendor = vendor;
+ }
}
impl<'input, Endian> DebugFrame<EndianSlice<'input, Endian>>
@@ -95,6 +105,7 @@ impl<R: Reader> From<R> for DebugFrame<R> {
section,
address_size: mem::size_of::<usize>() as u8,
segment_size: 0,
+ vendor: Vendor::Default,
}
}
}
@@ -158,11 +169,7 @@ impl<R: Reader> EhFrameHdr<R> {
if fde_count_enc == constants::DW_EH_PE_omit || table_enc == constants::DW_EH_PE_omit {
fde_count = 0
} else {
- let ptr = parse_encoded_pointer(fde_count_enc, &parameters, &mut reader)?;
- fde_count = match ptr {
- Pointer::Direct(c) => c,
- Pointer::Indirect(_) => return Err(Error::UnsupportedPointerEncoding),
- }
+ fde_count = parse_encoded_pointer(fde_count_enc, &parameters, &mut reader)?.direct()?;
}
Ok(ParsedEhFrameHdr {
@@ -348,11 +355,8 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
let head = reader.split(R::Offset::from_u64((len / 2) * row_size)?)?;
let tail = reader.clone();
- let pivot = parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut reader)?;
- let pivot = match pivot {
- Pointer::Direct(x) => x,
- Pointer::Indirect(_) => return Err(Error::UnsupportedPointerEncoding),
- };
+ let pivot =
+ parse_encoded_pointer(self.hdr.table_enc, &parameters, &mut reader)?.direct()?;
match pivot.cmp(&address) {
Ordering::Equal => {
@@ -379,15 +383,8 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
///
/// This does not support indirect pointers.
pub fn pointer_to_offset(&self, ptr: Pointer) -> Result<EhFrameOffset<R::Offset>> {
- let ptr = match ptr {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- };
-
- let eh_frame_ptr = match self.hdr.eh_frame_ptr() {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- };
+ let ptr = ptr.direct()?;
+ let eh_frame_ptr = self.hdr.eh_frame_ptr().direct()?;
// Calculate the offset in the EhFrame section
R::Offset::from_u64(ptr - eh_frame_ptr).map(EhFrameOffset)
@@ -496,6 +493,7 @@ impl<'a, R: Reader + 'a> EhHdrTable<'a, R> {
pub struct EhFrame<R: Reader> {
section: R,
address_size: u8,
+ vendor: Vendor,
}
impl<R: Reader> EhFrame<R> {
@@ -505,6 +503,13 @@ impl<R: Reader> EhFrame<R> {
pub fn set_address_size(&mut self, address_size: u8) {
self.address_size = address_size
}
+
+ /// Set the vendor extensions to use.
+ ///
+ /// This defaults to `Vendor::Default`.
+ pub fn set_vendor(&mut self, vendor: Vendor) {
+ self.vendor = vendor;
+ }
}
impl<'input, Endian> EhFrame<EndianSlice<'input, Endian>>
@@ -547,6 +552,7 @@ impl<R: Reader> From<R> for EhFrame<R> {
EhFrame {
section,
address_size: mem::size_of::<usize>() as u8,
+ vendor: Vendor::Default,
}
}
}
@@ -627,6 +633,9 @@ pub trait _UnwindSectionPrivate<R: Reader> {
/// The segment size to use if `has_address_and_segment_sizes` returns false.
fn segment_size(&self) -> u8;
+
+ /// The vendor extensions to use.
+ fn vendor(&self) -> Vendor;
}
/// A section holding unwind information: either `.debug_frame` or
@@ -822,6 +831,10 @@ impl<R: Reader> _UnwindSectionPrivate<R> for DebugFrame<R> {
fn segment_size(&self) -> u8 {
self.segment_size
}
+
+ fn vendor(&self) -> Vendor {
+ self.vendor
+ }
}
impl<R: Reader> UnwindSection<R> for DebugFrame<R> {
@@ -862,6 +875,10 @@ impl<R: Reader> _UnwindSectionPrivate<R> for EhFrame<R> {
fn segment_size(&self) -> u8 {
0
}
+
+ fn vendor(&self) -> Vendor {
+ self.vendor
+ }
}
impl<R: Reader> UnwindSection<R> for EhFrame<R> {
@@ -1435,6 +1452,7 @@ impl<R: Reader> CommonInformationEntry<R> {
address_size: self.address_size,
section: section.section(),
},
+ vendor: section.vendor(),
}
}
@@ -1683,12 +1701,12 @@ impl<R: Reader> FrameDescriptionEntry<R> {
let initial_address = parse_encoded_pointer(encoding, parameters, input)?;
// Ignore indirection.
- let initial_address = initial_address.into();
+ let initial_address = initial_address.pointer();
// Address ranges cannot be relative to anything, so just grab the
// data format bits from the encoding.
let address_range = parse_encoded_pointer(encoding.format(), parameters, input)?;
- Ok((initial_address, address_range.into()))
+ Ok((initial_address, address_range.pointer()))
} else {
let initial_address = input.read_address(cie.address_size)?;
let address_range = input.read_address(cie.address_size)?;
@@ -1778,6 +1796,7 @@ impl<R: Reader> FrameDescriptionEntry<R> {
address_size: self.cie.address_size,
section: section.section(),
},
+ vendor: section.vendor(),
}
}
@@ -2414,6 +2433,18 @@ impl<'a, 'ctx, R: Reader, A: UnwindContextStorage<R>> UnwindTable<'a, 'ctx, R, A
self.ctx.row_mut().saved_args_size = size;
}
+ // AArch64 extension.
+ NegateRaState => {
+ let register = crate::AArch64::RA_SIGN_STATE;
+ let value = match self.ctx.row().register(register) {
+ RegisterRule::Undefined => 0,
+ RegisterRule::Constant(value) => value,
+ _ => return Err(Error::CfiInstructionInInvalidContext),
+ };
+ self.ctx
+ .set_register_rule(register, RegisterRule::Constant(value ^ 1))?;
+ }
+
// No operation.
Nop => {}
};
@@ -2783,6 +2814,7 @@ impl<R: Reader> CfaRule<R> {
/// has been saved and the rule to find the value for the register in the
/// previous frame."
#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
pub enum RegisterRule<R: Reader> {
/// > A register that has this rule has no recoverable value in the previous
/// > frame. (By convention, it is not preserved by a callee.)
@@ -2815,6 +2847,9 @@ pub enum RegisterRule<R: Reader> {
/// "The rule is defined externally to this specification by the augmenter."
Architectural,
+
+ /// This is a pseudo-register with a constant value.
+ Constant(u64),
}
impl<R: Reader> RegisterRule<R> {
@@ -2825,6 +2860,7 @@ impl<R: Reader> RegisterRule<R> {
/// A parsed call frame instruction.
#[derive(Clone, Debug, PartialEq, Eq)]
+#[non_exhaustive]
pub enum CallFrameInstruction<R: Reader> {
// 6.4.2.1 Row Creation Methods
/// > 1. DW_CFA_set_loc
@@ -3102,6 +3138,17 @@ pub enum CallFrameInstruction<R: Reader> {
size: u64,
},
+ /// > DW_CFA_AARCH64_negate_ra_state
+ /// >
+ /// > AArch64 Extension
+ /// >
+ /// > The DW_CFA_AARCH64_negate_ra_state operation negates bit[0] of the
+ /// > RA_SIGN_STATE pseudo-register. It does not take any operands. The
+ /// > DW_CFA_AARCH64_negate_ra_state must not be mixed with other DWARF Register
+ /// > Rule Instructions on the RA_SIGN_STATE pseudo-register in one Common
+ /// > Information Entry (CIE) and Frame Descriptor Entry (FDE) program sequence.
+ NegateRaState,
+
// 6.4.2.5 Padding Instruction
/// > 1. DW_CFA_nop
/// >
@@ -3118,6 +3165,7 @@ impl<R: Reader> CallFrameInstruction<R> {
input: &mut R,
address_encoding: Option<DwEhPe>,
parameters: &PointerEncodingParameters<R>,
+ vendor: Vendor,
) -> Result<CallFrameInstruction<R>> {
let instruction = input.read_u8()?;
let high_bits = instruction & CFI_INSTRUCTION_HIGH_BITS_MASK;
@@ -3151,10 +3199,7 @@ impl<R: Reader> CallFrameInstruction<R> {
constants::DW_CFA_set_loc => {
let address = if let Some(encoding) = address_encoding {
- match parse_encoded_pointer(encoding, parameters, input)? {
- Pointer::Direct(x) => x,
- _ => return Err(Error::UnsupportedPointerEncoding),
- }
+ parse_encoded_pointer(encoding, parameters, input)?.direct()?
} else {
input.read_address(parameters.address_size)?
};
@@ -3309,6 +3354,10 @@ impl<R: Reader> CallFrameInstruction<R> {
Ok(CallFrameInstruction::ArgsSize { size })
}
+ constants::DW_CFA_AARCH64_negate_ra_state if vendor == Vendor::AArch64 => {
+ Ok(CallFrameInstruction::NegateRaState)
+ }
+
otherwise => Err(Error::UnknownCallFrameInstruction(otherwise)),
}
}
@@ -3323,6 +3372,7 @@ pub struct CallFrameInstructionIter<'a, R: Reader> {
input: R,
address_encoding: Option<constants::DwEhPe>,
parameters: PointerEncodingParameters<'a, R>,
+ vendor: Vendor,
}
impl<'a, R: Reader> CallFrameInstructionIter<'a, R> {
@@ -3332,8 +3382,12 @@ impl<'a, R: Reader> CallFrameInstructionIter<'a, R> {
return Ok(None);
}
- match CallFrameInstruction::parse(&mut self.input, self.address_encoding, &self.parameters)
- {
+ match CallFrameInstruction::parse(
+ &mut self.input,
+ self.address_encoding,
+ &self.parameters,
+ self.vendor,
+ ) {
Ok(instruction) => Ok(Some(instruction)),
Err(e) => {
self.input.empty();
@@ -3389,15 +3443,6 @@ impl Default for Pointer {
}
}
-impl From<Pointer> for u64 {
- #[inline]
- fn from(p: Pointer) -> u64 {
- match p {
- Pointer::Direct(p) | Pointer::Indirect(p) => p,
- }
- }
-}
-
impl Pointer {
#[inline]
fn new(encoding: constants::DwEhPe, address: u64) -> Pointer {
@@ -3407,6 +3452,23 @@ impl Pointer {
Pointer::Direct(address)
}
}
+
+ /// Return the direct pointer value.
+ #[inline]
+ pub fn direct(self) -> Result<u64> {
+ match self {
+ Pointer::Direct(p) => Ok(p),
+ Pointer::Indirect(_) => Err(Error::UnsupportedPointerEncoding),
+ }
+ }
+
+ /// Return the pointer value, discarding indirectness information.
+ #[inline]
+ pub fn pointer(self) -> u64 {
+ match self {
+ Pointer::Direct(p) | Pointer::Indirect(p) => p,
+ }
+ }
}
#[derive(Clone, Debug)]
@@ -3637,7 +3699,7 @@ mod tests {
.uleb(cie.code_alignment_factor)
.sleb(cie.data_alignment_factor)
.uleb(cie.return_address_register.0.into())
- .append_bytes(cie.initial_instructions.into())
+ .append_bytes(cie.initial_instructions.slice())
.mark(&end);
cie.length = (&end - &start) as usize;
@@ -3714,11 +3776,11 @@ mod tests {
let section = section.uleb(u64::from(fde.cie.address_size));
match fde.cie.address_size {
4 => section.D32({
- let x: u64 = lsda.into();
+ let x: u64 = lsda.pointer();
x as u32
}),
8 => section.D64({
- let x: u64 = lsda.into();
+ let x: u64 = lsda.pointer();
x
}),
x => panic!("Unsupported address size: {}", x),
@@ -3732,7 +3794,7 @@ mod tests {
section
};
- let section = section.append_bytes(fde.instructions.into()).mark(&end);
+ let section = section.append_bytes(fde.instructions.slice()).mark(&end);
fde.length = (&end - &start) as usize;
length.set_const(fde.length as u64);
@@ -4445,7 +4507,7 @@ mod tests {
address_size,
section: &R::default(),
};
- CallFrameInstruction::parse(input, None, parameters)
+ CallFrameInstruction::parse(input, None, parameters, Vendor::Default)
}
#[test]
@@ -4558,7 +4620,12 @@ mod tests {
section: &EndianSlice::new(&[], LittleEndian),
};
assert_eq!(
- CallFrameInstruction::parse(input, Some(constants::DW_EH_PE_textrel), parameters),
+ CallFrameInstruction::parse(
+ input,
+ Some(constants::DW_EH_PE_textrel),
+ parameters,
+ Vendor::Default
+ ),
Ok(CallFrameInstruction::SetLoc {
address: expected_addr,
})
@@ -5018,6 +5085,27 @@ mod tests {
}
#[test]
+ fn test_parse_cfi_instruction_negate_ra_state() {
+ let expected_rest = [1, 2, 3, 4];
+ let section = Section::with_endian(Endian::Little)
+ .D8(constants::DW_CFA_AARCH64_negate_ra_state.0)
+ .append_bytes(&expected_rest);
+ let contents = section.get_contents().unwrap();
+ let input = &mut EndianSlice::new(&contents, LittleEndian);
+ let parameters = &PointerEncodingParameters {
+ bases: &SectionBaseAddresses::default(),
+ func_base: None,
+ address_size: 8,
+ section: &EndianSlice::default(),
+ };
+ assert_eq!(
+ CallFrameInstruction::parse(input, None, parameters, Vendor::AArch64),
+ Ok(CallFrameInstruction::NegateRaState)
+ );
+ assert_eq!(*input, EndianSlice::new(&expected_rest, LittleEndian));
+ }
+
+ #[test]
fn test_parse_cfi_instruction_unknown_instruction() {
let expected_rest = [1, 2, 3, 4];
let unknown_instr = constants::DwCfa(0b0011_1111);
@@ -5065,6 +5153,7 @@ mod tests {
input,
address_encoding: None,
parameters,
+ vendor: Vendor::Default,
};
assert_eq!(
@@ -5102,6 +5191,7 @@ mod tests {
input,
address_encoding: None,
parameters,
+ vendor: Vendor::Default,
};
assert_eq!(
@@ -5580,6 +5670,55 @@ mod tests {
}
#[test]
+ fn test_eval_negate_ra_state() {
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(crate::AArch64::RA_SIGN_STATE, RegisterRule::Constant(1))
+ .unwrap();
+ let instructions = [(Ok(false), CallFrameInstruction::NegateRaState)];
+ assert_eval(ctx, expected, cie, None, instructions);
+
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(crate::AArch64::RA_SIGN_STATE, RegisterRule::Constant(0))
+ .unwrap();
+ let instructions = [
+ (Ok(false), CallFrameInstruction::NegateRaState),
+ (Ok(false), CallFrameInstruction::NegateRaState),
+ ];
+ assert_eval(ctx, expected, cie, None, instructions);
+
+ // NegateRaState can't be used with other instructions.
+ let cie = make_test_cie();
+ let ctx = UnwindContext::new();
+ let mut expected = ctx.clone();
+ expected
+ .set_register_rule(
+ crate::AArch64::RA_SIGN_STATE,
+ RegisterRule::Offset(cie.data_alignment_factor as i64),
+ )
+ .unwrap();
+ let instructions = [
+ (
+ Ok(false),
+ CallFrameInstruction::Offset {
+ register: crate::AArch64::RA_SIGN_STATE,
+ factored_offset: 1,
+ },
+ ),
+ (
+ Err(Error::CfiInstructionInInvalidContext),
+ CallFrameInstruction::NegateRaState,
+ ),
+ ];
+ assert_eval(ctx, expected, cie, None, instructions);
+ }
+
+ #[test]
fn test_eval_nop() {
let cie = make_test_cie();
let ctx = UnwindContext::new();
@@ -6262,7 +6401,6 @@ mod tests {
section.start().set_const(0);
let section = section.get_contents().unwrap();
- let section = EndianSlice::new(&section, LittleEndian);
let eh_frame = kind.section(&section);
// Setup eh_frame_hdr
diff --git a/vendor/gimli/src/read/endian_slice.rs b/vendor/gimli/src/read/endian_slice.rs
index d0fd67c0b..fbf5cbb79 100644
--- a/vendor/gimli/src/read/endian_slice.rs
+++ b/vendor/gimli/src/read/endian_slice.rs
@@ -4,7 +4,7 @@
use alloc::borrow::Cow;
#[cfg(feature = "read")]
use alloc::string::String;
-use core::ops::{Deref, Index, Range, RangeFrom, RangeTo};
+use core::ops::{Deref, Range, RangeFrom, RangeTo};
use core::str;
use crate::endianity::Endianity;
@@ -57,7 +57,7 @@ where
(self.range_to(..idx), self.range_from(idx..))
}
- /// Find the first occurence of a byte in the slice, and return its index.
+ /// Find the first occurrence of a byte in the slice, and return its index.
#[inline]
pub fn find(&self, byte: u8) -> Option<usize> {
self.slice.iter().position(|ch| *ch == byte)
@@ -167,26 +167,6 @@ where
}
}
-impl<'input, Endian> Index<usize> for EndianSlice<'input, Endian>
-where
- Endian: Endianity,
-{
- type Output = u8;
- fn index(&self, idx: usize) -> &Self::Output {
- &self.slice[idx]
- }
-}
-
-impl<'input, Endian> Index<RangeFrom<usize>> for EndianSlice<'input, Endian>
-where
- Endian: Endianity,
-{
- type Output = [u8];
- fn index(&self, idx: RangeFrom<usize>) -> &Self::Output {
- &self.slice[idx]
- }
-}
-
impl<'input, Endian> Deref for EndianSlice<'input, Endian>
where
Endian: Endianity,
@@ -197,15 +177,6 @@ where
}
}
-impl<'input, Endian> From<EndianSlice<'input, Endian>> for &'input [u8]
-where
- Endian: Endianity,
-{
- fn from(endian_slice: EndianSlice<'input, Endian>) -> &'input [u8] {
- endian_slice.slice
- }
-}
-
impl<'input, Endian> Reader for EndianSlice<'input, Endian>
where
Endian: Endianity,
diff --git a/vendor/gimli/src/read/line.rs b/vendor/gimli/src/read/line.rs
index 65400a99e..47eae92e6 100644
--- a/vendor/gimli/src/read/line.rs
+++ b/vendor/gimli/src/read/line.rs
@@ -2327,7 +2327,7 @@ mod tests {
fn test_parse_unknown_standard_opcode_many_args() {
let input = [OPCODE_BASE, 1, 2, 3];
let input = EndianSlice::new(&input, LittleEndian);
- let args = EndianSlice::new(&input[1..], LittleEndian);
+ let args = input.range_from(1..);
let mut standard_opcode_lengths = Vec::new();
let mut header = make_test_header(input);
standard_opcode_lengths.extend(header.standard_opcode_lengths.slice());
diff --git a/vendor/gimli/src/read/mod.rs b/vendor/gimli/src/read/mod.rs
index 82b79502d..22a8e9fbe 100644
--- a/vendor/gimli/src/read/mod.rs
+++ b/vendor/gimli/src/read/mod.rs
@@ -41,10 +41,10 @@
//!
//! Full example programs:
//!
-//! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/examples/simple.rs)
+//! * [A simple parser](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/simple.rs)
//!
//! * [A `dwarfdump`
-//! clone](https://github.com/gimli-rs/gimli/blob/master/examples/dwarfdump.rs)
+//! clone](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarfdump.rs)
//!
//! * [An `addr2line` clone](https://github.com/gimli-rs/addr2line)
//!
@@ -55,7 +55,7 @@
//! compilers used to create each compilation unit within a shared library or
//! executable (via `DW_AT_producer`)
//!
-//! * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/examples/dwarf-validate.rs),
+//! * [`dwarf-validate`](https://github.com/gimli-rs/gimli/blob/master/crates/examples/src/bin/dwarf-validate.rs),
//! a program to validate the integrity of some DWARF and its references
//! between sections and compilation units.
//!
diff --git a/vendor/gimli/src/read/op.rs b/vendor/gimli/src/read/op.rs
index 670d1ad21..0b6a71b48 100644
--- a/vendor/gimli/src/read/op.rs
+++ b/vendor/gimli/src/read/op.rs
@@ -985,6 +985,16 @@ impl<R: Reader> OperationIter<R> {
}
}
+#[cfg(feature = "fallible-iterator")]
+impl<R: Reader> fallible_iterator::FallibleIterator for OperationIter<R> {
+ type Item = Operation<R>;
+ type Error = Error;
+
+ fn next(&mut self) -> ::core::result::Result<Option<Self::Item>, Self::Error> {
+ OperationIter::next(self)
+ }
+}
+
/// Specification of what storage should be used for [`Evaluation`].
///
#[cfg_attr(
diff --git a/vendor/gimli/src/read/reader.rs b/vendor/gimli/src/read/reader.rs
index 1bb748bb8..e7dd4772c 100644
--- a/vendor/gimli/src/read/reader.rs
+++ b/vendor/gimli/src/read/reader.rs
@@ -245,7 +245,7 @@ pub trait Reader: Debug + Clone {
/// it is associated with this reader.
fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<Self::Offset>;
- /// Find the index of the first occurence of the given byte.
+ /// Find the index of the first occurrence of the given byte.
/// The offset of the reader is not changed.
fn find(&self, byte: u8) -> Result<Self::Offset>;
diff --git a/vendor/gimli/src/read/unit.rs b/vendor/gimli/src/read/unit.rs
index 672435330..d799f0f07 100644
--- a/vendor/gimli/src/read/unit.rs
+++ b/vendor/gimli/src/read/unit.rs
@@ -3295,7 +3295,7 @@ mod tests {
}
};
- let section = section.append_bytes(unit.entries_buf.into()).mark(&end);
+ let section = section.append_bytes(unit.entries_buf.slice()).mark(&end);
unit.unit_length = (&end - &start) as usize;
length.set_const(unit.unit_length as u64);
diff --git a/vendor/gimli/src/read/value.rs b/vendor/gimli/src/read/value.rs
index 6f43ebb26..77b08eda5 100644
--- a/vendor/gimli/src/read/value.rs
+++ b/vendor/gimli/src/read/value.rs
@@ -367,7 +367,7 @@ impl Value {
Value::I64(value) => Value::I64(value.wrapping_neg()),
Value::F32(value) => Value::F32(-value),
Value::F64(value) => Value::F64(-value),
- // It's unclear if these should implicity convert to a signed value.
+ // It's unclear if these should implicitly convert to a signed value.
// For now, we don't support them.
Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
return Err(Error::UnsupportedTypeOperation);
@@ -664,7 +664,7 @@ impl Value {
Value::U16(v1) => Value::U16(if v2 >= 16 { 0 } else { v1 >> v2 }),
Value::U32(v1) => Value::U32(if v2 >= 32 { 0 } else { v1 >> v2 }),
Value::U64(v1) => Value::U64(if v2 >= 64 { 0 } else { v1 >> v2 }),
- // It's unclear if signed values should implicity convert to an unsigned value.
+ // It's unclear if signed values should implicitly convert to an unsigned value.
// For now, we don't support them.
Value::I8(_) | Value::I16(_) | Value::I32(_) | Value::I64(_) => {
return Err(Error::UnsupportedTypeOperation);
@@ -737,7 +737,7 @@ impl Value {
} else {
v1 >> v2
}),
- // It's unclear if unsigned values should implicity convert to a signed value.
+ // It's unclear if unsigned values should implicitly convert to a signed value.
// For now, we don't support them.
Value::U8(_) | Value::U16(_) | Value::U32(_) | Value::U64(_) => {
return Err(Error::UnsupportedTypeOperation);
diff --git a/vendor/gimli/src/write/cfi.rs b/vendor/gimli/src/write/cfi.rs
index 718cb69ad..5e108f15a 100644
--- a/vendor/gimli/src/write/cfi.rs
+++ b/vendor/gimli/src/write/cfi.rs
@@ -377,6 +377,7 @@ impl FrameDescriptionEntry {
///
/// This may be a CFA definition, a register rule, or some other directive.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[non_exhaustive]
pub enum CallFrameInstruction {
/// Define the CFA rule to use the provided register and offset.
Cfa(Register, i32),
@@ -410,6 +411,9 @@ pub enum CallFrameInstruction {
RestoreState,
/// The size of the arguments that have been pushed onto the stack.
ArgsSize(u32),
+
+ /// AAarch64 extension: negate the `RA_SIGN_STATE` pseudo-register.
+ NegateRaState,
}
impl CallFrameInstruction {
@@ -523,6 +527,9 @@ impl CallFrameInstruction {
w.write_u8(constants::DW_CFA_GNU_args_size.0)?;
w.write_uleb128(size.into())?;
}
+ CallFrameInstruction::NegateRaState => {
+ w.write_u8(constants::DW_CFA_AARCH64_negate_ra_state.0)?;
+ }
}
Ok(())
}
@@ -834,6 +841,7 @@ pub(crate) mod convert {
read::CallFrameInstruction::ArgsSize { size } => {
CallFrameInstruction::ArgsSize(size as u32)
}
+ read::CallFrameInstruction::NegateRaState => CallFrameInstruction::NegateRaState,
read::CallFrameInstruction::Nop => return Ok(None),
}))
}
@@ -847,7 +855,7 @@ mod tests {
use crate::arch::X86_64;
use crate::read;
use crate::write::EndianVec;
- use crate::LittleEndian;
+ use crate::{LittleEndian, Vendor};
#[test]
fn test_frame_table() {
@@ -980,44 +988,61 @@ mod tests {
(28 + 0x20280, CallFrameInstruction::ArgsSize(23)),
];
+ let fde_instructions_aarch64 = [(0, CallFrameInstruction::NegateRaState)];
+
for &version in &[1, 3, 4] {
for &address_size in &[4, 8] {
- for &format in &[Format::Dwarf32, Format::Dwarf64] {
- let encoding = Encoding {
- format,
- version,
- address_size,
- };
- let mut frames = FrameTable::default();
-
- let mut cie = CommonInformationEntry::new(encoding, 2, 8, X86_64::RA);
- for i in &cie_instructions {
- cie.add_instruction(i.clone());
- }
- let cie_id = frames.add_cie(cie);
+ for &vendor in &[Vendor::Default, Vendor::AArch64] {
+ for &format in &[Format::Dwarf32, Format::Dwarf64] {
+ let encoding = Encoding {
+ format,
+ version,
+ address_size,
+ };
+ let mut frames = FrameTable::default();
+
+ let mut cie = CommonInformationEntry::new(encoding, 2, 8, X86_64::RA);
+ for i in &cie_instructions {
+ cie.add_instruction(i.clone());
+ }
+ let cie_id = frames.add_cie(cie);
- let mut fde = FrameDescriptionEntry::new(Address::Constant(0x1000), 0x10);
- for (o, i) in &fde_instructions {
- fde.add_instruction(*o, i.clone());
- }
- frames.add_fde(cie_id, fde);
+ let mut fde = FrameDescriptionEntry::new(Address::Constant(0x1000), 0x10);
+ for (o, i) in &fde_instructions {
+ fde.add_instruction(*o, i.clone());
+ }
+ frames.add_fde(cie_id, fde);
+
+ if vendor == Vendor::AArch64 {
+ let mut fde =
+ FrameDescriptionEntry::new(Address::Constant(0x2000), 0x10);
+ for (o, i) in &fde_instructions_aarch64 {
+ fde.add_instruction(*o, i.clone());
+ }
+ frames.add_fde(cie_id, fde);
+ }
- let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian));
- frames.write_debug_frame(&mut debug_frame).unwrap();
+ let mut debug_frame = DebugFrame::from(EndianVec::new(LittleEndian));
+ frames.write_debug_frame(&mut debug_frame).unwrap();
- let mut read_debug_frame =
- read::DebugFrame::new(debug_frame.slice(), LittleEndian);
- read_debug_frame.set_address_size(address_size);
- let frames = FrameTable::from(&read_debug_frame, &|address| {
- Some(Address::Constant(address))
- })
- .unwrap();
+ let mut read_debug_frame =
+ read::DebugFrame::new(debug_frame.slice(), LittleEndian);
+ read_debug_frame.set_address_size(address_size);
+ read_debug_frame.set_vendor(vendor);
+ let frames = FrameTable::from(&read_debug_frame, &|address| {
+ Some(Address::Constant(address))
+ })
+ .unwrap();
- assert_eq!(
- &frames.cies.get_index(0).unwrap().instructions,
- &cie_instructions
- );
- assert_eq!(&frames.fdes[0].1.instructions, &fde_instructions);
+ assert_eq!(
+ &frames.cies.get_index(0).unwrap().instructions,
+ &cie_instructions
+ );
+ assert_eq!(&frames.fdes[0].1.instructions, &fde_instructions);
+ if vendor == Vendor::AArch64 {
+ assert_eq!(&frames.fdes[1].1.instructions, &fde_instructions_aarch64);
+ }
+ }
}
}
}
diff --git a/vendor/gimli/src/write/unit.rs b/vendor/gimli/src/write/unit.rs
index 23027bc2c..dd8ba6748 100644
--- a/vendor/gimli/src/write/unit.rs
+++ b/vendor/gimli/src/write/unit.rs
@@ -4,7 +4,7 @@ use std::{slice, usize};
use crate::common::{
DebugAbbrevOffset, DebugInfoOffset, DebugLineOffset, DebugMacinfoOffset, DebugMacroOffset,
- DebugStrOffset, DebugTypeSignature, DwoId, Encoding, Format, SectionId,
+ DebugStrOffset, DebugTypeSignature, Encoding, Format, SectionId,
};
use crate::constants;
use crate::leb128::write::{sleb128_size, uleb128_size};
@@ -159,7 +159,7 @@ pub struct Unit {
// - entries can be added in any order
// - entries have a fixed id
// - able to quickly lookup an entry from its id
- // Limitations of current implemention:
+ // Limitations of current implementation:
// - mutable iteration of children is messy due to borrow checker
entries: Vec<DebuggingInformationEntry>,
/// The index of the root entry in entries.
@@ -1378,6 +1378,7 @@ pub struct DebugInfoOffsets {
impl DebugInfoOffsets {
#[cfg(test)]
+ #[cfg(feature = "read")]
pub(crate) fn unit_offsets(&self, unit: UnitId) -> &UnitOffsets {
debug_assert_eq!(self.base_id, unit.base_id);
&self.units[unit.index]
@@ -1408,6 +1409,7 @@ pub(crate) struct UnitOffsets {
impl UnitOffsets {
#[cfg(test)]
+ #[cfg(feature = "read")]
fn none() -> Self {
UnitOffsets {
base_id: BaseId::default(),
@@ -1471,7 +1473,7 @@ pub(crate) struct DebugInfoReference {
#[cfg(feature = "read")]
pub(crate) mod convert {
use super::*;
- use crate::common::UnitSectionOffset;
+ use crate::common::{DwoId, UnitSectionOffset};
use crate::read::{self, Reader};
use crate::write::{self, ConvertError, ConvertResult, LocationList, RangeList};
use std::collections::HashMap;