Skip to content

Commit 3401064

Browse files
authored
Merge pull request gimli-rs#419 from philipc/write-eh-frame
write/cfi: implement .eh_frame
2 parents 70c3730 + e09f242 commit 3401064

File tree

10 files changed

+453
-186
lines changed

10 files changed

+453
-186
lines changed

examples/dwarfdump.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,17 @@ fn dump_eh_frame<R: Reader, W: Write>(
604604
writeln!(w, " code_align: {}", cie.code_alignment_factor())?;
605605
writeln!(w, " data_align: {}", cie.data_alignment_factor())?;
606606
writeln!(w, " ra_register: {:#x}", cie.return_address_register().0)?;
607-
// TODO: aug_arg
607+
if let Some(encoding) = cie.lsda_encoding() {
608+
writeln!(w, " lsda_encoding: {:#02x}", encoding.0)?;
609+
}
610+
if let Some((encoding, personality)) = cie.personality_with_encoding() {
611+
write!(w, " personality: {:#02x} ", encoding.0)?;
612+
dump_pointer(w, personality)?;
613+
writeln!(w)?;
614+
}
615+
if let Some(encoding) = cie.fde_address_encoding() {
616+
writeln!(w, " fde_encoding: {:#02x}", encoding.0)?;
617+
}
608618
dump_cfi_instructions(w, cie.instructions(eh_frame, bases), true, register_name)?;
609619
writeln!(w)?;
610620
}
@@ -629,8 +639,10 @@ fn dump_eh_frame<R: Reader, W: Write>(
629639
fde.len(),
630640
fde.initial_address() + fde.len()
631641
)?;
632-
if let Some(gimli::Pointer::Direct(lsda)) = fde.lsda() {
633-
writeln!(w, " lsda: {:#018x}", lsda)?;
642+
if let Some(lsda) = fde.lsda() {
643+
write!(w, " lsda: ")?;
644+
dump_pointer(w, lsda)?;
645+
writeln!(w)?;
634646
}
635647
dump_cfi_instructions(w, fde.instructions(eh_frame, bases), false, register_name)?;
636648
writeln!(w)?;
@@ -639,6 +651,18 @@ fn dump_eh_frame<R: Reader, W: Write>(
639651
}
640652
}
641653

654+
fn dump_pointer<W: Write>(w: &mut W, p: gimli::Pointer) -> Result<()> {
655+
match p {
656+
gimli::Pointer::Direct(p) => {
657+
write!(w, "{:#018x}", p)?;
658+
}
659+
gimli::Pointer::Indirect(p) => {
660+
write!(w, "({:#018x})", p)?;
661+
}
662+
}
663+
Ok(())
664+
}
665+
642666
#[allow(clippy::unneeded_field_pattern)]
643667
fn dump_cfi_instructions<R: Reader, W: Write>(
644668
w: &mut W,

src/read/cfi.rs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,7 +1077,7 @@ pub struct Augmentation {
10771077
/// > represents the pointer encoding used for the second argument, which is
10781078
/// > the address of a personality routine handler. The size of the
10791079
/// > personality routine pointer is specified by the pointer encoding used.
1080-
personality: Option<Pointer>,
1080+
personality: Option<(constants::DwEhPe, Pointer)>,
10811081

10821082
/// > A 'R' may be present at any position after the first character of the
10831083
/// > string. This character may only be present if 'z' is the first character
@@ -1134,7 +1134,7 @@ impl Augmentation {
11341134
};
11351135

11361136
let personality = parse_encoded_pointer(encoding, &parameters, rest)?;
1137-
augmentation.personality = Some(personality);
1137+
augmentation.personality = Some((encoding, personality));
11381138
}
11391139
b'R' => {
11401140
let encoding = parse_pointer_encoding(rest)?;
@@ -1391,10 +1391,29 @@ impl<R: Reader> CommonInformationEntry<R> {
13911391
self.augmentation.map_or(false, |a| a.lsda.is_some())
13921392
}
13931393

1394+
/// Return the encoding of the LSDA address for this CIE's FDEs.
1395+
pub fn lsda_encoding(&self) -> Option<constants::DwEhPe> {
1396+
self.augmentation.and_then(|a| a.lsda)
1397+
}
1398+
1399+
/// Return the encoding and address of the personality routine handler
1400+
/// for this CIE's FDEs.
1401+
pub fn personality_with_encoding(&self) -> Option<(constants::DwEhPe, Pointer)> {
1402+
self.augmentation.as_ref().and_then(|a| a.personality)
1403+
}
1404+
13941405
/// Return the address of the personality routine handler
13951406
/// for this CIE's FDEs.
13961407
pub fn personality(&self) -> Option<Pointer> {
1397-
self.augmentation.as_ref().and_then(|a| a.personality)
1408+
self.augmentation
1409+
.as_ref()
1410+
.and_then(|a| a.personality)
1411+
.map(|(_, p)| p)
1412+
}
1413+
1414+
/// Return the encoding of the addresses for this CIE's FDEs.
1415+
pub fn fde_address_encoding(&self) -> Option<constants::DwEhPe> {
1416+
self.augmentation.and_then(|a| a.fde_address_encoding)
13981417
}
13991418

14001419
/// True if this CIE's FDEs are trampolines for signal handlers.
@@ -6204,7 +6223,7 @@ mod tests {
62046223
let aug_str = &mut EndianSlice::new(b"zP", LittleEndian);
62056224

62066225
let mut augmentation = Augmentation::default();
6207-
augmentation.personality = Some(Pointer::Direct(0xf00d_f00d));
6226+
augmentation.personality = Some((constants::DW_EH_PE_udata8, Pointer::Direct(0xf00d_f00d)));
62086227

62096228
assert_eq!(
62106229
Augmentation::parse(aug_str, &bases, address_size, &section, input),
@@ -6290,7 +6309,7 @@ mod tests {
62906309

62916310
let augmentation = Augmentation {
62926311
lsda: Some(constants::DW_EH_PE_uleb128),
6293-
personality: Some(Pointer::Direct(0x1bad_f00d)),
6312+
personality: Some((constants::DW_EH_PE_udata8, Pointer::Direct(0x1bad_f00d))),
62946313
fde_address_encoding: Some(constants::DW_EH_PE_uleb128),
62956314
is_signal_trampoline: true,
62966315
};

0 commit comments

Comments
 (0)