mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 08:26:14 +00:00
87 lines
2.1 KiB
C
87 lines
2.1 KiB
C
#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;
|
|
}
|