File: origin3-no.c

package info (click to toggle)
valgrind 1%3A3.12.0~svn20160714-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 120,428 kB
  • ctags: 70,855
  • sloc: ansic: 674,645; exp: 26,134; xml: 21,574; asm: 7,570; cpp: 7,567; makefile: 7,380; sh: 6,188; perl: 5,855; haskell: 195
file content (116 lines) | stat: -rw-r--r-- 3,922 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116

/* This test case was originally written by Nicholas Nethercote. */

// [[This comment applies to the old piggybacking approach to
// origin-tracking.  The newer approach handles the cases in this file
// correctly.]]
// This test demonstrates cases the piggybacking algorithm cannot handle,
// but which are handled ok by the instrumentation based algorithm.

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "../memcheck.h"

int x = 0;

__attribute__((noinline)) int t1(void);
__attribute__((noinline)) int t2(void);
__attribute__((noinline)) int t3(void);
__attribute__((noinline)) int t4(void);
__attribute__((noinline)) int t5(void);
__attribute__((noinline)) int t6(void);

int main(void)
{
   assert(4 == sizeof(int));

   x += t1();
   x += t2();
   x += t3();
   x += t4();
   x += t5();
   x += t6();

   return x & 255;
}

__attribute__((noinline)) int t1(void)
{
   // 8-bit undefined value.  When compared it's loaded from memory, so will
   // never work.
   char* ptr_to_undef_char = malloc(sizeof(char));
   char  undef_char = *ptr_to_undef_char;
   fprintf(stderr, "\nUndef 1 of 8 (8 bit undef)\n");
   return (undef_char == 0x12 ? 11 : 22);
}

__attribute__((noinline)) int t2(void)
{
   // Stack, 8-bit from (recently) 32-bit.  But the load only loads 8-bits
   // of the value, so it'll never work.
   int undef_stack_int;
   register char undef_stack_char = (char)undef_stack_int;
   fprintf(stderr, "\nUndef 2 of 8 (8 bits of 32 undef)\n");
   return (undef_stack_char == 0x12 ? 11 : 22);
}

__attribute__((noinline)) int t3(void)
{
   // 32-bit undefined value.  This one is identified, and is here for
   // sanity-checking.
   int* ptr_to_undef_int = malloc(sizeof(int));
   int  undef_int = *ptr_to_undef_int;
   fprintf(stderr, "\nUndef 3 of 8 (32 bit undef)\n");
   return (undef_int == 0x12345678 ? 13 : 24);
}

__attribute__((noinline)) int t4(void)
{
   // Unaligned 32-bit value.
   int* ptr_to_undef_int = malloc(sizeof(int) + 1);
   int  undef_unaligned_int = *(int*)((long)ptr_to_undef_int + 1);
   fprintf(stderr, "\nUndef 4 of 8 (32 bit undef, unaligned)\n");
   return (undef_unaligned_int == 0x12345678 ? 14 : 25);
}

__attribute__((noinline)) int t5(void)
{
   // Modified 32-bit value.
   int* ptr_to_undef_int3 = malloc(sizeof(int));
   int  modified_undef_int = *ptr_to_undef_int3;
   fprintf(stderr, "\nUndef 5 of 8 (32 bit undef, modified)\n");
   modified_undef_int++;
   return (modified_undef_int == 0x12345678 ? 15 : 26);
}

__attribute__((noinline)) int t6(void)
{
   int y = 0;
   
   // Uninitialised 32-bit value (middle of 3) is made undefined in two
   // unaligned pieces:
   //   |....|....|....|   three 4-byte integers
   //    XXXX-YY           first MAKE_MEM_UNDEFINED
   //           YY-XXXX    second MAKE_MEM_UNDEFINED
   // Because the YY parts don't get marked (they're not 32-bit and aligned)
   // the middle byte keeps its original value, which is zero (from calloc).
   // So even though it's been marked as undefined, it doesn't have an
   // origin-tracking value and so cannot be identified.  We also check the
   // first and third ints (which are identified) for sanity-checking.
   {
      int* ptr_to_3_undef_ints = calloc(3, sizeof(int));
      int* ptr_to_middle       = (int*)((long)ptr_to_3_undef_ints + 6);
      (void) VALGRIND_MAKE_MEM_UNDEFINED(ptr_to_3_undef_ints, 6);
      (void) VALGRIND_MAKE_MEM_UNDEFINED(ptr_to_middle,       6);
      fprintf(stderr, "\nUndef 6 of 8 (32 bit undef, unaligned, strange, #1)\n");
      y += (*(ptr_to_3_undef_ints + 0)  == 0x12345678 ? 16 : 27);
      fprintf(stderr, "\nUndef 7 of 8 (32 bit undef, unaligned, strange, #2)\n");
      y += (*(ptr_to_3_undef_ints + 1)  == 0x12345678 ? 17 : 28);
      fprintf(stderr, "\nUndef 8 of 8 (32 bit undef, unaligned, strange, #3)\n");
      y += (*(ptr_to_3_undef_ints + 2)  == 0x12345678 ? 18 : 29);
      return y;
   }

   return x;
}