Skip to content

Commit

Permalink
Merge pull request #479 from philipc/issue-474
Browse files Browse the repository at this point in the history
write: implement references within expressions
  • Loading branch information
philipc authored Apr 28, 2020
2 parents fc3d94a + ebfffc6 commit e232bb9
Show file tree
Hide file tree
Showing 17 changed files with 2,573 additions and 527 deletions.
4 changes: 2 additions & 2 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ fn bench_parsing_debug_info_expressions(b: &mut test::Bencher) {
for &(expression, encoding) in &*expressions {
let mut pc = expression.0;
while !pc.is_empty() {
Operation::parse(&mut pc, &expression.0, encoding).expect("Should parse operation");
Operation::parse(&mut pc, encoding).expect("Should parse operation");
}
}
});
Expand Down Expand Up @@ -536,7 +536,7 @@ fn bench_parsing_debug_loc_expressions(b: &mut test::Bencher) {
for &(expression, encoding) in &*expressions {
let mut pc = expression.0;
while !pc.is_empty() {
Operation::parse(&mut pc, &expression.0, encoding).expect("Should parse operation");
Operation::parse(&mut pc, encoding).expect("Should parse operation");
}
}
});
Expand Down
42 changes: 21 additions & 21 deletions examples/dwarfdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ fn dump_attr_value<R: Reader, W: Write>(
}
write!(w, ": ")?;
}
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::AttributeValue::Flag(true) => {
Expand Down Expand Up @@ -1318,22 +1318,22 @@ fn dump_file_index<R: Reader, W: Write>(

fn dump_exprloc<R: Reader, W: Write>(
w: &mut W,
encoding: gimli::Encoding,
data: &gimli::Expression<R>,
unit: &gimli::Unit<R>,
) -> Result<()> {
let mut pc = data.0.clone();
let mut space = false;
while pc.len() != 0 {
let mut op_pc = pc.clone();
let dwop = gimli::DwOp(op_pc.read_u8()?);
match gimli::Operation::parse(&mut pc, &data.0, unit.encoding()) {
match gimli::Operation::parse(&mut pc, encoding) {
Ok(op) => {
if space {
write!(w, " ")?;
} else {
space = true;
}
dump_op(w, dwop, op, &pc)?;
dump_op(w, encoding, dwop, op)?;
}
Err(gimli::Error::InvalidExpression(op)) => {
writeln!(w, "WARNING: unsupported operation 0x{:02x}", op.0)?;
Expand All @@ -1358,9 +1358,9 @@ fn dump_exprloc<R: Reader, W: Write>(

fn dump_op<R: Reader, W: Write>(
w: &mut W,
encoding: gimli::Encoding,
dwop: gimli::DwOp,
op: gimli::Operation<R>,
newpc: &R,
) -> Result<()> {
write!(w, "{}", dwop)?;
match op {
Expand All @@ -1383,21 +1383,22 @@ fn dump_op<R: Reader, W: Write>(
write!(w, " {}", value as i64)?;
}
gimli::Operation::Bra { target } => {
let offset = newpc.len() as isize - target.len() as isize;
write!(w, " {}", offset)?;
write!(w, " {}", target)?;
}
gimli::Operation::Skip { target } => {
let offset = newpc.len() as isize - target.len() as isize;
write!(w, " {}", offset)?;
write!(w, " {}", target)?;
}
gimli::Operation::Literal { value } => match dwop {
gimli::Operation::SignedConstant { value } => match dwop {
gimli::DW_OP_const1s
| gimli::DW_OP_const2s
| gimli::DW_OP_const4s
| gimli::DW_OP_const8s
| gimli::DW_OP_consts => {
write!(w, " {}", value as i64)?;
write!(w, " {}", value)?;
}
_ => {}
},
gimli::Operation::UnsignedConstant { value } => match dwop {
gimli::DW_OP_const1u
| gimli::DW_OP_const2u
| gimli::DW_OP_const4u
Expand Down Expand Up @@ -1465,10 +1466,9 @@ fn dump_op<R: Reader, W: Write>(
write!(w, " 0x{:08x} {}", value.0, byte_offset)?;
}
gimli::Operation::EntryValue { expression } => {
write!(w, " 0x{:08x} contents 0x", expression.len())?;
for byte in expression.to_slice()?.iter() {
write!(w, "{:02x}", byte)?;
}
write!(w, "(")?;
dump_exprloc(w, encoding, &gimli::Expression(expression))?;
write!(w, ")")?;
}
gimli::Operation::ParameterRef { offset } => {
write!(w, " 0x{:08x}", offset.0)?;
Expand Down Expand Up @@ -1571,7 +1571,7 @@ fn dump_loc_list<R: Reader, W: Write>(
high-off: [{}]0x{:08x} addr 0x{:08x}>",
begin.0, begin_val, location.range.begin, end.0, end_val, location.range.end
)?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::RawLocListEntry::StartxLength {
Expand All @@ -1588,7 +1588,7 @@ fn dump_loc_list<R: Reader, W: Write>(
high-off: 0x{:08x} addr 0x{:08x}>",
begin.0, begin_val, location.range.begin, length, location.range.end
)?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::RawLocListEntry::AddressOrOffsetPair {
Expand All @@ -1609,12 +1609,12 @@ fn dump_loc_list<R: Reader, W: Write>(
high-off: 0x{:08x} addr 0x{:08x}>",
begin, location.range.begin, end, location.range.end
)?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::RawLocListEntry::DefaultLocation { ref data } => {
write!(w, "<default location>")?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::RawLocListEntry::StartEnd {
Expand All @@ -1630,7 +1630,7 @@ fn dump_loc_list<R: Reader, W: Write>(
high-off: 0x{:08x} addr 0x{:08x}>",
begin, location.range.begin, end, location.range.end
)?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
gimli::RawLocListEntry::StartLength {
Expand All @@ -1646,7 +1646,7 @@ fn dump_loc_list<R: Reader, W: Write>(
high-off: 0x{:08x} addr 0x{:08x}>",
begin, location.range.begin, length, location.range.end
)?;
dump_exprloc(w, data, unit)?;
dump_exprloc(w, unit.encoding(), data)?;
writeln!(w)?;
}
};
Expand Down
27 changes: 27 additions & 0 deletions src/leb128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
//! ```

const CONTINUATION_BIT: u8 = 1 << 7;
#[cfg(feature = "read")]
const SIGN_BIT: u8 = 1 << 6;

#[inline]
Expand Down Expand Up @@ -176,6 +177,18 @@ pub mod write {
}
}

/// Return the size of the LEB128 encoding of the given unsigned number.
pub fn uleb128_size(mut val: u64) -> usize {
let mut size = 0;
loop {
val >>= 7;
size += 1;
if val == 0 {
return size;
}
}
}

/// Write the given signed number using the LEB128 encoding to the given
/// `std::io::Write`able. Returns the number of bytes written to `w`, or an
/// error if writing failed.
Expand Down Expand Up @@ -207,6 +220,20 @@ pub mod write {
}
}
}

/// Return the size of the LEB128 encoding of the given signed number.
pub fn sleb128_size(mut val: i64) -> usize {
let mut size = 0;
loop {
val >>= 6;
let done = val == 0 || val == -1;
val >>= 1;
size += 1;
if done {
return size;
}
}
}
}

#[cfg(test)]
Expand Down
7 changes: 7 additions & 0 deletions src/read/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,11 @@ impl<R: Reader> Unit<R> {
self.header.encoding()
}

/// Read the `DebuggingInformationEntry` at the given offset.
pub fn entry(&self, offset: UnitOffset<R::Offset>) -> Result<DebuggingInformationEntry<R>> {
self.header.entry(&self.abbreviations, offset)
}

/// Navigate this unit's `DebuggingInformationEntry`s.
#[inline]
pub fn entries(&self) -> EntriesCursor<R> {
Expand Down Expand Up @@ -694,6 +699,8 @@ impl<T: ReaderOffset> UnitSectionOffset<T> {
impl<T: ReaderOffset> UnitOffset<T> {
/// Convert an offset to be relative to the start of the .debug_info section,
/// instead of relative to the start of the given compilation unit.
///
/// Does not check that the offset is valid.
pub fn to_unit_section_offset<R>(&self, unit: &Unit<R>) -> UnitSectionOffset<T>
where
R: Reader<Offset = T>,
Expand Down
Loading

0 comments on commit e232bb9

Please sign in to comment.