c2rust icon indicating copy to clipboard operation
c2rust copied to clipboard

c2rust-analyze: handle uses of statics

Open spernsteiner opened this issue 2 years ago • 2 comments

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 stderr in fprintf(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, ...) to eprintln!(...).
  • [ ] static mut of primitive type, like lighttpd's clockid_mono_coarse and log_monotonic_secs
    • I think these can be rewritten into atomics, such as converting i32 to AtomicI32. We don't have to be too specific beyond that because even Ordering::Relaxed would provide more guarantees than the program was previously getting.
  • [ ] static mut containing pointers, like graceful_sockets and log_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 complicated Mutex + Arc machinery.
  • [ ] Lookup tables that don't actually need to be mut, like name2id, static_table, and yy_shift_ofst
    • c2rust-transpile already generates safe indexing operations for some of these, so all that's needed is to identify static muts that are never mutated and convert them to non-mut.
  • [x] (#837) String and bytestring literals, like the expect call in connection_write_cq
    • These are not exactly statics, but look fairly similar in that they use an Operand::Constant of reference type.

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.

spernsteiner avatar Mar 29 '23 21:03 spernsteiner

@fw-immunant @kkysen just wanted to check to see if anything else should be crossed off this list given your work in this area

aneksteind avatar Jul 11 '23 19:07 aneksteind

@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.

kkysen avatar Jul 11 '23 19:07 kkysen