Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: src/trusted/validator/validation_cache_test.cc

Issue 9535001: Add validation caching interface. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: More edits Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2012 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 "gtest/gtest.h"
8
9 #include "native_client/src/include/nacl_compiler_annotations.h"
10 #include "native_client/src/shared/platform/nacl_log.h"
11 #include "native_client/src/trusted/validator/ncvalidate.h"
12 #include "native_client/src/trusted/validator/validation_cache.h"
13
14 #define CODE_SIZE 32
15
16 const char nop[CODE_SIZE+1] =
17 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
18 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
19
20 // ret
21 const char ret[CODE_SIZE+1] =
22 "\xc3\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
23 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
24
25 // pblendw $0xc0,%xmm0,%xmm2
26 const char sse41[CODE_SIZE+1] =
27 "\x66\x0f\x3a\x0e\xd0\xc0\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
28 "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90";
29
30 struct MockContext {
31 /* Sanity check that we're getting the right object. */
32 int marker;
33 int query_result;
34 int set_validates_expected;
35 int query_destroyed;
36 };
37
38 enum MockQueryState {
39 QUERY_CREATED,
40 QUERY_GET,
41 QUERY_SET,
42 QUERY_DESTROYED
43 };
44
45 struct MockQuery {
46 /* Sanity check that we're getting the right object. */
47 int marker;
48 MockQueryState state;
49 int add_count;
50 MockContext *context;
51 };
52
53 void *MockCreateQuery(void *handle) {
54 MockContext *mcontext = (MockContext *) handle;
55 MockQuery *mquery = (MockQuery *) malloc(sizeof(MockQuery));
56 EXPECT_EQ(31, mcontext->marker);
57 mquery->marker = 37;
58 mquery->state = QUERY_CREATED;
59 mquery->add_count = 0;
60 mquery->context = mcontext;
61 return mquery;
62 }
63
64 void MockAddData(void *query, const unsigned char *data, size_t length) {
65 MockQuery *mquery = (MockQuery *) query;
66 ASSERT_EQ(37, mquery->marker);
67 UNREFERENCED_PARAMETER(data);
68 EXPECT_EQ(QUERY_CREATED, mquery->state);
69 /* Small data is supicious. */
70 EXPECT_LE((size_t) 2, length);
71 mquery->add_count += 1;
72 }
73
74 int MockQueryCodeValidates(void *query) {
75 MockQuery *mquery = (MockQuery *) query;
76 EXPECT_EQ(37, mquery->marker);
77 EXPECT_EQ(QUERY_CREATED, mquery->state);
78 /* Less than two pieces of data is suspicious. */
79 EXPECT_LE(2, mquery->add_count);
80 mquery->state = QUERY_GET;
81 return mquery->context->query_result;
82 }
83
84 void MockSetCodeValidates(void *query) {
85 MockQuery *mquery = (MockQuery *) query;
86 ASSERT_EQ(37, mquery->marker);
87 EXPECT_EQ(QUERY_GET, mquery->state);
88 EXPECT_EQ(1, mquery->context->set_validates_expected);
89 mquery->state = QUERY_SET;
90 }
91
92 void MockDestroyQuery(void *query) {
93 MockQuery *mquery = (MockQuery *) query;
94 ASSERT_EQ(37, mquery->marker);
95 if (mquery->context->set_validates_expected) {
96 EXPECT_EQ(QUERY_SET, mquery->state);
97 } else {
98 EXPECT_EQ(QUERY_GET, mquery->state);
99 }
100 mquery->state = QUERY_DESTROYED;
101 mquery->context->query_destroyed = 1;
102 free(mquery);
103 }
104
105 class ValidationCachingInterfaceTests : public ::testing::Test {
106 protected:
107 MockContext context;
108 NaClValidationCache cache;
109 NaClCPUFeatures cpu_features;
110 int bundle_size;
111
112 unsigned char code_buffer[32];
113
114 void SetUp() {
115 context.marker = 31;
116 context.query_result = 1;
117 context.set_validates_expected = 0;
118 context.query_destroyed = 0;
119
120 cache.handle = &context;
121 cache.CreateQuery = MockCreateQuery;
122 cache.AddData = MockAddData;
123 cache.QueryCodeValidates = MockQueryCodeValidates;
124 cache.SetCodeValidates = MockSetCodeValidates;
125 cache.DestroyQuery = MockDestroyQuery;
126
127 NaClSetAllCPUFeatures(&cpu_features);
128
129 bundle_size = 32;
130
131 memset(code_buffer, 0x90, 32);
132 }
133
134 NaClValidationStatus Validate() {
135 return NACL_SUBARCH_NAME(ApplyValidator,
136 NACL_TARGET_ARCH,
137 NACL_TARGET_SUBARCH)(
138 NACL_SB_DEFAULT,
139 NaClApplyCodeValidation,
140 0, code_buffer, 32,
141 bundle_size, &cpu_features,
142 &cache);
143 }
144 };
145
146 TEST_F(ValidationCachingInterfaceTests, Sanity) {
147 void *query = cache.CreateQuery(cache.handle);
148 cache.AddData(query, 0, 6);
149 cache.AddData(query, 0, 128);
150 EXPECT_EQ(1, cache.QueryCodeValidates(query));
151 cache.DestroyQuery(query);
152 EXPECT_EQ(1, context.query_destroyed);
153 }
154
155 TEST_F(ValidationCachingInterfaceTests, NoCache) {
156 NaClValidationStatus status =
157 NACL_SUBARCH_NAME(ApplyValidator,
158 NACL_TARGET_ARCH,
159 NACL_TARGET_SUBARCH)(
160 NACL_SB_DEFAULT,
161 NaClApplyCodeValidation,
162 0, code_buffer, CODE_SIZE,
163 bundle_size, &cpu_features,
164 NULL);
165 EXPECT_EQ(NaClValidationSucceeded, status);
166 }
167
168 TEST_F(ValidationCachingInterfaceTests, CacheHit) {
169 NaClValidationStatus status = Validate();
170 EXPECT_EQ(NaClValidationSucceeded, status);
171 EXPECT_EQ(1, context.query_destroyed);
172 }
173
174 TEST_F(ValidationCachingInterfaceTests, CacheMiss) {
175 context.query_result = 0;
176 context.set_validates_expected = 1;
177 NaClValidationStatus status = Validate();
178 EXPECT_EQ(NaClValidationSucceeded, status);
179 EXPECT_EQ(1, context.query_destroyed);
180 }
181
182 TEST_F(ValidationCachingInterfaceTests, SSE4Allowed) {
183 memcpy(code_buffer, sse41, CODE_SIZE);
184 context.query_result = 0;
185 context.set_validates_expected = 1;
186 NaClValidationStatus status = Validate();
187 EXPECT_EQ(NaClValidationSucceeded, status);
188 EXPECT_EQ(1, context.query_destroyed);
189 }
190
191 TEST_F(ValidationCachingInterfaceTests, SSE4Stubout) {
192 memcpy(code_buffer, sse41, CODE_SIZE);
193 context.query_result = 0;
194 NaClSetCPUFeature(&cpu_features, NaClCPUFeature_SSE41, 0);
195 NaClValidationStatus status = Validate();
196 EXPECT_EQ(NaClValidationSucceeded, status);
197 EXPECT_EQ(1, context.query_destroyed);
198 }
199
200 TEST_F(ValidationCachingInterfaceTests, IllegalInst) {
201 memcpy(code_buffer, ret, CODE_SIZE);
202 context.query_result = 0;
203 NaClValidationStatus status = Validate();
204 EXPECT_EQ(NaClValidationFailed, status);
205 EXPECT_EQ(1, context.query_destroyed);
206 }
207
208 TEST_F(ValidationCachingInterfaceTests, IllegalCacheHit) {
209 memcpy(code_buffer, ret, CODE_SIZE);
210 NaClValidationStatus status = Validate();
211 // Success proves the cache shortcircuted validation.
212 EXPECT_EQ(NaClValidationSucceeded, status);
213 EXPECT_EQ(1, context.query_destroyed);
214 }
215
216 // Test driver function.
217 int main(int argc, char *argv[]) {
218 // The IllegalInst test touches the log mutex deep inside the validator.
219 // This causes an SEH exception to be thrown on Windows if the mutex is not
220 // initialized.
221 // http://code.google.com/p/nativeclient/issues/detail?id=1696
222 NaClLogModuleInit();
223 testing::InitGoogleTest(&argc, argv);
224 return RUN_ALL_TESTS();
225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698