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/] [memmove-chk.c] - Blame information for rev 688

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

powered by: WebSVN 2.1.0

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