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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gcc-4.5.1/] [gcc-4.5.1-or32-1.0rc1/] [gcc/] [testsuite/] [gcc.c-torture/] [execute/] [builtins/] [memcpy-chk.c] - Blame information for rev 338

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 297 jeremybenn
/* Copyright (C) 2004, 2005  Free Software Foundation.
2
 
3
   Ensure builtin __memcpy_chk performs correctly.  */
4
 
5
extern void abort (void);
6
typedef __SIZE_TYPE__ size_t;
7
extern size_t strlen(const char *);
8
extern void *memcpy (void *, const void *, size_t);
9
extern int memcmp (const void *, const void *, size_t);
10
 
11
#include "chk.h"
12
 
13
const char s1[] = "123";
14
char p[32] = "";
15
char *s2 = "defg";
16
char *s3 = "FGH";
17
size_t l1 = 1;
18
 
19
void
20
__attribute__((noinline))
21
test1 (void)
22
{
23
  int i;
24
 
25
#if defined __i386__ || defined __x86_64__
26
  /* The functions below might not be optimized into direct stores on all
27
     arches.  It depends on how many instructions would be generated and
28
     what limits the architecture chooses in STORE_BY_PIECES_P.  */
29
  memcpy_disallowed = 1;
30
#endif
31
 
32
  /* All the memcpy calls in this routine except last have fixed length, so
33
     object size checking should be done at compile time if optimizing.  */
34
  chk_calls = 0;
35
 
36
  if (memcpy (p, "ABCDE", 6) != p || memcmp (p, "ABCDE", 6))
37
    abort ();
38
  if (memcpy (p + 16, "VWX" + 1, 2) != p + 16
39
      || memcmp (p + 16, "WX\0\0", 5))
40
    abort ();
41
  if (memcpy (p + 1, "", 1) != p + 1 || memcmp (p, "A\0CDE", 6))
42
    abort ();
43
  if (memcpy (p + 3, "FGHI", 4) != p + 3 || memcmp (p, "A\0CFGHI", 8))
44
    abort ();
45
 
46
  i = 8;
47
  memcpy (p + 20, "qrstu", 6);
48
  memcpy (p + 25, "QRSTU", 6);
49
  if (memcpy (p + 25 + 1, s1, 3) != p + 25 + 1
50
      || memcmp (p + 25, "Q123U", 6))
51
    abort ();
52
 
53
  if (memcpy (memcpy (p, "abcdEFG", 4) + 4, "efg", 4) != p + 4
54
      || memcmp (p, "abcdefg", 8))
55
    abort();
56
 
57
  /* Test at least one instance of the __builtin_ style.  We do this
58
     to ensure that it works and that the prototype is correct.  */
59
  if (__builtin_memcpy (p, "ABCDE", 6) != p || memcmp (p, "ABCDE", 6))
60
    abort ();
61
 
62
  memcpy (p + 5, s3, 1);
63
  if (memcmp (p, "ABCDEFg", 8))
64
    abort ();
65
 
66
  memcpy_disallowed = 0;
67
  if (chk_calls)
68
    abort ();
69
  chk_calls = 0;
70
 
71
  memcpy (p + 6, s1 + 1, l1);
72
  if (memcmp (p, "ABCDEF2", 8))
73
    abort ();
74
 
75
  /* The above memcpy copies into an object with known size, but
76
     unknown length, so it should be a __memcpy_chk call.  */
77
  if (chk_calls != 1)
78
    abort ();
79
}
80
 
81
long buf1[64];
82
char *buf2 = (char *) (buf1 + 32);
83
long buf5[20];
84
char buf7[20];
85
 
86
void
87
__attribute__((noinline))
88
test2_sub (long *buf3, char *buf4, char *buf6, int n)
89
{
90
  int i = 0;
91
 
92
  /* All the memcpy/__builtin_memcpy/__builtin___memcpy_chk
93
     calls in this routine are either fixed length, or have
94
     side-effects in __builtin_object_size arguments, or
95
     dst doesn't point into a known object.  */
96
  chk_calls = 0;
97
 
98
  /* These should probably be handled by store_by_pieces on most arches.  */
99
  if (memcpy (buf1, "ABCDEFGHI", 9) != (char *) buf1
100
      || memcmp (buf1, "ABCDEFGHI\0", 11))
101
    abort ();
102
 
103
  if (memcpy (buf1, "abcdefghijklmnopq", 17) != (char *) buf1
104
      || memcmp (buf1, "abcdefghijklmnopq\0", 19))
105
    abort ();
106
 
107
  if (__builtin_memcpy (buf3, "ABCDEF", 6) != (char *) buf1
108
      || memcmp (buf1, "ABCDEFghijklmnopq\0", 19))
109
    abort ();
110
 
111
  if (__builtin_memcpy (buf3, "a", 1) != (char *) buf1
112
      || memcmp (buf1, "aBCDEFghijklmnopq\0", 19))
113
    abort ();
114
 
115
  if (memcpy ((char *) buf3 + 2, "bcd" + ++i, 2) != (char *) buf1 + 2
116
      || memcmp (buf1, "aBcdEFghijklmnopq\0", 19)
117
      || i != 1)
118
    abort ();
119
 
120
  /* These should probably be handled by move_by_pieces on most arches.  */
121
  if (memcpy ((char *) buf3 + 4, buf5, 6) != (char *) buf1 + 4
122
      || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
123
    abort ();
124
 
125
  if (__builtin_memcpy ((char *) buf1 + ++i + 8, (char *) buf5 + 1, 1)
126
      != (char *) buf1 + 10
127
      || memcmp (buf1, "aBcdRSTUVWSlmnopq\0", 19)
128
      || i != 2)
129
    abort ();
130
 
131
  if (memcpy ((char *) buf3 + 14, buf6, 2) != (char *) buf1 + 14
132
      || memcmp (buf1, "aBcdRSTUVWSlmnrsq\0", 19))
133
    abort ();
134
 
135
  if (memcpy (buf3, buf5, 8) != (char *) buf1
136
      || memcmp (buf1, "RSTUVWXYVWSlmnrsq\0", 19))
137
    abort ();
138
 
139
  if (memcpy (buf3, buf5, 17) != (char *) buf1
140
      || memcmp (buf1, "RSTUVWXYZ01234567\0", 19))
141
    abort ();
142
 
143
  __builtin_memcpy (buf3, "aBcdEFghijklmnopq\0", 19);
144
 
145
  /* These should be handled either by movmemendM or memcpy
146
     call.  */
147
 
148
  /* buf3 points to an unknown object, so __memcpy_chk should not be done.  */
149
  if (memcpy ((char *) buf3 + 4, buf5, n + 6) != (char *) buf1 + 4
150
      || memcmp (buf1, "aBcdRSTUVWklmnopq\0", 19))
151
    abort ();
152
 
153
  /* This call has side-effects in dst, therefore no checking.  */
154
  if (__builtin___memcpy_chk ((char *) buf1 + ++i + 8, (char *) buf5 + 1,
155
                              n + 1, os ((char *) buf1 + ++i + 8))
156
      != (char *) buf1 + 11
157
      || memcmp (buf1, "aBcdRSTUVWkSmnopq\0", 19)
158
      || i != 3)
159
    abort ();
160
 
161
  if (memcpy ((char *) buf3 + 14, buf6, n + 2) != (char *) buf1 + 14
162
      || memcmp (buf1, "aBcdRSTUVWkSmnrsq\0", 19))
163
    abort ();
164
 
165
  i = 1;
166
 
167
  /* These might be handled by store_by_pieces.  */
168
  if (memcpy (buf2, "ABCDEFGHI", 9) != buf2
169
      || memcmp (buf2, "ABCDEFGHI\0", 11))
170
    abort ();
171
 
172
  if (memcpy (buf2, "abcdefghijklmnopq", 17) != buf2
173
      || memcmp (buf2, "abcdefghijklmnopq\0", 19))
174
    abort ();
175
 
176
  if (__builtin_memcpy (buf4, "ABCDEF", 6) != buf2
177
      || memcmp (buf2, "ABCDEFghijklmnopq\0", 19))
178
    abort ();
179
 
180
  if (__builtin_memcpy (buf4, "a", 1) != buf2
181
      || memcmp (buf2, "aBCDEFghijklmnopq\0", 19))
182
    abort ();
183
 
184
  if (memcpy (buf4 + 2, "bcd" + i++, 2) != buf2 + 2
185
      || memcmp (buf2, "aBcdEFghijklmnopq\0", 19)
186
      || i != 2)
187
    abort ();
188
 
189
  /* These might be handled by move_by_pieces.  */
190
  if (memcpy (buf4 + 4, buf7, 6) != buf2 + 4
191
      || memcmp (buf2, "aBcdRSTUVWklmnopq\0", 19))
192
    abort ();
193
 
194
  /* Side effect.  */
195
  if (__builtin___memcpy_chk (buf2 + i++ + 8, buf7 + 1, 1,
196
                              os (buf2 + i++ + 8))
197
      != buf2 + 10
198
      || memcmp (buf2, "aBcdRSTUVWSlmnopq\0", 19)
199
      || i != 3)
200
    abort ();
201
 
202
  if (memcpy (buf4 + 14, buf6, 2) != buf2 + 14
203
      || memcmp (buf2, "aBcdRSTUVWSlmnrsq\0", 19))
204
    abort ();
205
 
206
  __builtin_memcpy (buf4, "aBcdEFghijklmnopq\0", 19);
207
 
208
  /* These should be handled either by movmemendM or memcpy
209
     call.  */
210
  if (memcpy (buf4 + 4, buf7, n + 6) != buf2 + 4
211
      || memcmp (buf2, "aBcdRSTUVWklmnopq\0", 19))
212
    abort ();
213
 
214
  /* Side effect.  */
215
  if (__builtin___memcpy_chk (buf2 + i++ + 8, buf7 + 1, n + 1,
216
                              os (buf2 + i++ + 8))
217
      != buf2 + 11
218
      || memcmp (buf2, "aBcdRSTUVWkSmnopq\0", 19)
219
      || i != 4)
220
    abort ();
221
 
222
  if (memcpy (buf4 + 14, buf6, n + 2) != buf2 + 14
223
      || memcmp (buf2, "aBcdRSTUVWkSmnrsq\0", 19))
224
    abort ();
225
 
226
  if (chk_calls)
227
    abort ();
228
}
229
 
230
void
231
__attribute__((noinline))
232
test2 (void)
233
{
234
  long *x;
235
  char *y;
236
  int z;
237
  __builtin_memcpy (buf5, "RSTUVWXYZ0123456789", 20);
238
  __builtin_memcpy (buf7, "RSTUVWXYZ0123456789", 20);
239
 __asm ("" : "=r" (x) : "0" (buf1));
240
 __asm ("" : "=r" (y) : "0" (buf2));
241
 __asm ("" : "=r" (z) : "0" (0));
242
  test2_sub (x, y, "rstuvwxyz", z);
243
}
244
 
245
/* Test whether compile time checking is done where it should
246
   and so is runtime object size checking.  */
247
void
248
__attribute__((noinline))
249
test3 (void)
250
{
251
  struct A { char buf1[10]; char buf2[10]; } a;
252
  char *r = l1 == 1 ? &a.buf1[5] : &a.buf2[4];
253
  char buf3[20];
254
  int i;
255
  size_t l;
256
 
257
  /* The following calls should do runtime checking
258
     - length is not known, but destination is.  */
259
  chk_calls = 0;
260
  memcpy (a.buf1 + 2, s3, l1);
261
  memcpy (r, s3, l1 + 1);
262
  r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
263
  memcpy (r, s2, l1 + 2);
264
  memcpy (r + 2, s3, l1);
265
  r = buf3;
266
  for (i = 0; i < 4; ++i)
267
    {
268
      if (i == l1 - 1)
269
        r = &a.buf1[1];
270
      else if (i == l1)
271
        r = &a.buf2[7];
272
      else if (i == l1 + 1)
273
        r = &buf3[5];
274
      else if (i == l1 + 2)
275
        r = &a.buf1[9];
276
    }
277
  memcpy (r, s2, l1);
278
  if (chk_calls != 5)
279
    abort ();
280
 
281
  /* Following have known destination and known length,
282
     so if optimizing certainly shouldn't result in the checking
283
     variants.  */
284
  chk_calls = 0;
285
  memcpy (a.buf1 + 2, s3, 1);
286
  memcpy (r, s3, 2);
287
  r = l1 == 1 ? __builtin_alloca (4) : &a.buf2[7];
288
  memcpy (r, s2, 3);
289
  r = buf3;
290
  l = 4;
291
  for (i = 0; i < 4; ++i)
292
    {
293
      if (i == l1 - 1)
294
        r = &a.buf1[1], l = 2;
295
      else if (i == l1)
296
        r = &a.buf2[7], l = 3;
297
      else if (i == l1 + 1)
298
        r = &buf3[5], l = 4;
299
      else if (i == l1 + 2)
300
        r = &a.buf1[9], l = 1;
301
    }
302
  memcpy (r, s2, 1);
303
  /* Here, l is known to be at most 4 and __builtin_object_size (&buf3[16], 0)
304
     is 4, so this doesn't need runtime checking.  */
305
  memcpy (&buf3[16], s2, l);
306
  if (chk_calls)
307
    abort ();
308
  chk_calls = 0;
309
}
310
 
311
/* Test whether runtime and/or compile time checking catches
312
   buffer overflows.  */
313
void
314
__attribute__((noinline))
315
test4 (void)
316
{
317
  struct A { char buf1[10]; char buf2[10]; } a;
318
  char buf3[20];
319
 
320
  chk_fail_allowed = 1;
321
  /* Runtime checks.  */
322
  if (__builtin_setjmp (chk_fail_buf) == 0)
323
    {
324
      memcpy (&a.buf2[9], s2, l1 + 1);
325
      abort ();
326
    }
327
  if (__builtin_setjmp (chk_fail_buf) == 0)
328
    {
329
      memcpy (&a.buf2[7], s3, strlen (s3) + 1);
330
      abort ();
331
    }
332
  /* This should be detectable at compile time already.  */
333
  if (__builtin_setjmp (chk_fail_buf) == 0)
334
    {
335
      memcpy (&buf3[19], "ab", 2);
336
      abort ();
337
    }
338
  chk_fail_allowed = 0;
339
}
340
 
341
#ifndef MAX_OFFSET
342
#define MAX_OFFSET (sizeof (long long))
343
#endif
344
 
345
#ifndef MAX_COPY
346
#define MAX_COPY (10 * sizeof (long long))
347
#endif
348
 
349
#ifndef MAX_EXTRA
350
#define MAX_EXTRA (sizeof (long long))
351
#endif
352
 
353
#define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
354
 
355
/* Use a sequence length that is not divisible by two, to make it more
356
   likely to detect when words are mixed up.  */
357
#define SEQUENCE_LENGTH 31
358
 
359
static union {
360
  char buf[MAX_LENGTH];
361
  long long align_int;
362
  long double align_fp;
363
} u1, u2;
364
 
365
void
366
__attribute__((noinline))
367
test5 (void)
368
{
369
  int off1, off2, len, i;
370
  char *p, *q, c;
371
 
372
  for (off1 = 0; off1 < MAX_OFFSET; off1++)
373
    for (off2 = 0; off2 < MAX_OFFSET; off2++)
374
      for (len = 1; len < MAX_COPY; len++)
375
        {
376
          for (i = 0, c = 'A'; i < MAX_LENGTH; i++, c++)
377
            {
378
              u1.buf[i] = 'a';
379
              if (c >= 'A' + SEQUENCE_LENGTH)
380
                c = 'A';
381
              u2.buf[i] = c;
382
            }
383
 
384
          p = memcpy (u1.buf + off1, u2.buf + off2, len);
385
          if (p != u1.buf + off1)
386
            abort ();
387
 
388
          q = u1.buf;
389
          for (i = 0; i < off1; i++, q++)
390
            if (*q != 'a')
391
              abort ();
392
 
393
          for (i = 0, c = 'A' + off2; i < len; i++, q++, c++)
394
            {
395
              if (c >= 'A' + SEQUENCE_LENGTH)
396
                c = 'A';
397
              if (*q != c)
398
                abort ();
399
            }
400
 
401
          for (i = 0; i < MAX_EXTRA; i++, q++)
402
            if (*q != 'a')
403
              abort ();
404
        }
405
}
406
 
407
#define TESTSIZE 80
408
 
409
char srcb[TESTSIZE] __attribute__ ((aligned));
410
char dstb[TESTSIZE] __attribute__ ((aligned));
411
 
412
void
413
__attribute__((noinline))
414
check (char *test, char *match, int n)
415
{
416
  if (memcmp (test, match, n))
417
    abort ();
418
}
419
 
420
#define TN(n) \
421
{ memset (dstb, 0, n); memcpy (dstb, srcb, n); check (dstb, srcb, n); }
422
#define T(n) \
423
TN (n) \
424
TN ((n) + 1) \
425
TN ((n) + 2) \
426
TN ((n) + 3)
427
 
428
void
429
__attribute__((noinline))
430
test6 (void)
431
{
432
  int i;
433
 
434
  chk_calls = 0;
435
 
436
  for (i = 0; i < sizeof (srcb); ++i)
437
      srcb[i] = 'a' + i % 26;
438
 
439
  T (0);
440
  T (4);
441
  T (8);
442
  T (12);
443
  T (16);
444
  T (20);
445
  T (24);
446
  T (28);
447
  T (32);
448
  T (36);
449
  T (40);
450
  T (44);
451
  T (48);
452
  T (52);
453
  T (56);
454
  T (60);
455
  T (64);
456
  T (68);
457
  T (72);
458
  T (76);
459
 
460
  /* All memcpy calls in this routine have constant arguments.  */
461
  if (chk_calls)
462
    abort ();
463
}
464
 
465
void
466
main_test (void)
467
{
468
#ifndef __OPTIMIZE__
469
  /* Object size checking is only intended for -O[s123].  */
470
  return;
471
#endif
472
  __asm ("" : "=r" (l1) : "0" (l1));
473
  test1 ();
474
  test2 ();
475
  test3 ();
476
  test4 ();
477
  test5 ();
478
  test6 ();
479
}

powered by: WebSVN 2.1.0

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