mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-10 09:26:15 +00:00
120 lines
3.4 KiB
C
120 lines
3.4 KiB
C
/* https://bugs.kde.org/show_bug.cgi?id=309921 */
|
|
|
|
#define _XOPEN_SOURCE 600 /* for posix_memalign() */
|
|
|
|
#include "../../memcheck.h"
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Exercise pcmpistri instruction in a realistic way. */
|
|
int aligned_strlen(const char *const s)
|
|
{
|
|
assert(((unsigned long)s & 0x0F) == 0);
|
|
|
|
const char *p = s;
|
|
|
|
/* volatile asm and "memory" clobber are needed here, since we
|
|
access memory in ways we cannot describe to GCC. */
|
|
__asm__ __volatile__ ("\n1:\n"
|
|
"\tmovdqa (%0),%%xmm6\n"
|
|
"\tpcmpistri $0x3a,%%xmm6,%%xmm6\n"
|
|
"\tjc 2f\n"
|
|
"\tadd $0x10,%0\n"
|
|
"\tjmp 1b\n"
|
|
"2:\n"
|
|
"\tadd %%rcx,%0\n"
|
|
: "=p" (p) : "0" (p) : "xmm6", "rcx", "cc", "memory");
|
|
|
|
return p-s;
|
|
}
|
|
|
|
/* Compute strlen(s). Arrange for result to be valid or invalid
|
|
according to second argument. */
|
|
int test_strlen(const char *const s, int valid)
|
|
{
|
|
/* len = length of string including trailing null */
|
|
const size_t len = strlen(s) + 1;
|
|
const size_t roundup = ((len+15)/16)*16;
|
|
int result = -1;
|
|
|
|
void *space;
|
|
posix_memalign(&space, 16, roundup);
|
|
memset(space, 'x', roundup);
|
|
memcpy(space, s, len);
|
|
|
|
const char *const s_copy = space;
|
|
const unsigned char ff = 0xFF;
|
|
if (valid) {
|
|
/* Mark all bytes beyond the null as invalid. */
|
|
size_t i;
|
|
for (i=len ; i < roundup ; ++i)
|
|
(void)VALGRIND_SET_VBITS(&s_copy[i], &ff, 1);
|
|
}
|
|
else {
|
|
/* Mark the null byte itself as invalid. */
|
|
assert(len > 0);
|
|
(void)VALGRIND_SET_VBITS(&s_copy[len-1], &ff, 1);
|
|
}
|
|
|
|
result = aligned_strlen(s_copy);
|
|
|
|
free(space);
|
|
|
|
return result;
|
|
}
|
|
|
|
void doit(const char *const s)
|
|
{
|
|
printf("strlen(\"%s\")=%d\n", s, test_strlen(s, 1));
|
|
|
|
fprintf(stderr, "strlen(\"%s\")=%s\n", s,
|
|
test_strlen(s, 0) ? "true" : "false");
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
doit("");
|
|
doit("a");
|
|
doit("ab");
|
|
doit("abc");
|
|
doit("abcd");
|
|
doit("abcde");
|
|
doit("abcdef");
|
|
doit("abcdefg");
|
|
/* 8 */
|
|
doit("abcdefgh");
|
|
doit("abcdefghi");
|
|
doit("abcdefghij");
|
|
doit("abcdefghijk");
|
|
doit("abcdefghijkl");
|
|
doit("abcdefghijklm");
|
|
doit("abcdefghijklmn");
|
|
doit("abcdefghijklmno");
|
|
/* 16 */
|
|
doit("abcdefghijklmnop");
|
|
doit("abcdefghijklmnopq");
|
|
doit("abcdefghijklmnopqr");
|
|
doit("abcdefghijklmnopqrs");
|
|
doit("abcdefghijklmnopqrst");
|
|
doit("abcdefghijklmnopqrstu");
|
|
doit("abcdefghijklmnopqrstuv");
|
|
doit("abcdefghijklmnopqrstuvw");
|
|
doit("abcdefghijklmnopqrstuwvx");
|
|
doit("abcdefghijklmnopqrstuwvxy");
|
|
doit("abcdefghijklmnopqrstuwvxyz");
|
|
/* 255 */
|
|
doit("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
|
/* 256 */
|
|
doit("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
|
|
return 0;
|
|
}
|