10e7867ed1330c74ae261609c199729052c5770d8sewardj
20e7867ed1330c74ae261609c199729052c5770d8sewardj#include <stdio.h>
30e7867ed1330c74ae261609c199729052c5770d8sewardj#include <assert.h>
40e7867ed1330c74ae261609c199729052c5770d8sewardj#include <dlfcn.h>
50e7867ed1330c74ae261609c199729052c5770d8sewardj
60e7867ed1330c74ae261609c199729052c5770d8sewardj/* see comments in preen_invar_so.c for explanation of this */
70e7867ed1330c74ae261609c199729052c5770d8sewardj
80e7867ed1330c74ae261609c199729052c5770d8sewardj
90e7867ed1330c74ae261609c199729052c5770d8sewardjint main ( void )
100e7867ed1330c74ae261609c199729052c5770d8sewardj{
110e7867ed1330c74ae261609c199729052c5770d8sewardj  int i, r, sum = 0;
120e7867ed1330c74ae261609c199729052c5770d8sewardj  char* im_a_global_array;
130e7867ed1330c74ae261609c199729052c5770d8sewardj  void* hdl = dlopen("./preen_invars_so.so", RTLD_NOW);
140e7867ed1330c74ae261609c199729052c5770d8sewardj  assert(hdl);
150e7867ed1330c74ae261609c199729052c5770d8sewardj  im_a_global_array = dlsym(hdl, "im_a_global_array");
160e7867ed1330c74ae261609c199729052c5770d8sewardj  assert(im_a_global_array);
170e7867ed1330c74ae261609c199729052c5770d8sewardj  /* printf("%p %p\n", im_a_global_array, me_too_me_too); */
180e7867ed1330c74ae261609c199729052c5770d8sewardj
190e7867ed1330c74ae261609c199729052c5770d8sewardj  /* poke around in the global array, so as to cause exp-ptrcheck
200e7867ed1330c74ae261609c199729052c5770d8sewardj     to generate an Inv_Global invar for it. */
210e7867ed1330c74ae261609c199729052c5770d8sewardj  for (i = 10/*ERROR*/; i >= 0; i--) {
220e7867ed1330c74ae261609c199729052c5770d8sewardj     sum += im_a_global_array[i];
230e7867ed1330c74ae261609c199729052c5770d8sewardj  }
240e7867ed1330c74ae261609c199729052c5770d8sewardj  /* iterating 10 .. 0 causes an Unknown->Global transition at i = 9.
250e7867ed1330c74ae261609c199729052c5770d8sewardj     We do it this way in order that at the end of a loop, there is a
260e7867ed1330c74ae261609c199729052c5770d8sewardj     Global invar in place for the memory read in the loop, so that
270e7867ed1330c74ae261609c199729052c5770d8sewardj     the subsequent dlclose (hence munmap) causes it to get preened.
280e7867ed1330c74ae261609c199729052c5770d8sewardj
290e7867ed1330c74ae261609c199729052c5770d8sewardj     Unfortunately there's nothing to show that the preen was
300e7867ed1330c74ae261609c199729052c5770d8sewardj     successful or happened at all.  The only way to see is from the
310e7867ed1330c74ae261609c199729052c5770d8sewardj     -v output:
320e7867ed1330c74ae261609c199729052c5770d8sewardj
330e7867ed1330c74ae261609c199729052c5770d8sewardj     --686--  sg_:  251 Invars preened, of which 1 changed
340e7867ed1330c74ae261609c199729052c5770d8sewardj
350e7867ed1330c74ae261609c199729052c5770d8sewardj     It's the "1 changed" bit which is significant.
360e7867ed1330c74ae261609c199729052c5770d8sewardj  */
370e7867ed1330c74ae261609c199729052c5770d8sewardj
380e7867ed1330c74ae261609c199729052c5770d8sewardj  /* let's hope gcc is not clever enough to optimise this away, since
390e7867ed1330c74ae261609c199729052c5770d8sewardj     if it does, then it will also nuke the preceding loop, and
400e7867ed1330c74ae261609c199729052c5770d8sewardj     thereby render this test program useless. */
410e7867ed1330c74ae261609c199729052c5770d8sewardj
420e7867ed1330c74ae261609c199729052c5770d8sewardj  if (sum & 1) printf("%s bar %d\n", "foo", sum & 1); else
430e7867ed1330c74ae261609c199729052c5770d8sewardj               printf("foo %s %d\n", "bar", 1 - (sum & 1));
440e7867ed1330c74ae261609c199729052c5770d8sewardj
450e7867ed1330c74ae261609c199729052c5770d8sewardj  /* Now close (== unmap) the array, so that exp-ptrcheck has to check
460e7867ed1330c74ae261609c199729052c5770d8sewardj     its collection of Inv_Global invars, and remove this one from
470e7867ed1330c74ae261609c199729052c5770d8sewardj     it. */
480e7867ed1330c74ae261609c199729052c5770d8sewardj  r = dlclose(hdl);
490e7867ed1330c74ae261609c199729052c5770d8sewardj  assert(r == 0);
500e7867ed1330c74ae261609c199729052c5770d8sewardj
510e7867ed1330c74ae261609c199729052c5770d8sewardj  return 0;
520e7867ed1330c74ae261609c199729052c5770d8sewardj}
53