OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [gcc.c-torture/] [execute/] [builtins/] [vsprintf-chk.c] - Blame information for rev 774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 688 jeremybenn
/* Copyright (C) 2004, 2005  Free Software Foundation.
2
 
3
   Ensure builtin __vsprintf_chk performs correctly.  */
4
 
5
#include <stdarg.h>
6
 
7
extern void abort (void);
8
typedef __SIZE_TYPE__ size_t;
9
extern size_t strlen(const char *);
10
extern void *memcpy (void *, const void *, size_t);
11
extern char *strcpy (char *, const char *);
12
extern int memcmp (const void *, const void *, size_t);
13
extern void *memset (void *, int, size_t);
14
extern int vsprintf (char *, const char *, va_list);
15
 
16
#include "chk.h"
17
 
18
const char s1[] = "123";
19
char p[32] = "";
20
char *s2 = "defg";
21
char *s3 = "FGH";
22
char *s4;
23
size_t l1 = 1;
24
static char buffer[32];
25
char * volatile ptr = "barf";  /* prevent constant propagation to happen when whole program assumptions are made.  */
26
 
27
int
28
__attribute__((noinline))
29
test1_sub (int i, ...)
30
{
31
  int ret = 0;
32
  va_list ap;
33
  va_start (ap, i);
34
  switch (i)
35
    {
36
    case 0:
37
      vsprintf (buffer, "foo", ap);
38
      break;
39
    case 1:
40
      ret = vsprintf (buffer, "foo", ap);
41
      break;
42
    case 2:
43
      vsprintf (buffer, "%s", ap);
44
      break;
45
    case 3:
46
      ret = vsprintf (buffer, "%s", ap);
47
      break;
48
    case 4:
49
      vsprintf (buffer, "%d - %c", ap);
50
      break;
51
    case 5:
52
      vsprintf (s4, "%d - %c", ap);
53
      break;
54
    }
55
  va_end (ap);
56
  return ret;
57
}
58
 
59
void
60
__attribute__((noinline))
61
test1 (void)
62
{
63
  chk_calls = 0;
64
  vsprintf_disallowed = 1;
65
 
66
  memset (buffer, 'A', 32);
67
  test1_sub (0);
68
  if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
69
    abort ();
70
 
71
  memset (buffer, 'A', 32);
72
  if (test1_sub (1) != 3)
73
    abort ();
74
  if (memcmp (buffer, "foo", 4) || buffer[4] != 'A')
75
    abort ();
76
 
77
  if (chk_calls)
78
    abort ();
79
  vsprintf_disallowed = 0;
80
 
81
  memset (buffer, 'A', 32);
82
  test1_sub (2, "bar");
83
  if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
84
    abort ();
85
 
86
  memset (buffer, 'A', 32);
87
  if (test1_sub (3, "bar") != 3)
88
    abort ();
89
  if (memcmp (buffer, "bar", 4) || buffer[4] != 'A')
90
    abort ();
91
 
92
  memset (buffer, 'A', 32);
93
  test1_sub (2, ptr);
94
  if (memcmp (buffer, "barf", 5) || buffer[5] != 'A')
95
    abort ();
96
 
97
  memset (buffer, 'A', 32);
98
  test1_sub (4, (int) l1 + 27, *ptr);
99
  if (memcmp (buffer, "28 - b\0AAAAA", 12))
100
    abort ();
101
 
102
  if (chk_calls != 4)
103
    abort ();
104
  chk_calls = 0;
105
 
106
  test1_sub (5, (int) l1 - 17, ptr[1]);
107
  if (memcmp (s4, "-16 - a", 8))
108
    abort ();
109
  if (chk_calls)
110
    abort ();
111
}
112
 
113
void
114
__attribute__((noinline))
115
test2_sub (int i, ...)
116
{
117
  va_list ap;
118
  struct A { char buf1[10]; char buf2[10]; } a;
119
  char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
120
  char buf3[20];
121
  int j;
122
 
123
  va_start (ap, i);
124
  /* The following calls should do runtime checking
125
     - source length is not known, but destination is.  */
126
  switch (i)
127
    {
128
    case 0:
129
      vsprintf (a.buf1 + 2, "%s", ap);
130
      break;
131
    case 1:
132
      vsprintf (r, "%s%c", ap);
133
      break;
134
    case 2:
135
      r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
136
      vsprintf (r, "%c %s", ap);
137
      break;
138
    case 3:
139
      r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
140
      vsprintf (r + 2, s3 + 3, ap);
141
      break;
142
    case 4:
143
    case 7:
144
      r = buf3;
145
      for (j = 0; j < 4; ++j)
146
        {
147
          if (j == l1 - 1)
148
            r = &a.buf1[1];
149
          else if (j == l1)
150
            r = &a.buf2[7];
151
          else if (j == l1 + 1)
152
            r = &buf3[5];
153
          else if (j == l1 + 2)
154
            r = &a.buf1[9];
155
        }
156
      if (i == 4)
157
        vsprintf (r, s2 + 4, ap);
158
      else
159
        vsprintf (r, "a", ap);
160
      break;
161
    case 5:
162
      r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
163
      vsprintf (r, "%s", ap);
164
      break;
165
    case 6:
166
      vsprintf (a.buf1 + 2, "", ap);
167
      break;
168
    case 8:
169
      vsprintf (s4, "%s %d", ap);
170
      break;
171
    }
172
  va_end (ap);
173
}
174
 
175
/* Test whether compile time checking is done where it should
176
   and so is runtime object size checking.  */
177
void
178
__attribute__((noinline))
179
test2 (void)
180
{
181
  /* The following calls should do runtime checking
182
     - source length is not known, but destination is.  */
183
  chk_calls = 0;
184
  test2_sub (0, s3 + 3);
185
  test2_sub (1, s3 + 3, s3[3]);
186
  test2_sub (2, s2[2], s2 + 4);
187
  test2_sub (3);
188
  test2_sub (4);
189
  test2_sub (5, s1 + 1);
190
  if (chk_calls != 6)
191
    abort ();
192
 
193
  /* Following have known destination and known source length,
194
     so if optimizing certainly shouldn't result in the checking
195
     variants.  */
196
  chk_calls = 0;
197
  vsprintf_disallowed = 1;
198
  test2_sub (6);
199
  test2_sub (7);
200
  vsprintf_disallowed = 0;
201
  /* Unknown destination and source, no checking.  */
202
  test2_sub (8, s3, 0);
203
  if (chk_calls)
204
    abort ();
205
}
206
 
207
void
208
__attribute__((noinline))
209
test3_sub (int i, ...)
210
{
211
  va_list ap;
212
  struct A { char buf1[10]; char buf2[10]; } a;
213
  char buf3[20];
214
 
215
  va_start (ap, i);
216
  /* The following calls should do runtime checking
217
     - source length is not known, but destination is.  */
218
  switch (i)
219
    {
220
    case 0:
221
      vsprintf (&a.buf2[9], "%c%s", ap);
222
      break;
223
    case 1:
224
      vsprintf (&a.buf2[7], "%s%c", ap);
225
      break;
226
    case 2:
227
      vsprintf (&a.buf2[7], "%d", ap);
228
      break;
229
    case 3:
230
      vsprintf (&buf3[17], "%s", ap);
231
      break;
232
    case 4:
233
      vsprintf (&buf3[19], "a", ap);
234
      break;
235
    }
236
  va_end (ap);
237
}
238
 
239
/* Test whether runtime and/or compile time checking catches
240
   buffer overflows.  */
241
void
242
__attribute__((noinline))
243
test3 (void)
244
{
245
  chk_fail_allowed = 1;
246
  /* Runtime checks.  */
247
  if (__builtin_setjmp (chk_fail_buf) == 0)
248
    {
249
      test3_sub (0, s2[3], s2 + 4);
250
      abort ();
251
    }
252
  if (__builtin_setjmp (chk_fail_buf) == 0)
253
    {
254
      test3_sub (1, s3 + strlen (s3) - 2, *s3);
255
      abort ();
256
    }
257
  if (__builtin_setjmp (chk_fail_buf) == 0)
258
    {
259
      test3_sub (2, (int) l1 + 9999);
260
      abort ();
261
    }
262
  if (__builtin_setjmp (chk_fail_buf) == 0)
263
    {
264
      test3_sub (3, "abc");
265
      abort ();
266
    }
267
  /* This should be detectable at compile time already.  */
268
  if (__builtin_setjmp (chk_fail_buf) == 0)
269
    {
270
      test3_sub (4);
271
      abort ();
272
    }
273
  chk_fail_allowed = 0;
274
}
275
 
276
void
277
main_test (void)
278
{
279
#ifndef __OPTIMIZE__
280
  /* Object size checking is only intended for -O[s123].  */
281
  return;
282
#endif
283
  __asm ("" : "=r" (s2) : "0" (s2));
284
  __asm ("" : "=r" (s3) : "0" (s3));
285
  __asm ("" : "=r" (l1) : "0" (l1));
286
  s4 = p;
287
  test1 ();
288
  test2 ();
289
  test3 ();
290
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.