rocq/theories/HelloName.v
GNU Hello's set_program_name through the program logic of Logic.v (docs/logic.md, "GNU Hello through the logic", milestone 2).
gnulib's progname.c: the first thing main does. It finds the last / of argv0 (wp_strrchr); if seven bytes precede the base name, it compares them with "/.libs/" (memeq, by memeq_spec); if they match, it compares the base name with "lt-" (wp_strncmp) and skips it on a match. Then it stores the chosen pointers into three cells: Hello's program_name and libc's program_invocation_name and program_invocation_short_name.
The compiled function has no check that argv0 is not null: gnulib declares the parameter nonnull, so clang drops its abort branch, and strrchr of a null pointer would break its contract. set_program_name_spec therefore owns argv0 as a string.
Every path is safe whatever the comparisons return; the triple only says that each cell ends up holding a pointer with argv0's capability. The proof follows the blocks: spn_start to the strrchr hit, spn_L8 from the base name, spn_L16 for "lt-" and spn_L18 for the stores.
Integer arithmetic on an unknown stays folded when a premise is computed (Symbolic.v).
The function and its data
set_program_name(argv0).
strrchr for /, then is there a slash?
The base name starts after the slash.
Do seven bytes precede the base name?
Are they "/.libs/"?
Branch on that answer.
Does the base name start with "lt-"?
Skip "lt-".
Store the three names.
set_program_name has its entry.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L6.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L8.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L25.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L26.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L16.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L35.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name has L18.
Explore proof 2 tactics
Initial goal
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name's entry binds argv0.
Explore proof 1 tactics
Initial goal
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
memeq is a function of a genv with Hello's module.
Explore proof 5 tactics
Initial goal
intros Hm
unfold find_fn
rewrite Hm
vm_compute
reflexivity
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
Hello's program_name: an 8-byte cell at 66080.
The literal "/.libs/" of progname.c, read-only at 66112.
Its bytes.
The literal "lt-" of progname.c, read-only at 66144.
Its bytes.
Hello's symbols put program_name and the two literals there.
Explore proof 2 tactics
Initial goal
vm_compute
auto
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
set_program_name over any runtime R.
The genv links Hello, with the contracts the function calls.
A pointer store into the cell at offset 0 of the object b, with the region reg, keeps the world interpretation, whatever it held and whatever it now holds (wp_raw_store_pointer's premise).
The three cells: program_name in the object 66080 with the region pn, libc's program_invocation_name in the object nb with nreg, and program_invocation_short_name in sb with sreg, each its own object, as each Fil-C global is.
The Iris instance of the registry and wi.
The expressions of the language.
The three cells, holding x, x and y.
The two literals, as strings.
The genv's program_name and literals are Hello's.
Explore proof 4 tactics
Initial goal
destruct progname_globals as H1 & H2 & H3
destruct Hlinked as _ & Hg & _
split ; exact Hg_ _ H1 |
split ; exact Hg_ _ H2 | exact Hg_ _ H3
No remaining goals.
Qed
✓ Proof checked and closed by Rocq.
Source script
The stores, from L18 after its phis, where pr.1 reads as x and pr.3 as y: each cell's check passes and its store keeps the world interpretation.
Proof 38 steps Qed
Take every branch of the goal's conditions: each path is safe.
The "lt-" test, from L16, with v15 reading as the base name, the suffix of argv0 from its j-th byte: strncmp of it and "lt-", and either answer goes on to the stores, past "lt-" or not.
Proof 44 steps Qed
From L8, with v15 reading as the base name, the suffix of argv0 from its j-th byte, and v0 as argv0: if seven bytes precede the base name, memeq compares them with "/.libs/"; whatever it says, the run goes on to the "lt-" test or to the stores.
Proof 93 steps Qed
Fewer than seven bytes precede the base name.
Compare the seven bytes before it with "/.libs/".
set_program_name's triple: owning argv0 as the string at p, the literals and the three cells, the call is safe and each cell ends up holding a pointer with p's capability: the first two the same one.
Proof 39 steps Qed
No slash: the base name is argv0.
A slash at i: the base name starts after it.
HelloNameOn over a Logic instance of its own.