| #include "tests/malloc.h" |
| #include <stdio.h> |
| #include <assert.h> |
| |
| typedef unsigned long long int ULong; |
| typedef unsigned long int UWord; |
| |
| __attribute__((noinline)) |
| static int my_ffsll ( ULong x ) |
| { |
| int i; |
| for (i = 0; i < 64; i++) { |
| if ((x & 1ULL) == 1ULL) |
| break; |
| x >>= 1; |
| } |
| return i+1; |
| } |
| |
| /* Find length of string, assuming it is aligned and shorter than 8 |
| characters. Little-endian only. */ |
| __attribute__((noinline)) |
| static int aligned_strlen(char *s) |
| { |
| /* This is for 64-bit platforms */ |
| assert(sizeof(ULong) == 8); |
| /* ..and only works for aligned input */ |
| assert(((unsigned long)s & 0x7) == 0); |
| |
| /* read 8 bytes */ |
| ULong val = *(ULong*)s; |
| /* Subtract one from each byte */ |
| ULong val2 = val - 0x0101010101010101ULL; |
| /* Find lowest byte whose high bit changed */ |
| val2 ^= val; |
| val2 &= 0x8080808080808080ULL; |
| |
| return (my_ffsll(val2) / 8) - 1; |
| } |
| |
| __attribute__((noinline)) void foo ( int x ) |
| { |
| __asm__ __volatile__("":::"memory"); |
| } |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| char *buf = memalign16(5); |
| buf[0] = 'a'; |
| buf[1] = 'b'; |
| buf[2] = 'c'; |
| buf[3] = 'd'; |
| buf[4] = '\0'; |
| |
| /* --partial-loads-ok=no: expect addr error (here) */ |
| /* --partial-loads-ok=yes: expect no error */ |
| if (aligned_strlen(buf) == 4) |
| foo(44); |
| |
| /* --partial-loads-ok=no: expect addr error (here) */ |
| /* --partial-loads-ok=yes: expect value error (in my_ffsll) */ |
| buf[4] = 'x'; |
| if (aligned_strlen(buf) == 0) |
| foo(37); |
| |
| free(buf); |
| |
| /* Also, we need to check that a completely out-of-range, |
| word-sized load gives an addressing error regardless of the |
| start of --partial-loads-ok=. *And* that the resulting |
| value is completely defined. */ |
| UWord* words = malloc(3 * sizeof(UWord)); |
| free(words); |
| |
| /* Should ALWAYS give an addr error. */ |
| UWord w = words[1]; |
| |
| /* Should NEVER give an error (you might expect a value one, but no.) */ |
| if (w == 0x31415927) { |
| fprintf(stderr, |
| "Elvis is alive and well and living in Milton Keynes.\n"); |
| } |
| |
| return 0; |
| } |