#cast #model #memory #look #sound #ptr #int

totally-sound-ptr-int-cast

do i _look_ like a memory model?

2 releases

0.1.1 Mar 31, 2022
0.1.0 Mar 31, 2022

#561 in Audio

AGPL-3.0

7KB
77 lines

totally sound ptr<-> int casts

doom is upon us

Okay, so, it looks like as-casts between usize and raw pointer types are on the way out. People are talking about how those make provenance really annoying which is bad for formalizing a memory model. In this hypothetical future, it would be highly illegal to cast a pointer to an integer, maybe roundtrip it through some OS or FFI API, cast it back to an integer, and then dereference it.

It may be too late to avert that terrible fate. In this doomed timeline, it may become necessary to use this crate to perform totally sound ptr<->int casts.

let n = totally_sound_ptr_int_cast::ptr2int(
    Bxo::into_raw(your_boxed_stuff.into_raw()));

and, at any later point within the same program execution,

let p = totally_sound_ptr_int_cast::int2ptr_mut(n);
unsafe { println!("{:?}", &*p); } // or whatever

you get your stuff back.


lib.rs:

why is this sound

To withstand this future I'm raving about in the readme, we return to the old ways.

C defines the printf format specifier p something like

The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.

and the scanf format specifier p like

Matches an implementation-defined set of sequences, which should be the same as the set of sequences that may be produced by the %p conversion of the fprintf function. The corresponding argument shall be a pointer to a pointer to void. The input item is converted to a pointer value in an implementation-defined manner. If the input item is a value converted earlier during the same program execution, the pointer that results shall compare equal to that value; otherwise the behavior of the %p conversion is undefined.

Once you're at "shall compare equal", you pretty much can't get out of the pointers being usable interchangeably, or the wording for casting to void* and back doesn't work.

We additionally note that glibc documents that non-null pointers are printed as hex integers. I'm pretty sure musl does about the same thing but I haven't tested with musl.

So, we %p-print a pointer and parse the result as an integer and there's our very defensible integer representation of a pointer. For the inverse, we print the integer in that exact hexadecimal form, and then %p-parse it back into a pointer, and we have the great, very defensible argument that we can actually use this pointer because that's what the scanf docs say. The rust memory model can hardly say that C stops working as defined, right?

Dependencies

~42KB