1 #include "tests/malloc.h"
2 #include <stdio.h>
3 #include <assert.h>
4 
5 typedef  unsigned long long int  ULong;
6 typedef  unsigned long int       UWord;
7 
8 __attribute__((noinline))
9 static int my_ffsll ( ULong x )
10 {
11    int i;
12    for (i = 0; i < 64; i++) {
13       if ((x & 1ULL) == 1ULL)
14          break;
15       x >>= 1;
16    }
17    return i+1;
18 }
19 
20 /* Find length of string, assuming it is aligned and shorter than 8
21    characters.  Little-endian only. */
22 __attribute__((noinline))
23 static int aligned_strlen(char *s)
24 {
25     /* This is for 64-bit platforms */
26     assert(sizeof(ULong) == 8);
27     /* ..and only works for aligned input */
28     assert(((unsigned long)s & 0x7) == 0);
29 
30     /* read 8 bytes */
31     ULong val = *(ULong*)s;
32     /* Subtract one from each byte */
33     ULong val2 = val - 0x0101010101010101ULL;
34     /* Find lowest byte whose high bit changed */
35     val2 ^= val;
36     val2 &= 0x8080808080808080ULL;
37 
38     return (my_ffsll(val2) / 8) - 1;
39 }
40 
41 __attribute__((noinline)) void foo ( int x )
42 {
43    __asm__ __volatile__("":::"memory");
44 }
45 
46 int
47 main(int argc, char *argv[])
48 {
49     char *buf = memalign16(5);
50     buf[0] = 'a';
51     buf[1] = 'b';
52     buf[2] = 'c';
53     buf[3] = 'd';
54     buf[4] = '\0';
55 
56     /* --partial-loads-ok=no:  expect addr error (here) */
57     /* --partial-loads-ok=yes: expect no error */
58     if (aligned_strlen(buf) == 4)
59         foo(44);
60 
61     /* --partial-loads-ok=no:  expect addr error (here) */
62     /* --partial-loads-ok=yes: expect value error (in my_ffsll) */
63     buf[4] = 'x';
64     if (aligned_strlen(buf) == 0)
65         foo(37);
66 
67     free(buf);
68 
69     /* Also, we need to check that a completely out-of-range,
70        word-sized load gives an addressing error regardless of the
71        start of --partial-loads-ok=.  *And* that the resulting
72        value is completely defined. */
73     UWord* words = malloc(3 * sizeof(UWord));
74     free(words);
75 
76     /* Should ALWAYS give an addr error. */
77     UWord  w     = words[1];
78 
79     /* Should NEVER give an error (you might expect a value one, but no.) */
80     if (w == 0x31415927) {
81        fprintf(stderr,
82                "Elvis is alive and well and living in Milton Keynes.\n");
83     }
84 
85     return 0;
86 }
87