Skip to content

Commit

Permalink
Add field depth to Field events
Browse files Browse the repository at this point in the history
Add Field level depth in order to distinguish between
identical field indices at different depths, e.g.,
x.1.2 and x.2 would emit an identical Field(&x, 2) event.
  • Loading branch information
ahomescu committed Jun 7, 2024
1 parent 8ed0e8a commit 2320828
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 16 deletions.
10 changes: 8 additions & 2 deletions analysis/runtime/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ pub enum EventKind {
/// Field projection. Used for operations like `_2 = &(*_1).0`. Nested field
/// accesses like `_4 = &(*_1).x.y.z` are broken into multiple `Node`s, each
/// covering one level.
Field(Pointer, u32),
Field {
ptr: Pointer,
depth: u32,
field_id: u32,
},

Alloc {
size: usize,
Expand Down Expand Up @@ -90,7 +94,9 @@ impl Debug for EventKind {
use EventKind::*;
match *self {
CopyPtr(ptr) => write!(f, "copy(0x{:x})", ptr),
Field(ptr, id) => write!(f, "field(0x{:x}, {})", ptr, id),
Field { ptr, depth, field_id } => {
write!(f, "field(0x{:x}, {}, {})", ptr, depth, field_id)
}
Alloc { size, ptr } => {
write!(f, "malloc({}) -> 0x{:x}", size, ptr)
}
Expand Down
8 changes: 6 additions & 2 deletions analysis/runtime/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,14 @@ pub const HOOK_FUNCTIONS: &[&str] = &[
hook_fn!(offset),
];

pub fn ptr_field(mir_loc: MirLocId, ptr: usize, field_id: u32) {
pub fn ptr_field(mir_loc: MirLocId, ptr: usize, depth: u32, field_id: u32) {
RUNTIME.send_event(Event {
mir_loc,
kind: EventKind::Field(ptr, field_id),
kind: EventKind::Field {
ptr,
depth,
field_id,
},
});
}

Expand Down
14 changes: 4 additions & 10 deletions dynamic_instrumentation/src/instrument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,22 +348,16 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> {
let base_ty = self.local_decls()[place.local].ty;

// Instrument field projections on raw-ptr places
// None of the events here have a destination because
// the assignment takes care of that separately in visit_assign
if is_region_or_unsafe_ptr(base_ty) && context.is_use() {
for (base, elem) in place.iter_projections() {
for (depth, (base, elem)) in place.iter_projections().enumerate() {
if let PlaceElem::Field(field, _) = elem {
let proj_dest = || {
// Only the last field projection gets a destination
self.assignment()
.as_ref()
.map(|(dest, _)| dest)
.copied()
.filter(|_| base.projection.len() == place.projection.len() - 1)
};
self.loc(location, location, field_fn)
.arg_var(place.local)
.arg_var(u32::try_from(depth).expect("Field depth too large"))
.arg_index_of(field)
.source(place)
.dest_from(proj_dest)
.add_to(self);
}
}
Expand Down
4 changes: 2 additions & 2 deletions pdg/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl EventKindExt for EventKind {
use EventKind::*;
Some(match *self {
CopyPtr(lhs) => lhs,
Field(ptr, ..) => ptr,
Field { ptr, .. } => ptr,
Free { ptr } => ptr,
Ret(ptr) => ptr,
LoadAddr(ptr) => ptr,
Expand All @@ -70,7 +70,7 @@ impl EventKindExt for EventKind {
Realloc { .. } => NodeKind::Alloc(1),
Free { .. } => NodeKind::Free,
CopyPtr(..) | CopyRef => NodeKind::Copy,
Field(_, field) => NodeKind::Field(field.into()),
Field { field_id, .. } => NodeKind::Field(field_id.into()),
LoadAddr(..) => NodeKind::LoadAddr,
StoreAddr(..) => NodeKind::StoreAddr,
StoreAddrTaken(..) => NodeKind::StoreAddr,
Expand Down

0 comments on commit 2320828

Please sign in to comment.