immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
3.98k stars 237 forks source link

Dynamic instrumentation does not support intermediate `LoadValue` and `LoadAddr` events #578

Open aneksteind opened 2 years ago

aneksteind commented 2 years ago

We'd like to treat the following MIR:

_13 = &raw const (*((*((*_8).2: *mut pointers::S)).2: *mut pointers::S))

as something roughly equal to:

1: p = (*_8).2: *mut pointers::S
2: q = (*p).2: *mut pointers::S
3: _13 = &raw const (*q)

implying that there LoadAddr and LoadValue events for (*_8).2 and (*p).2

When generating these events, the value of each respective pointer will need to be passed to the instrumentation in order for the corresponding object to be detected. This means that the source needs to be instrumented with assignment statements to locals that can be passed. For example:

1: _21 =  (*_8).2
2: field_hook(/* ... info about line 1 ... */)
3: load_addr_hook(/* ... info about line 1 ... */)
4: load_value_hook(/* ... info about line 1 ... */)
5: _22 = (*_21).2: *mut pointers::S
6: field_hook(/* ... info about line 5 ... */)
7: load_addr_hook(/* ... info about line 5 ... */)
8: load_value_hook(/* ... info about line 5 ... */)
9: _13 = &raw const (*((*((*_8).2: *mut pointers::S)).2: *mut pointers::S))
10: copy_addr_hook(/* ... info about line 9 ... */)
aneksteind commented 2 years ago

There is an additional challenge to this: instrumentation points are created before statements are inserted. This means that ... info about line 1 ... is (at that point), impossible to determine at point-building time (it doesn't exist yet)

aneksteind commented 2 years ago

I've added test cases that demonstrate the issue in #568. The following PDG node is generated there:

n[0]: &_8 _ => _14 @ bb0[39]: fn test_ref_field_addr; _14 = &raw const ((*((*_8).2: *mut pointers::S)).2: *mut pointers::S);

This is a both a bug (AddrOf node is incorrect) and does not produce all the events listed above