| 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 |