Home | History | Annotate | Download | only in tests
      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