Skip to content

Commit

Permalink
Merge pull request #328 from philipc/register
Browse files Browse the repository at this point in the history
Add newtype for registers
  • Loading branch information
philipc authored Sep 18, 2018
2 parents 3015ebe + 44bd277 commit 2e3e14d
Show file tree
Hide file tree
Showing 7 changed files with 526 additions and 269 deletions.
68 changes: 45 additions & 23 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,25 @@ where
object::Machine::Other => mem::size_of::<usize>() as u8,
};

fn register_name_none(_: gimli::Register) -> Option<&'static str> {
None
}
let arch_register_name = match file.machine() {
object::Machine::Arm | object::Machine::Arm64 => gimli::Arm::register_name,
object::Machine::X86 => gimli::X86::register_name,
object::Machine::X86_64 => gimli::X86_64::register_name,
_ => register_name_none,
};
let register_name = |register| {
match arch_register_name(register) {
Some(name) => Cow::Borrowed(name),
None => Cow::Owned(format!("{}", register.0)),
}
};

let mut eh_frame: gimli::EhFrame<_> = load_section(&arena, file, endian);
eh_frame.set_address_size(address_size);
dump_eh_frame(&mut BufWriter::new(out.lock()), &eh_frame)?;
dump_eh_frame(&mut BufWriter::new(out.lock()), &eh_frame, &register_name)?;
}
if flags.info {
dump_info(
Expand Down Expand Up @@ -400,7 +416,11 @@ where
Ok(())
}

fn dump_eh_frame<R: Reader, W: Write>(w: &mut W, eh_frame: &gimli::EhFrame<R>) -> Result<()> {
fn dump_eh_frame<R: Reader, W: Write>(
w: &mut W,
eh_frame: &gimli::EhFrame<R>,
register_name: &Fn(gimli::Register) -> Cow<'static, str>,
) -> Result<()> {
// TODO: Print "__eh_frame" here on macOS, and more generally use the
// section that we're actually looking at, which is what the canonical
// dwarfdump does.
Expand Down Expand Up @@ -431,9 +451,9 @@ fn dump_eh_frame<R: Reader, W: Write>(w: &mut W, eh_frame: &gimli::EhFrame<R>) -
// TODO: augmentation
writeln!(w, " code_align: {}", cie.code_alignment_factor())?;
writeln!(w, " data_align: {}", cie.data_alignment_factor())?;
writeln!(w, " ra_register: {:#x}", cie.return_address_register())?;
writeln!(w, " ra_register: {:#x}", cie.return_address_register().0)?;
// TODO: aug_arg
dump_cfi_instructions(w, cie.instructions(), true)?;
dump_cfi_instructions(w, cie.instructions(), true, register_name)?;
writeln!(w)?;
}
Some(gimli::CieOrFde::Fde(partial)) => {
Expand All @@ -457,7 +477,7 @@ fn dump_eh_frame<R: Reader, W: Write>(w: &mut W, eh_frame: &gimli::EhFrame<R>) -
fde.len(),
fde.initial_address() + fde.len()
)?;
dump_cfi_instructions(w, fde.instructions(), false)?;
dump_cfi_instructions(w, fde.instructions(), false, register_name)?;
writeln!(w)?;
}
}
Expand All @@ -468,16 +488,14 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
w: &mut W,
mut insns: gimli::CallFrameInstructionIter<R>,
is_initial: bool,
register_name: &Fn(gimli::Register) -> Cow<'static, str>,
) -> Result<()> {
use gimli::CallFrameInstruction::*;

// TODO: we need to actually evaluate these instructions as we iterate them
// so we can print the initialized state for CIEs, and each unwind row's
// registers for FDEs.
//
// TODO: We should turn register numbers into register names (eg "7" ->
// "rsp" on x86_64).
//
// TODO: We should print DWARF expressions for the CFI instructions that
// embed DWARF expressions within themselves.

Expand Down Expand Up @@ -508,7 +526,7 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_def_cfa ({}, {})",
register, offset
register_name(register), offset
)?;
}
DefCfaSf {
Expand All @@ -518,11 +536,11 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_def_cfa_sf ({}, {})",
register, factored_offset
register_name(register), factored_offset
)?;
}
DefCfaRegister { register } => {
writeln!(w, " DW_CFA_def_cfa_register ({})", register)?;
writeln!(w, " DW_CFA_def_cfa_register ({})", register_name(register))?;
}
DefCfaOffset { offset } => {
writeln!(w, " DW_CFA_def_cfa_offset ({})", offset)?;
Expand All @@ -538,10 +556,10 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(w, " DW_CFA_def_cfa_expression (...)")?;
}
Undefined { register } => {
writeln!(w, " DW_CFA_undefined ({})", register)?;
writeln!(w, " DW_CFA_undefined ({})", register_name(register))?;
}
SameValue { register } => {
writeln!(w, " DW_CFA_same_value ({})", register)?;
writeln!(w, " DW_CFA_same_value ({})", register_name(register))?;
}
Offset {
register,
Expand All @@ -550,7 +568,7 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_offset ({}, {})",
register, factored_offset
register_name(register), factored_offset
)?;
}
OffsetExtendedSf {
Expand All @@ -560,7 +578,7 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_offset_extended_sf ({}, {})",
register, factored_offset
register_name(register), factored_offset
)?;
}
ValOffset {
Expand All @@ -570,7 +588,7 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_val_offset ({}, {})",
register, factored_offset
register_name(register), factored_offset
)?;
}
ValOffsetSf {
Expand All @@ -580,7 +598,7 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_val_offset_sf ({}, {})",
register, factored_offset
register_name(register), factored_offset
)?;
}
Register {
Expand All @@ -590,14 +608,14 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_register ({}, {})",
dest_register, src_register
register_name(dest_register), register_name(src_register)
)?;
}
Expression {
register,
expression: _,
} => {
writeln!(w, " DW_CFA_expression ({}, ...)", register)?;
writeln!(w, " DW_CFA_expression ({}, ...)", register_name(register))?;
}
ValExpression {
register,
Expand All @@ -606,11 +624,11 @@ fn dump_cfi_instructions<R: Reader, W: Write>(
writeln!(
w,
" DW_CFA_val_expression ({}, ...)",
register
register_name(register)
)?;
}
Restore { register } => {
writeln!(w, " DW_CFA_restore ({})", register)?;
writeln!(w, " DW_CFA_restore ({})", register_name(register))?;
}
RememberState => {
writeln!(w, " DW_CFA_remember_state")?;
Expand Down Expand Up @@ -1127,6 +1145,10 @@ fn dump_exprloc<R: Reader, W: Write>(
writeln!(w, "WARNING: unsupported operation 0x{:02x}", op.0)?;
return Ok(());
}
Err(gimli::Error::UnsupportedRegister(register)) => {
writeln!(w, "WARNING: unsupported register {}", register)?;
return Ok(());
}
otherwise => panic!("Unexpected Operation::parse result: {:?}", otherwise),
}
}
Expand Down Expand Up @@ -1186,7 +1208,7 @@ fn dump_op<R: Reader, W: Write>(
},
gimli::Operation::Register { register } => {
if dwop == gimli::DW_OP_regx {
write!(w, " {}", register)?;
write!(w, " {}", register.0)?;
}
}
gimli::Operation::RegisterOffset {
Expand All @@ -1197,7 +1219,7 @@ fn dump_op<R: Reader, W: Write>(
if dwop >= gimli::DW_OP_breg0 && dwop <= gimli::DW_OP_breg31 {
write!(w, "{:+}", offset)?;
} else {
write!(w, " {}", register)?;
write!(w, " {}", register.0)?;
if offset != 0 {
write!(w, "{:+}", offset)?;
}
Expand Down
Loading

0 comments on commit 2e3e14d

Please sign in to comment.