1d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
2d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Check of variable location identification when using .debug_types.  */
3d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Relevant compile flags are:
5d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
6d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   -Wall -g -I$prefix/include/valgrind -gdwarf-4 -fdebug-types-section
7d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
8d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   eg -Wall -g -I`pwd`/Inst/include/valgrind -gdwarf-4 -fdebug-types-section
9d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj*/
10d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
11d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include <stdio.h>
12d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include <stdlib.h>
13f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include <string.h>
14d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include <assert.h>
15f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include "tests/sys_mman.h"
16f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include <sys/types.h>
17f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include <sys/stat.h>
18f7ec77f53fd09a5682dbe6db049efe0746df7948philippe#include <fcntl.h>
19d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include "memcheck/memcheck.h"
20d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
21d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Cause memcheck to complain about the address "a" and so to print
22d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe   its best guess as to what "a" actually is.*/
23d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjvoid croak ( void* aV )
24d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
25d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  if(VALGRIND_CHECK_MEM_IS_ADDRESSABLE(aV,1) != 0)
26d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe     return;
27d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  char* a = (char*)aV;
28d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  char* undefp = malloc(1);
29d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  char saved = *a;
30d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  assert(undefp);
31d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  *a = *undefp;
3206bc722457ffe12e056d2f40d0d2f5c8711b541fflorian  (void) VALGRIND_CHECK_MEM_IS_DEFINED(a, 1);
33d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  *a = saved;
34d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  free(undefp);
35d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
36d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
37d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstruct s1
38d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
39d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  char c;
40d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  short s;
41d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  int i;
42d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  long l;
43d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  float f;
44d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  double d;
45d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj};
46d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
47d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstruct s1 S2[30];
48d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
49d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjint main ( void )
50d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
51d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  struct s1 local;
52d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  struct s1* onheap = malloc(sizeof (struct s1));
53f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  void *p, *q;
54f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  int fd;
55f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  int n;
56f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  char filename[256];
57f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
58d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  assert(onheap);
59d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  croak(&onheap->i);
60d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
61d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  croak( &S2[0].i );
62d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  croak( &local.i );
63f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
64f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  /* Describe anonymous mmap-ed */
65f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  p = mmap( 0, 16 * 1024, PROT_READ|PROT_WRITE,
66f7ec77f53fd09a5682dbe6db049efe0746df7948philippe            MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
67f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  assert(p != MAP_FAILED);
68f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  croak( p);
69f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
70f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  /* Describe file mmap-ed */
718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj  snprintf(filename, sizeof(filename), "./valgrind-dw4-test.%ld",
728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj           (long) getpid());
73f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
74f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  unlink(filename);
75f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
76f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
77f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  assert (fd > 0);
78f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  n = write(fd, filename, strlen(filename));
79f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  assert (n > 8);
80f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  q = mmap(NULL, 100, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
81f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  assert (q != MAP_FAILED);
82f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  croak( q);
83f7ec77f53fd09a5682dbe6db049efe0746df7948philippe  unlink(filename);
84f7ec77f53fd09a5682dbe6db049efe0746df7948philippe
85d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  /* Describe memory in or past the heap end. */
86d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  void *addr = sbrk(0);
87d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  croak(addr); // in the first brk page, after brk_limit
88d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  sbrk(4 * 1024); // increase brk segment
89d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  croak(addr); // Now, must be inside.
90d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  addr = (void *) ((char*)addr + 2 * 1024);
91d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  croak(addr); // Must still be inside.
92d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  sbrk(-3*1024);
93d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe  croak(addr); // Must now be after.
94d0da968735a4986e3a23f0832e9173fa9d58a1a3philippe
95d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj  return 0;
96d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
97