1 : /*
2 : * Copyright (c) 2010 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <stdio.h>
8 : #include <stdlib.h>
9 :
10 : #include "native_client/src/include/portability.h"
11 :
12 : #include "native_client/src/shared/platform/nacl_check.h"
13 :
14 : #include "native_client/src/trusted/desc/nrd_all_modules.h"
15 : #include "native_client/src/trusted/gio/gio_shm_unbounded.h"
16 : #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
17 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
18 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
19 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
20 :
21 :
22 : size_t gNumBytes = 10 * NACL_MAP_PAGESIZE;
23 : uint32_t gLinearGeneratorSeed = 0xdeadbeef;
24 :
25 : struct DataGenerator {
26 : void (*Dtor)(struct DataGenerator *self);
27 : uint8_t (*Next)(struct DataGenerator *self);
28 : };
29 :
30 : struct LinearGenerator {
31 : struct DataGenerator base;
32 : uint32_t state;
33 : };
34 :
35 1320996 : uint8_t LinearGeneratorNext(struct DataGenerator *vself) {
36 1320996 : struct LinearGenerator *self = (struct LinearGenerator *) vself;
37 1320996 : uint8_t rv;
38 :
39 1320996 : rv = (uint8_t) (self->state ^ (self->state >> 8) ^ (self->state >> 16));
40 1320996 : self->state = 1664525 * self->state + 1013904223; /* numerical recipies */
41 1320996 : return rv;
42 : }
43 :
44 2 : void LinearGeneratorDtor(struct DataGenerator *vself) {
45 2 : struct LinearGenerator *self = (struct LinearGenerator *) vself;
46 2 : self->base.Dtor = NULL;
47 2 : self->base.Next = NULL;
48 2 : }
49 :
50 2 : void LinearGeneratorCtor(struct LinearGenerator *self) {
51 2 : self->base.Dtor = LinearGeneratorDtor;
52 2 : self->base.Next = LinearGeneratorNext;
53 2 : self->state = gLinearGeneratorSeed;
54 2 : }
55 :
56 1 : size_t FillGioWithGenerator(struct NaClGioShmUnbounded *ngsup,
57 1 : struct DataGenerator *genp,
58 1 : size_t nbytes) {
59 1 : size_t nerrs = 0;
60 1 : size_t ix;
61 1 : uint8_t buf[256];
62 1 : size_t jx;
63 :
64 1 : (*ngsup->base.vtbl->Seek)(&ngsup->base, 0, SEEK_SET);
65 5140 : for (ix = 0; ix < nbytes; ) {
66 5138 : size_t ask;
67 5138 : ssize_t got;
68 :
69 5138 : ask = (*genp->Next)(genp) + 1;
70 5138 : if (ask > (nbytes - ix)) {
71 1 : ask = nbytes - ix;
72 1 : }
73 1320996 : for (jx = 0; jx < ask; ++jx) {
74 655360 : buf[jx] = (*genp->Next)(genp);
75 655360 : NaClLog(5, " %02x\n", buf[jx]);
76 655360 : }
77 5138 : NaClLog(1, "gio_shm_unbounded_test: writing %"NACL_PRIdS" bytes\n", ask);
78 5138 : if ((size_t) (got = (*ngsup->base.vtbl->Write)(&ngsup->base, buf, ask))
79 : != ask) {
80 0 : ++nerrs;
81 0 : NaClLog(LOG_FATAL,
82 : ("gio_shm_unbounded_test: unexpected write return. ask"
83 : " %"NACL_PRIdS" bytes, got %"NACL_PRIdS"\n"),
84 : ask,
85 : got);
86 0 : }
87 5138 : ix += ask;
88 5138 : }
89 1 : return nerrs;
90 : }
91 :
92 1 : size_t CheckGioWithGenerator(struct NaClGioShmUnbounded *ngsup,
93 1 : struct DataGenerator *genp,
94 1 : size_t nbytes) {
95 1 : size_t nerrs = 0;
96 1 : size_t ix;
97 1 : uint8_t buf[256];
98 1 : uint8_t actual[256];
99 1 : size_t jx;
100 :
101 1 : (*ngsup->base.vtbl->Seek)(&ngsup->base, 0, SEEK_SET);
102 5140 : for (ix = 0; ix < nbytes; ) {
103 5138 : size_t ask;
104 5138 : ssize_t got;
105 :
106 5138 : ask = (*genp->Next)(genp) + 1;
107 :
108 5138 : if (ask > (nbytes - ix)) {
109 1 : ask = nbytes - ix;
110 1 : }
111 1320996 : for (jx = 0; jx < ask; ++jx) {
112 655360 : buf[jx] = (*genp->Next)(genp);
113 655360 : NaClLog(5, " %02x\n", buf[jx]);
114 655360 : }
115 5138 : NaClLog(1,
116 : ("gio_shm_unbounded_test: reading %"NACL_PRIdS
117 : " bytes, %"NACL_PRIdS" remains\n"),
118 : ask,
119 : (nbytes - ix));
120 5138 : if ((size_t) (got = (*ngsup->base.vtbl->Read)(&ngsup->base, actual, ask))
121 : != ask) {
122 0 : ++nerrs;
123 0 : NaClLog(LOG_FATAL,
124 : ("gio_shm_unbounded_test: unexpected read return. ask"
125 : " %"NACL_PRIdS" bytes, got %"NACL_PRIdS"\n"),
126 : ask,
127 : got);
128 0 : }
129 1320996 : for (jx = 0; jx < ask; ++jx) {
130 655360 : if (buf[jx] != actual[jx]) {
131 0 : ++nerrs;
132 0 : NaClLog(1,
133 : ("gio_shm_unbounded_test: byte %"NACL_PRIdS" differs:"
134 : " expected 0x%02x, got 0x%02x\n"),
135 : jx,
136 : buf[jx],
137 : actual[jx]);
138 0 : }
139 655360 : }
140 5138 : ix += ask;
141 5138 : }
142 1 : return nerrs;
143 : }
144 :
145 1 : size_t TestWithDataGenerators(struct NaClGioShmUnbounded *ngsup) {
146 1 : size_t nerrs = 0;
147 1 : struct LinearGenerator lg;
148 :
149 1 : LinearGeneratorCtor(&lg);
150 1 : nerrs += FillGioWithGenerator(ngsup, (struct DataGenerator *) &lg, gNumBytes);
151 1 : (*lg.base.Dtor)((struct DataGenerator *) &lg);
152 :
153 1 : LinearGeneratorCtor(&lg);
154 1 : nerrs += CheckGioWithGenerator(ngsup, (struct DataGenerator *) &lg,
155 : gNumBytes);
156 1 : (*lg.base.Dtor)((struct DataGenerator *) &lg);
157 :
158 1 : return nerrs;
159 : }
160 :
161 :
162 1 : int main(int ac, char **av) {
163 1 : int opt;
164 1 : size_t nerrs = 0;
165 1 : struct NaClGioShmUnbounded ngsu;
166 :
167 1 : NaClNrdAllModulesInit();
168 :
169 2 : while (EOF != (opt = getopt(ac, av, "n:s:"))) {
170 0 : switch (opt) {
171 : case 'n':
172 0 : gNumBytes = (size_t) strtoul(optarg, (char **) NULL, 0);
173 0 : break;
174 : case 's':
175 0 : gLinearGeneratorSeed = (uint32_t) strtoul(optarg, (char **) NULL, 0);
176 0 : break;
177 : default:
178 0 : fprintf(stderr,
179 : "Usage: gio_shm_unbounded_test [-n nbytes] [-s seed]\n");
180 0 : return EXIT_FAILURE;
181 : }
182 0 : }
183 :
184 1 : printf("Writing %"NACL_PRIdS" bytes.\n", gNumBytes);
185 1 : printf("Seed %"NACL_PRIu32".\n", gLinearGeneratorSeed);
186 :
187 1 : if (!NaClGioShmUnboundedCtor(&ngsu)) {
188 0 : fprintf(stderr, "NaClGioShmUnboundedCtor failed\n");
189 0 : ++nerrs;
190 0 : goto unrecoverable;
191 : }
192 :
193 1 : nerrs += TestWithDataGenerators(&ngsu);
194 :
195 1 : (*ngsu.base.vtbl->Dtor)(&ngsu.base);
196 :
197 : unrecoverable:
198 1 : NaClNrdAllModulesFini();
199 :
200 1 : printf("%s\n", (0 == nerrs) ? "PASSED" : "FAILED");
201 1 : return (0 == nerrs) ? EXIT_SUCCESS : EXIT_FAILURE;
202 1 : }
|