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 <stdio.h> | 7 #include <stdio.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "sandbox/linux/seccomp-bpf/basicblock.h" | 12 #include "sandbox/linux/seccomp-bpf/basicblock.h" |
13 #include "sandbox/linux/seccomp-bpf/die.h" | 13 #include "sandbox/linux/seccomp-bpf/die.h" |
14 #include "sandbox/linux/seccomp-bpf/instruction.h" | 14 #include "sandbox/linux/seccomp-bpf/instruction.h" |
15 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" | 15 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" |
16 | 16 |
17 namespace { | |
18 | |
19 // Helper function for Traverse(). | |
20 void TraverseRecursively(std::set<sandbox::Instruction*>* visited, | |
21 sandbox::Instruction* instruction) { | |
22 if (visited->find(instruction) == visited->end()) { | |
23 visited->insert(instruction); | |
24 switch (BPF_CLASS(instruction->code)) { | |
25 case BPF_JMP: | |
26 if (BPF_OP(instruction->code) != BPF_JA) { | |
27 TraverseRecursively(visited, instruction->jf_ptr); | |
28 } | |
29 TraverseRecursively(visited, instruction->jt_ptr); | |
30 break; | |
31 case BPF_RET: | |
32 break; | |
33 default: | |
34 TraverseRecursively(visited, instruction->next); | |
35 break; | |
36 } | |
37 } | |
38 } | |
39 | |
40 } // namespace | |
41 | |
42 namespace sandbox { | 17 namespace sandbox { |
43 | 18 |
44 CodeGen::CodeGen() : compiled_(false) {} | 19 CodeGen::CodeGen() : compiled_(false) {} |
45 | 20 |
46 CodeGen::~CodeGen() { | 21 CodeGen::~CodeGen() { |
47 for (Instructions::iterator iter = instructions_.begin(); | 22 for (Instructions::iterator iter = instructions_.begin(); |
48 iter != instructions_.end(); | 23 iter != instructions_.end(); |
49 ++iter) { | 24 ++iter) { |
50 delete *iter; | 25 delete *iter; |
51 } | 26 } |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 SANDBOX_DIE("Expected a BPF_JMP instruction"); | 157 SANDBOX_DIE("Expected a BPF_JMP instruction"); |
183 } | 158 } |
184 if (!jt || !jf) { | 159 if (!jt || !jf) { |
185 SANDBOX_DIE("Branches must jump to a valid instruction"); | 160 SANDBOX_DIE("Branches must jump to a valid instruction"); |
186 } | 161 } |
187 Instruction* insn = new Instruction(code, k, jt, jf); | 162 Instruction* insn = new Instruction(code, k, jt, jf); |
188 instructions_.push_back(insn); | 163 instructions_.push_back(insn); |
189 return insn; | 164 return insn; |
190 } | 165 } |
191 | 166 |
192 void CodeGen::Traverse(Instruction* instruction, | |
193 void (*fnc)(Instruction*, void*), | |
194 void* aux) { | |
195 std::set<Instruction*> visited; | |
196 TraverseRecursively(&visited, instruction); | |
197 for (std::set<Instruction*>::const_iterator iter = visited.begin(); | |
198 iter != visited.end(); | |
199 ++iter) { | |
200 fnc(*iter, aux); | |
201 } | |
202 } | |
203 | |
204 void CodeGen::FindBranchTargets(const Instruction& instructions, | 167 void CodeGen::FindBranchTargets(const Instruction& instructions, |
205 BranchTargets* branch_targets) { | 168 BranchTargets* branch_targets) { |
206 // Follow all possible paths through the "instructions" graph and compute | 169 // Follow all possible paths through the "instructions" graph and compute |
207 // a list of branch targets. This will later be needed to compute the | 170 // a list of branch targets. This will later be needed to compute the |
208 // boundaries of basic blocks. | 171 // boundaries of basic blocks. |
209 // We maintain a set of all instructions that we have previously seen. This | 172 // We maintain a set of all instructions that we have previously seen. This |
210 // set ultimately converges on all instructions in the program. | 173 // set ultimately converges on all instructions in the program. |
211 std::set<const Instruction*> seen_instructions; | 174 std::set<const Instruction*> seen_instructions; |
212 Instructions stack; | 175 Instructions stack; |
213 for (const Instruction* insn = &instructions; insn;) { | 176 for (const Instruction* insn = &instructions; insn;) { |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks); | 689 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks); |
727 MergeTails(&all_blocks); | 690 MergeTails(&all_blocks); |
728 BasicBlocks basic_blocks; | 691 BasicBlocks basic_blocks; |
729 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks); | 692 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks); |
730 ComputeRelativeJumps(&basic_blocks, all_blocks); | 693 ComputeRelativeJumps(&basic_blocks, all_blocks); |
731 ConcatenateBasicBlocks(basic_blocks, program); | 694 ConcatenateBasicBlocks(basic_blocks, program); |
732 return; | 695 return; |
733 } | 696 } |
734 | 697 |
735 } // namespace sandbox | 698 } // namespace sandbox |
OLD | NEW |