]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a regtest for #126147.
authorJulian Seward <jseward@acm.org>
Tue, 14 Nov 2006 15:50:44 +0000 (15:50 +0000)
committerJulian Seward <jseward@acm.org>
Tue, 14 Nov 2006 15:50:44 +0000 (15:50 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6352

none/tests/x86/Makefile.am
none/tests/x86/bug126147-x86.c [new file with mode: 0644]
none/tests/x86/bug126147-x86.stderr.exp [new file with mode: 0644]
none/tests/x86/bug126147-x86.stdout.exp [new file with mode: 0644]
none/tests/x86/bug126147-x86.vgtest [new file with mode: 0644]

index dd9ea2c7f470a07d1c598d5fc7ad774fb2259365..508b27f659ba30d7e88392a8f253fdac7cd24802 100644 (file)
@@ -9,6 +9,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        bt_everything.stderr.exp bt_everything.stdout.exp bt_everything.vgtest \
        bt_literal.stderr.exp bt_literal.stdout.exp bt_literal.vgtest \
        bug125959-x86.stderr.exp bug125959-x86.stdout.exp bug125959-x86.vgtest \
+       bug126147-x86.stderr.exp bug126147-x86.stdout.exp bug126147-x86.vgtest \
        bug132813-x86.stderr.exp bug132813-x86.stdout.exp bug132813-x86.vgtest \
        cpuid.stderr.exp cpuid.stdout.exp cpuid.vgtest \
        cmpxchg8b.stderr.exp cmpxchg8b.stdout.exp cmpxchg8b.vgtest \
@@ -36,6 +37,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
 check_PROGRAMS = \
        badseg bt_everything bt_literal \
        bug125959-x86 \
+       bug126147-x86 \
        bug132813-x86 \
        cmpxchg8b cpuid \
        faultstatus fcmovnu fpu_lazy_eflags fxtract \
diff --git a/none/tests/x86/bug126147-x86.c b/none/tests/x86/bug126147-x86.c
new file mode 100644 (file)
index 0000000..5477348
--- /dev/null
@@ -0,0 +1,211 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* These fns taken from dietlibc-0.30 (is GPL v2'd) */
+
+/*
+  Copyright (C) 2002 Thomas M. Ogrisegg
+
+  This is free software. You can redistribute and
+  modify it under the terms of the GNU General Public
+  Public License.
+
+  strncpy.S
+    i386 assembler implementation of strncpy(3)
+*/
+extern char *mystrncpy(char *dest, const char *src, size_t n);
+asm(
+".text\n"
+".globl mystrncpy\n"
+".type mystrncpy,@function\n"
+"\n"
+"mystrncpy:\n"
+"      pushl %esi\n"
+"      pushl %edi\n"
+"      movl %esp, %ecx\n"
+"      movl  0x0c(%ecx), %edi\n"
+"      movl  0x10(%ecx), %esi\n"
+"      movl  0x14(%ecx), %ecx\n"
+"\n"
+"      movl %edi, %edx\n"
+"      cld\n"
+".Lzzloop:\n"
+"      dec %ecx\n"
+"      js .Lzzout\n"
+"      lodsb\n"
+"      stosb\n"
+"      or %al, %al\n"
+"      jnz .Lzzloop\n"
+"      repnz stosb\n"
+".Lzzout:\n"
+"      movl %edx, %eax\n"
+"      popl %edi\n"
+"      popl %esi\n"
+"      ret\n"
+".previous\n"
+"\n"
+);
+
+
+/*
+   Copyright (C) 2002 Thomas M. Ogrisegg
+
+   __ltostr.S -- convert an integer into a string
+
+ %eax = dividend
+ %ebx = divisor
+ %ecx = size of output-buffer
+ %edi = output-buffer
+ %ebp = if uppercase is set, then %ebp is 'A'-10 else %ebp is 'a'-10
+
+*/
+extern int __ltostr(char *s, unsigned int size, unsigned long i, 
+                             unsigned int base, int UpCase);
+asm(
+".text\n"
+".globl __ltostr\n"
+"__ltostr:\n"
+"        pushl %esi\n"
+"        pushl %edi              # destination\n"
+"        pushl %ebp\n"
+"        pushl %ebx\n"
+"        movl %esp, %eax\n"
+"        movl 0x14(%eax), %edi\n"
+"        movl 0x18(%eax), %ecx   # size\n"
+"        movl 0x20(%eax), %ebx   # divisor\n"
+"        movl 0x1c(%eax), %eax   # dividend\n"
+"        decl %ecx\n"
+"        movl %ecx, %esi\n"
+"        movl $('A'-0xa), %ebp\n"
+"        xorl %edx, %edx         # must be 0 -- used by idiv\n"
+"        cmpl $0x0, 36(%esp)     # check for uppercase\n"
+"        jnz .Lyynext\n"
+"        addl $0x20, %ebp        # set lowercase\n"
+".Lyynext:\n"
+"        idiv %ebx, %eax\n"
+"        cmpb $0x9, %dl\n"
+"        jg .Lyynext2\n"
+"        addb $'0', %dl\n"
+"        jmp .Lyystos\n"
+".Lyynext2:\n"
+"        addl %ebp, %edx\n"
+".Lyystos:\n"
+"        movb %dl, (%edi, %ecx)\n"
+"        xorl %edx, %edx\n"
+"        decl %ecx\n"
+"        jz .Lyyout\n"
+"        orl %eax, %eax\n"
+"        jnz .Lyynext\n"
+".Lyyout:\n"
+"        cld\n"
+"        movl %esi, %ebx\n"
+"        leal 1(%edi, %ecx), %esi\n"
+"        subl %ebx, %ecx\n"
+"        negl %ecx\n"
+"        movl %ecx, %eax\n"
+"        repnz movsb\n"
+"        movb $0x0, (%edi)\n"
+"        popl %ebx\n"
+"        popl %ebp\n"
+"        popl %edi\n"
+"        popl %esi\n"
+"        ret\n"
+".previous\n"
+);
+
+#define STREQ(a, b)     (strcmp((a), (b)) == 0)
+
+const char *it = "<UNSET>";     /* Routine name for message routines. */
+size_t errors = 0;
+
+/* Complain if condition is not true.  */
+static void
+check (int thing, int number)
+{
+  if (!thing)
+    {
+      printf("%s flunked test %d\n", it, number);
+      ++errors;
+    }
+}
+
+/* Complain if first two args don't strcmp as equal.  */
+static void
+equal (const char *a, const char *b, int number)
+{
+  check(a != NULL && b != NULL && STREQ (a, b), number);
+}
+
+char one[50];
+char two[50];
+char *cp;
+
+static void
+test_strncpy (void)
+{
+  /* Testing is a bit different because of odd semantics.  */
+  it = "strncpy";
+  check (mystrncpy (one, "abc", 4) == one, 1);    /* Returned value. */
+  equal (one, "abc", 2);                        /* Did the copy go right? */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) mystrncpy (one, "xyz", 2);
+  equal (one, "xycdefgh", 3);                   /* Copy cut by count. */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) mystrncpy (one, "xyz", 3);               /* Copy cut just before NUL. */
+  equal (one, "xyzdefgh", 4);
+
+  (void) strcpy (one, "abcdefgh");
+  (void) mystrncpy (one, "xyz", 4);               /* Copy just includes NUL. */
+  equal (one, "xyz", 5);
+  equal (one+4, "efgh", 6);                     /* Wrote too much? */
+
+  (void) strcpy (one, "abcdefgh");
+  (void) mystrncpy (one, "xyz", 5);               /* Copy includes padding. */
+  equal (one, "xyz", 7);
+  equal (one+4, "", 8);
+  equal (one+5, "fgh", 9);
+
+  (void) strcpy (one, "abc");
+  (void) mystrncpy (one, "xyz", 0);               /* Zero-length copy. */
+  equal (one, "abc", 10);
+
+  (void) mystrncpy (one, "", 2);          /* Zero-length source. */
+  equal (one, "", 11);
+  equal (one+1, "", 12);
+  equal (one+2, "c", 13);
+
+  (void) strcpy (one, "hi there");
+  (void) mystrncpy (two, one, 9);
+  equal (two, "hi there", 14);          /* Just paranoia. */
+  equal (one, "hi there", 15);          /* Stomped on source? */
+}
+
+
+int main ( void )
+{
+  char buf[1024];
+
+  /* test strncpy, hence repnz stosb */
+  test_strncpy();
+    if (errors == 0)
+    {
+      printf("No errors.\n");
+    }
+  else
+    {
+      printf("%d errors.\n", (int)errors);
+    }
+
+    /* test __ltostr, hence repnz stosb */ 
+  assert(__ltostr(buf,10,1723,10,0)==4); assert(!strcmp(buf,"1723"));
+  assert(__ltostr(buf,3,1723,10,0)==2); assert(!strcmp(buf,"23"));
+  assert(__ltostr(buf,2,0x1234,16,0)==1); assert(!strcmp(buf,"4"));
+  assert(__ltostr(buf,3,0xFEFE,16,1)==2); assert(!strcmp(buf,"FE"));
+
+ return 0;
+}
diff --git a/none/tests/x86/bug126147-x86.stderr.exp b/none/tests/x86/bug126147-x86.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/x86/bug126147-x86.stdout.exp b/none/tests/x86/bug126147-x86.stdout.exp
new file mode 100644 (file)
index 0000000..8c92275
--- /dev/null
@@ -0,0 +1 @@
+No errors.
diff --git a/none/tests/x86/bug126147-x86.vgtest b/none/tests/x86/bug126147-x86.vgtest
new file mode 100644 (file)
index 0000000..26fc22b
--- /dev/null
@@ -0,0 +1 @@
+prog: bug126147-x86