c2rust
c2rust copied to clipboard
c2rust-analyze: handle uses of statics
On lighttpd, our second-largest source of panics is the Operand::Constant case of type_of, which currently doesn't allow any pointers or references to appear in the type of the constant. Constants of reference type are used for accessing statics - here is an example:
static MY_STATIC: i32 = 12345;
let x = MY_STATIC;
// Produces the following MIR:
_2 = const {alloc1: &i32};
_1 = (*_2);
Here, alloc1 is the static allocation used to store the value of MY_STATIC. The value assigned to _2 is an Operand::Constant of type &i32, which currently causes a panic in our static analysis.
There are several different cases observed in lighttpd that we'd eventually like to handle:
- [ ] Extern statics, like
stderrinfprintf(stderr, "some message\n")- These can't be rewritten in general, but in some cases we might be able to apply a higher-level rewrite, such as
fprintf(stderr, ...)toeprintln!(...).
- These can't be rewritten in general, but in some cases we might be able to apply a higher-level rewrite, such as
- [ ]
static mutof primitive type, like lighttpd'sclockid_mono_coarseandlog_monotonic_secs- I think these can be rewritten into atomics, such as converting
i32toAtomicI32. We don't have to be too specific beyond that because evenOrdering::Relaxedwould provide more guarantees than the program was previously getting.
- I think these can be rewritten into atomics, such as converting
- [ ]
static mutcontaining pointers, likegraceful_socketsandlog_con_jqueue- I don't have a good strategy for this, though we could maybe make some initial progress by assuming that the program is single-threaded. This would let us use
thread_local!Cell<Box<T>>or similar, instead of needing more complicatedMutex+Arcmachinery.
- I don't have a good strategy for this, though we could maybe make some initial progress by assuming that the program is single-threaded. This would let us use
- [ ] Lookup tables that don't actually need to be
mut, likename2id,static_table, andyy_shift_ofstc2rust-transpilealready generates safe indexing operations for some of these, so all that's needed is to identifystatic muts that are never mutated and convert them to non-mut.
- [x] (#837) String and bytestring literals, like the
expectcall inconnection_write_cq- These are not exactly statics, but look fairly similar in that they use an
Operand::Constantof reference type.
- These are not exactly statics, but look fairly similar in that they use an
Lookup tables are probably the easiest, but the handling of that case is entirely separate from the main analysis. Aside from that, strings and bytestrings also seem relatively simple, and adding support for these to the dataflow analysis could provide some ideas on how to handle the more complex cases.
@fw-immunant @kkysen just wanted to check to see if anything else should be crossed off this list given your work in this area
@fw-immunant @kkysen just wanted to check to see if anything else should be crossed off this list given your work in this area
Just the string literals, which I've checked the box for now.