How does this proposal handle situations where the unsafe
code is relying on the well-formedness of a complex data structure? For example, here is some FFI code I just wrote...
unsafe {
use shim::{UAPIStruct, STRUCTS};
let mut map = HashMap::new();
for UAPIStruct { name, align, size, fields, } in &STRUCTS
{
let name = CStr::from_ptr(*name);
let name = name.to_str().expect("struct tag name not valid UTF-8");
let mut rfields = Vec::new();
for i in 0.. {
let field = fields.offset(i).read();
if field.name.is_null() {
break;
}
let fname = CStr::from_ptr(field.name);
let fname = fname.to_str().expect("field name not valid UTF-8");
rfields.push(Field {
name: fname,
size: field.size,
offset: field.offset,
});
}
map.insert(name, Struct { size, align, fields: rfields })
}
map
}
where STRUCTS
is static data generated by compiling a C module. The safety requirements for this code are
- the definitions of
UAPIStruct
and its daughter structUAPIField
(the type offields
) must agree with the matching definitions on the C side of the fence - On the Rust side
STRUCTS
is declared asstatic STRUCTS: [UAPIStruct; n]
;n
must be accurate - all the pointer dereferences need to be valid
- all the pointers passed to
CStr::from_ptr
must be valid C strings - there must actually be a null pointer terminator for each
fields
array - probably some other stuff I forgot
How much of this can be captured in your proposal and how would it be written? I can provide more fragments if it will help.