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

Side by Side Diff: sandbox/linux/seccomp-bpf/codegen_unittest.cc

Issue 699633003: CodeGen: rewrite implementation [3/3] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@codegen-api-2
Patch Set: Use size_t instead of uint32_t as semantically appropriate Created 6 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/seccomp-bpf/codegen.h" 5 #include "sandbox/linux/seccomp-bpf/codegen.h"
6 6
7 #include <linux/filter.h> 7 #include <linux/filter.h>
8 8
9 #include <cstring> 9 #include <cstring>
10 #include <map> 10 #include <map>
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 106
107 // MakeInstruction calls CodeGen::MakeInstruction() and associated 107 // MakeInstruction calls CodeGen::MakeInstruction() and associated
108 // the returned address with a hash of the instruction. 108 // the returned address with a hash of the instruction.
109 CodeGen::Addr MakeInstruction(uint16_t code, 109 CodeGen::Addr MakeInstruction(uint16_t code,
110 uint32_t k, 110 uint32_t k,
111 CodeGen::Addr jt = CodeGen::kNullAddr, 111 CodeGen::Addr jt = CodeGen::kNullAddr,
112 CodeGen::Addr jf = CodeGen::kNullAddr) { 112 CodeGen::Addr jf = CodeGen::kNullAddr) {
113 CodeGen::Addr res = gen_.MakeInstruction(code, k, jt, jf); 113 CodeGen::Addr res = gen_.MakeInstruction(code, k, jt, jf);
114 EXPECT_NE(CodeGen::kNullAddr, res); 114 EXPECT_NE(CodeGen::kNullAddr, res);
115 115
116 Hash digest; 116 Hash digest(code, k, Lookup(jt), Lookup(jf));
117 if (code == BPF_JMP + BPF_JA) {
118 // TODO(mdempsky): Disallow use of JA.
119 digest = Lookup(jt);
120 } else {
121 digest = Hash(code, k, Lookup(jt), Lookup(jf));
122 }
123 auto it = addr_hashes_.insert(std::make_pair(res, digest)); 117 auto it = addr_hashes_.insert(std::make_pair(res, digest));
124 EXPECT_EQ(digest, it.first->second); 118 EXPECT_EQ(digest, it.first->second);
125 119
126 return res; 120 return res;
127 } 121 }
128 122
129 // RunTest compiles the program and verifies that the output matches 123 // RunTest compiles the program and verifies that the output matches
130 // what is expected. It should be called at the end of each program 124 // what is expected. It should be called at the end of each program
131 // test case. 125 // test case.
132 void RunTest(CodeGen::Addr head) { 126 void RunTest(CodeGen::Addr head) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 // the same object, we do not actually have any "mergeable" branches. 198 // the same object, we do not actually have any "mergeable" branches.
205 // This needs to be reflected in our choice of "flags". 199 // This needs to be reflected in our choice of "flags".
206 RunTest(head); 200 RunTest(head);
207 } 201 }
208 202
209 TEST_F(ProgramTest, Complex) { 203 TEST_F(ProgramTest, Complex) {
210 // Creates a basic BPF program that we'll use to test some of the code: 204 // Creates a basic BPF program that we'll use to test some of the code:
211 // JUMP if eq 42 the $0 else $1 (insn6) 205 // JUMP if eq 42 the $0 else $1 (insn6)
212 // 0: LD 23 (insn5) 206 // 0: LD 23 (insn5)
213 // 1: JUMP if eq 42 then $2 else $4 (insn4) 207 // 1: JUMP if eq 42 then $2 else $4 (insn4)
214 // 2: JUMP to $3 (insn2) 208 // 2: JUMP to $3 (insn2)
rickyz (no longer on Chrome) 2014/11/12 23:43:50 Update this comment now that we got rid of the jum
mdempsky 2014/11/18 01:07:30 So my reasoning was this is the description of the
215 // 3: LD 42 (insn1) 209 // 3: LD 42 (insn1)
216 // RET 42 (insn0) 210 // RET 42 (insn0)
217 // 4: LD 42 (insn3) 211 // 4: LD 42 (insn3)
218 // RET 42 (insn3+) 212 // RET 42 (insn3+)
219 CodeGen::Addr insn0 = MakeInstruction(BPF_RET + BPF_K, 42); 213 CodeGen::Addr insn0 = MakeInstruction(BPF_RET + BPF_K, 42);
220 CodeGen::Addr insn1 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42, insn0); 214 CodeGen::Addr insn1 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42, insn0);
221 CodeGen::Addr insn2 = MakeInstruction(BPF_JMP + BPF_JA, 0, insn1); 215 CodeGen::Addr insn2 = insn1; // Implicit JUMP
222 216
223 // We explicitly duplicate instructions so that MergeTails() can coalesce 217 // We explicitly duplicate instructions to check that CodeGen merges them.
224 // them later.
225 CodeGen::Addr insn3 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42, 218 CodeGen::Addr insn3 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 42,
226 MakeInstruction(BPF_RET + BPF_K, 42)); 219 MakeInstruction(BPF_RET + BPF_K, 42));
220 EXPECT_EQ(insn2, insn3);
227 221
228 CodeGen::Addr insn4 = 222 CodeGen::Addr insn4 =
229 MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, insn2, insn3); 223 MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 42, insn2, insn3);
230 CodeGen::Addr insn5 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 23, insn4); 224 CodeGen::Addr insn5 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 23, insn4);
231 225
232 // Force a basic block that ends in neither a jump instruction nor a return 226 // Force a basic block that ends in neither a jump instruction nor a return
233 // instruction. It only contains "insn5". This exercises one of the less 227 // instruction. It only contains "insn5". This exercises one of the less
234 // common code paths in the topo-sort algorithm. 228 // common code paths in the topo-sort algorithm.
235 // This also gives us a diamond-shaped pattern in our graph, which stresses 229 // This also gives us a diamond-shaped pattern in our graph, which stresses
236 // another aspect of the topo-sort algorithm (namely, the ability to 230 // another aspect of the topo-sort algorithm (namely, the ability to
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 CodeGen::Addr i5 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7); 309 CodeGen::Addr i5 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7);
316 CodeGen::Addr i4 = MakeInstruction(BPF_RET + BPF_K, 42); 310 CodeGen::Addr i4 = MakeInstruction(BPF_RET + BPF_K, 42);
317 CodeGen::Addr i3 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5); 311 CodeGen::Addr i3 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5);
318 CodeGen::Addr i2 = MakeInstruction(BPF_RET + BPF_K, 42); 312 CodeGen::Addr i2 = MakeInstruction(BPF_RET + BPF_K, 42);
319 CodeGen::Addr i1 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3); 313 CodeGen::Addr i1 = MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3);
320 CodeGen::Addr i0 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1); 314 CodeGen::Addr i0 = MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1);
321 315
322 RunTest(i0); 316 RunTest(i0);
323 } 317 }
324 318
319 TEST_F(ProgramTest, InstructionFolding) {
320 // Check that simple instructions are folded as expected.
321 CodeGen::Addr a = MakeInstruction(BPF_RET + BPF_K, 0);
322 EXPECT_EQ(a, MakeInstruction(BPF_RET + BPF_K, 0));
323 CodeGen::Addr b = MakeInstruction(BPF_RET + BPF_K, 1);
324 EXPECT_EQ(a, MakeInstruction(BPF_RET + BPF_K, 0));
325 EXPECT_EQ(b, MakeInstruction(BPF_RET + BPF_K, 1));
326 EXPECT_EQ(b, MakeInstruction(BPF_RET + BPF_K, 1));
327
328 // Check that complex sequences are folded too.
329 CodeGen::Addr c =
330 MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0,
331 MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, 0x100, a, b));
332 EXPECT_EQ(c, MakeInstruction(
333 BPF_LD + BPF_W + BPF_ABS, 0,
334 MakeInstruction(BPF_JMP + BPF_JSET + BPF_K, 0x100, a, b)));
335
336 RunTest(c);
337 }
338
325 } // namespace 339 } // namespace
rickyz (no longer on Chrome) 2014/11/12 23:43:50 Can you add a test that calls MakeInstruction with
mdempsky 2014/11/18 01:07:30 Done.
326 } // namespace sandbox 340 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698