summaryrefslogtreecommitdiffstats
path: root/private/ntos/rtl/alpha/tmovmem.c
blob: 3b381d9ba64c0d642a001637283154e95f5d42e1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*++

Copyright (c) 1993  Digital Equipment Corporation

Module Name:

    tmovmem.c

Abstract:

    This module implements a test of the operation of the RtlMoveMemory
    function by running an exhaustive test of every case of string offset,
    move length, and relative overlap of the two strings up to and a little
    beyond one 32-byte cache line. This represents several hundred thousand
    test cases. It is assumed any bugs that exist will be found within this
    range. If only the error count summary is desired, type "tmovmem > nul"
    instead.

Author:

    Thomas Van Baak (tvb) 13-Jan-1993

Environment:

    User mode.

Revision History:

--*/

#include <nt.h>
#include <ntrtl.h>
#include <stdio.h>
#include "localrtl.h"

//
// Two strings are defined within a large buffer. The target string is
// initially below the source string with a small gap between the two
// strings. A margin around the strings ensures any bytes accidentally
// changed outside the strings are detectable. As the length of the strings
// and the offset of the source string are varied, the target string wanders
// from well below, through, and well above the source string.
//

#define MIN_OVERLAP (-(MAX_LENGTH + MAX_MARGIN))
#define MAX_OVERLAP (MAX_LENGTH + MAX_MARGIN - 1)

#define BUFFER_SIZE (MAX_MARGIN + MAX_LENGTH + MAX_MARGIN + MAX_OFFSET + MAX_LENGTH + MAX_MARGIN + MAX_LENGTH + MAX_MARGIN)

UCHAR Buffer0[BUFFER_SIZE];
UCHAR Buffer1[BUFFER_SIZE];
UCHAR Buffer2[BUFFER_SIZE];

void
_CRTAPI1
main()
{
    ULONG ErrorCount;
    ULONG Length;
    ULONG Offset;
    LONG Overlap;
    ULONG Result;
    ULONG Source;
    ULONG Target;
    ULONG TestCases;

    fprintf(stderr, "Testing RtlMoveMemory\n");
    ErrorCount = 0;
    TestCases = 0;

    //
    // Make a call to RtlMoveMemory for all possible source string offsets
    // within a cache line, for a large set of string lengths, and a wide
    // range of positions of the target string relative to the source string,
    // including all possible overlapping string configurations.
    //

    for (Offset = 0; Offset <= MAX_OFFSET; Offset += 1) {
        for (Length = 0; Length <= MAX_LENGTH; Length += 1) {
            for (Overlap = MIN_OVERLAP; Overlap <= MAX_OVERLAP; Overlap += 1) {

                //
                // The same string configuration is made in two different
                // buffers. RtlMoveMemory is used on the two strings in one
                // buffer and the trusted LocalMoveMemory on the two strings
                // in the other buffer. The entire buffers are compared to
                // determine if the two move functions agree.
                //

                FillPattern(Buffer1, BUFFER_SIZE);
                FillPattern(Buffer2, BUFFER_SIZE);

                Source = MAX_MARGIN + MAX_LENGTH + MAX_MARGIN + Offset;
                Target = Source + Overlap;

                LocalMoveMemory(&Buffer1[Target], &Buffer1[Source], Length);
                RtlMoveMemory(&Buffer2[Target], &Buffer2[Source], Length);

                Result = LocalCompareMemory(Buffer1, Buffer2, BUFFER_SIZE);

                TestCases += 1;
                if (Result != BUFFER_SIZE) {
                    ErrorCount += 1;

                    printf("ERROR: Offset = %d, Length = %d, Overlap = %d\n",
                           Offset, Length, Overlap);
                    printf("RtlMoveMemory( &Buffer[ %d ], &Buffer[ %d ], %d )\n",
                           Target, Source, Length);

                    FillPattern(Buffer0, BUFFER_SIZE);
                    printf("  Original Source = %lx: <%.*s>\n",
                           &Buffer0[Source], Length, &Buffer0[Source]);
                    printf("  Expected Target = %lx: <%.*s>\n",
                           &Buffer1[Target], Length, &Buffer1[Target]);
                    printf("  Actual Target   = %lx: <%.*s>\n",
                           &Buffer2[Target], Length, &Buffer2[Target]);
                    printf("\n");
                    printf("Buffers differ starting at byte %d:\n", Result);
                    printf("Buffer1 = <%*s>\n", BUFFER_SIZE, Buffer1);
                    printf("Buffer2 = <%*s>\n", BUFFER_SIZE, Buffer2);
                    printf("\n");
                }
            }
        }
    }

    fprintf(stderr, "Test of RtlMoveMemory completed: ");
    fprintf(stderr, "%d test cases, %d errors found.\n", TestCases, ErrorCount);
}