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 <stdio.h> | 5 #include <stdio.h> |
6 | 6 |
7 #include "sandbox/linux/seccomp-bpf/codegen.h" | 7 #include "sandbox/linux/seccomp-bpf/codegen.h" |
8 | 8 |
9 namespace { | 9 namespace { |
10 | 10 |
11 // Helper function for Traverse(). | 11 // Helper function for Traverse(). |
12 void TraverseRecursively(std::set<playground2::Instruction*>* visited, | 12 void TraverseRecursively(std::set<sandbox::Instruction*>* visited, |
13 playground2::Instruction* instruction) { | 13 sandbox::Instruction* instruction) { |
14 if (visited->find(instruction) == visited->end()) { | 14 if (visited->find(instruction) == visited->end()) { |
15 visited->insert(instruction); | 15 visited->insert(instruction); |
16 switch (BPF_CLASS(instruction->code)) { | 16 switch (BPF_CLASS(instruction->code)) { |
17 case BPF_JMP: | 17 case BPF_JMP: |
18 if (BPF_OP(instruction->code) != BPF_JA) { | 18 if (BPF_OP(instruction->code) != BPF_JA) { |
19 TraverseRecursively(visited, instruction->jf_ptr); | 19 TraverseRecursively(visited, instruction->jf_ptr); |
20 } | 20 } |
21 TraverseRecursively(visited, instruction->jt_ptr); | 21 TraverseRecursively(visited, instruction->jt_ptr); |
22 break; | 22 break; |
23 case BPF_RET: | 23 case BPF_RET: |
24 break; | 24 break; |
25 default: | 25 default: |
26 TraverseRecursively(visited, instruction->next); | 26 TraverseRecursively(visited, instruction->next); |
27 break; | 27 break; |
28 } | 28 } |
29 } | 29 } |
30 } | 30 } |
31 | 31 |
32 } // namespace | 32 } // namespace |
33 | 33 |
34 namespace playground2 { | 34 namespace sandbox { |
35 | 35 |
36 CodeGen::CodeGen() : compiled_(false) {} | 36 CodeGen::CodeGen() : compiled_(false) {} |
37 | 37 |
38 CodeGen::~CodeGen() { | 38 CodeGen::~CodeGen() { |
39 for (Instructions::iterator iter = instructions_.begin(); | 39 for (Instructions::iterator iter = instructions_.begin(); |
40 iter != instructions_.end(); | 40 iter != instructions_.end(); |
41 ++iter) { | 41 ++iter) { |
42 delete *iter; | 42 delete *iter; |
43 } | 43 } |
44 for (BasicBlocks::iterator iter = basic_blocks_.begin(); | 44 for (BasicBlocks::iterator iter = basic_blocks_.begin(); |
45 iter != basic_blocks_.end(); | 45 iter != basic_blocks_.end(); |
46 ++iter) { | 46 ++iter) { |
47 delete *iter; | 47 delete *iter; |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 void CodeGen::PrintProgram(const Sandbox::Program& program) { | 51 void CodeGen::PrintProgram(const SandboxBPF::Program& program) { |
52 for (Sandbox::Program::const_iterator iter = program.begin(); | 52 for (SandboxBPF::Program::const_iterator iter = program.begin(); |
53 iter != program.end(); | 53 iter != program.end(); |
54 ++iter) { | 54 ++iter) { |
55 int ip = (int)(iter - program.begin()); | 55 int ip = (int)(iter - program.begin()); |
56 fprintf(stderr, "%3d) ", ip); | 56 fprintf(stderr, "%3d) ", ip); |
57 switch (BPF_CLASS(iter->code)) { | 57 switch (BPF_CLASS(iter->code)) { |
58 case BPF_LD: | 58 case BPF_LD: |
59 if (iter->code == BPF_LD + BPF_W + BPF_ABS) { | 59 if (iter->code == BPF_LD + BPF_W + BPF_ABS) { |
60 fprintf(stderr, "LOAD %d // ", (int)iter->k); | 60 fprintf(stderr, "LOAD %d // ", (int)iter->k); |
61 if (iter->k == offsetof(struct arch_seccomp_data, nr)) { | 61 if (iter->k == offsetof(struct arch_seccomp_data, nr)) { |
62 fprintf(stderr, "System call number\n"); | 62 fprintf(stderr, "System call number\n"); |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
699 } | 699 } |
700 | 700 |
701 // Proceed to next basic block. | 701 // Proceed to next basic block. |
702 offset += bb->instructions.size(); | 702 offset += bb->instructions.size(); |
703 bb->offset = offset; | 703 bb->offset = offset; |
704 } | 704 } |
705 return; | 705 return; |
706 } | 706 } |
707 | 707 |
708 void CodeGen::ConcatenateBasicBlocks(const BasicBlocks& basic_blocks, | 708 void CodeGen::ConcatenateBasicBlocks(const BasicBlocks& basic_blocks, |
709 Sandbox::Program* program) { | 709 SandboxBPF::Program* program) { |
710 // Our basic blocks have been sorted and relative jump offsets have been | 710 // Our basic blocks have been sorted and relative jump offsets have been |
711 // computed. The last remaining step is for all the instructions in our | 711 // computed. The last remaining step is for all the instructions in our |
712 // basic blocks to be concatenated into a BPF program. | 712 // basic blocks to be concatenated into a BPF program. |
713 program->clear(); | 713 program->clear(); |
714 for (BasicBlocks::const_iterator bb_iter = basic_blocks.begin(); | 714 for (BasicBlocks::const_iterator bb_iter = basic_blocks.begin(); |
715 bb_iter != basic_blocks.end(); | 715 bb_iter != basic_blocks.end(); |
716 ++bb_iter) { | 716 ++bb_iter) { |
717 const BasicBlock& bb = **bb_iter; | 717 const BasicBlock& bb = **bb_iter; |
718 for (Instructions::const_iterator insn_iter = bb.instructions.begin(); | 718 for (Instructions::const_iterator insn_iter = bb.instructions.begin(); |
719 insn_iter != bb.instructions.end(); | 719 insn_iter != bb.instructions.end(); |
720 ++insn_iter) { | 720 ++insn_iter) { |
721 const Instruction& insn = **insn_iter; | 721 const Instruction& insn = **insn_iter; |
722 program->push_back( | 722 program->push_back( |
723 (struct sock_filter) {insn.code, insn.jt, insn.jf, insn.k}); | 723 (struct sock_filter) {insn.code, insn.jt, insn.jf, insn.k}); |
724 } | 724 } |
725 } | 725 } |
726 return; | 726 return; |
727 } | 727 } |
728 | 728 |
729 void CodeGen::Compile(Instruction* instructions, Sandbox::Program* program) { | 729 void CodeGen::Compile(Instruction* instructions, SandboxBPF::Program* program) { |
730 if (compiled_) { | 730 if (compiled_) { |
731 SANDBOX_DIE( | 731 SANDBOX_DIE( |
732 "Cannot call Compile() multiple times. Create a new code " | 732 "Cannot call Compile() multiple times. Create a new code " |
733 "generator instead"); | 733 "generator instead"); |
734 } | 734 } |
735 compiled_ = true; | 735 compiled_ = true; |
736 | 736 |
737 BranchTargets branch_targets; | 737 BranchTargets branch_targets; |
738 FindBranchTargets(*instructions, &branch_targets); | 738 FindBranchTargets(*instructions, &branch_targets); |
739 TargetsToBlocks all_blocks; | 739 TargetsToBlocks all_blocks; |
740 BasicBlock* first_block = | 740 BasicBlock* first_block = |
741 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks); | 741 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks); |
742 MergeTails(&all_blocks); | 742 MergeTails(&all_blocks); |
743 BasicBlocks basic_blocks; | 743 BasicBlocks basic_blocks; |
744 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks); | 744 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks); |
745 ComputeRelativeJumps(&basic_blocks, all_blocks); | 745 ComputeRelativeJumps(&basic_blocks, all_blocks); |
746 ConcatenateBasicBlocks(basic_blocks, program); | 746 ConcatenateBasicBlocks(basic_blocks, program); |
747 return; | 747 return; |
748 } | 748 } |
749 | 749 |
750 } // namespace | 750 } // namespace |
Robert Sesek
2013/12/10 21:52:05
"namespace sandbox"
jln (very slow on Chromium)
2013/12/10 22:01:48
Done.
| |
OLD | NEW |