OLD | NEW |
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 <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 // Exhaustively test branch offsets near BPF's limits. | 360 // Exhaustively test branch offsets near BPF's limits. |
361 for (size_t jt = 250; jt < 260; ++jt) { | 361 for (size_t jt = 250; jt < 260; ++jt) { |
362 for (size_t jf = 250; jf < 260; ++jf) { | 362 for (size_t jf = 250; jf < 260; ++jf) { |
363 nodes.push_back(MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 0, | 363 nodes.push_back(MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 0, |
364 nodes.rbegin()[jt], nodes.rbegin()[jf])); | 364 nodes.rbegin()[jt], nodes.rbegin()[jf])); |
365 RunTest(nodes.back()); | 365 RunTest(nodes.back()); |
366 } | 366 } |
367 } | 367 } |
368 } | 368 } |
369 | 369 |
| 370 TEST_F(ProgramTest, JumpReuse) { |
| 371 // As a code size optimization, we try to reuse jumps when possible |
| 372 // instead of emitting new ones. Here we make sure that optimization |
| 373 // is working as intended. |
| 374 // |
| 375 // NOTE: To simplify testing, we rely on implementation details |
| 376 // about what CodeGen::Node values indicate (i.e., vector indices), |
| 377 // but CodeGen users should treat them as opaque values. |
| 378 |
| 379 // Populate with 260 initial instruction nodes. |
| 380 std::vector<CodeGen::Node> nodes; |
| 381 nodes.push_back(MakeInstruction(BPF_RET + BPF_K, 0)); |
| 382 for (size_t i = 1; i < 260; ++i) { |
| 383 nodes.push_back( |
| 384 MakeInstruction(BPF_ALU + BPF_ADD + BPF_K, i, nodes.back())); |
| 385 } |
| 386 |
| 387 // Branching to nodes[0] and nodes[1] should require 3 new |
| 388 // instructions: two far jumps plus the branch itself. |
| 389 CodeGen::Node one = |
| 390 MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 0, nodes[0], nodes[1]); |
| 391 EXPECT_EQ(nodes.back() + 3, one); // XXX: Implementation detail! |
| 392 RunTest(one); |
| 393 |
| 394 // Branching again to the same target nodes should require only one |
| 395 // new instruction, as we can reuse the previous branch's jumps. |
| 396 CodeGen::Node two = |
| 397 MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, nodes[0], nodes[1]); |
| 398 EXPECT_EQ(one + 1, two); // XXX: Implementation detail! |
| 399 RunTest(two); |
| 400 } |
| 401 |
370 } // namespace | 402 } // namespace |
371 } // namespace sandbox | 403 } // namespace sandbox |
OLD | NEW |