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

Unified Diff: sandbox/linux/seccomp-bpf/codegen.h

Issue 754433003: Update from https://crrev.com/305340 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc ('k') | sandbox/linux/seccomp-bpf/codegen.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sandbox/linux/seccomp-bpf/codegen.h
diff --git a/sandbox/linux/seccomp-bpf/codegen.h b/sandbox/linux/seccomp-bpf/codegen.h
index fd229f7b8e2ad5f823dd86ffd474b5f143276b07..bca404694d3c042cfc9118c5013ddbad8855bb51 100644
--- a/sandbox/linux/seccomp-bpf/codegen.h
+++ b/sandbox/linux/seccomp-bpf/codegen.h
@@ -5,28 +5,23 @@
#ifndef SANDBOX_LINUX_SECCOMP_BPF_CODEGEN_H__
#define SANDBOX_LINUX_SECCOMP_BPF_CODEGEN_H__
+#include <stddef.h>
#include <stdint.h>
#include <map>
#include <vector>
+#include "base/macros.h"
+#include "base/tuple.h"
#include "sandbox/sandbox_export.h"
struct sock_filter;
namespace sandbox {
-struct BasicBlock;
-struct Instruction;
-
-typedef std::vector<Instruction*> Instructions;
-typedef std::vector<BasicBlock*> BasicBlocks;
-typedef std::map<const Instruction*, int> BranchTargets;
-typedef std::map<const Instruction*, BasicBlock*> TargetsToBlocks;
-typedef std::map<const BasicBlock*, int> IncomingBranches;
// The code generator implements a basic assembler that can convert a
// graph of BPF instructions into a well-formed array of BPF
-// instructions. Most notably, it ensures that jumps are always
+// instructions. Most notably, it ensures that jumps are always
// forward and don't exceed the limit of 255 instructions imposed by
// the instruction set.
//
@@ -62,19 +57,18 @@ class SANDBOX_EXPORT CodeGen {
typedef std::vector<struct sock_filter> Program;
// Node represents a node within the instruction DAG being compiled.
- // Nodes are owned by the CodeGen object and need not be explicitly
- // deleted.
- using Node = Instruction*;
+ using Node = Program::size_type;
// kNullNode represents the "null" node; i.e., the reserved node
// value guaranteed to not equal any actual nodes.
- static const Node kNullNode;
+ static const Node kNullNode = -1;
CodeGen();
~CodeGen();
// MakeInstruction creates a node representing the specified
- // instruction. For details on the possible parameters refer to
+ // instruction, or returns and existing equivalent node if one
+ // exists. For details on the possible parameters refer to
// https://www.kernel.org/doc/Documentation/networking/filter.txt.
// TODO(mdempsky): Reconsider using default arguments here.
Node MakeInstruction(uint16_t code,
@@ -82,72 +76,39 @@ class SANDBOX_EXPORT CodeGen {
Node jt = kNullNode,
Node jf = kNullNode);
- // Compile linearizes the instruction DAG into a BPF program that
- // can be executed by a BPF virtual machine. Please note that this
- // function modifies the graph in place and must therefore only be
- // called once per graph.
+ // Compile linearizes the instruction DAG rooted at |head| into a
+ // program that can be executed by a BPF virtual machine.
void Compile(Node head, Program* program);
private:
- friend class CodeGenUnittestHelper;
-
- // Find all the instructions that are the target of BPF_JMPs.
- void FindBranchTargets(const Instruction& instructions,
- BranchTargets* branch_targets);
-
- // Combine instructions between "head" and "tail" into a new basic block.
- // Basic blocks are defined as sequences of instructions whose only branch
- // target is the very first instruction; furthermore, any BPF_JMP or BPF_RET
- // instruction must be at the very end of the basic block.
- BasicBlock* MakeBasicBlock(Instruction* head, Instruction* tail);
-
- // Creates a basic block and adds it to "basic_blocks"; sets "first_block"
- // if it is still NULL.
- void AddBasicBlock(Instruction* head,
- Instruction* tail,
- const BranchTargets& branch_targets,
- TargetsToBlocks* basic_blocks,
- BasicBlock** first_block);
-
- // Cuts the DAG of instructions into basic blocks.
- BasicBlock* CutGraphIntoBasicBlocks(Instruction* instructions,
- const BranchTargets& branch_targets,
- TargetsToBlocks* blocks);
-
- // Find common tail sequences of basic blocks and coalesce them.
- void MergeTails(TargetsToBlocks* blocks);
-
- // For each basic block, compute the number of incoming branches.
- void ComputeIncomingBranches(BasicBlock* block,
- const TargetsToBlocks& targets_to_blocks,
- IncomingBranches* incoming_branches);
-
- // Topologically sort the basic blocks so that all jumps are forward jumps.
- // This is a requirement for any well-formed BPF program.
- void TopoSortBasicBlocks(BasicBlock* first_block,
- const TargetsToBlocks& blocks,
- BasicBlocks* basic_blocks);
-
- // Convert jt_ptr_ and jf_ptr_ fields in BPF_JMP instructions to valid
- // jt_ and jf_ jump offsets. This can result in BPF_JA instructions being
- // inserted, if we need to jump over more than 256 instructions.
- void ComputeRelativeJumps(BasicBlocks* basic_blocks,
- const TargetsToBlocks& targets_to_blocks);
-
- // Concatenate instructions from all basic blocks into a BPF program that
- // can be passed to the kernel.
- void ConcatenateBasicBlocks(const BasicBlocks&, Program* program);
-
- // We stick all instructions and basic blocks into pools that get destroyed
- // when the CodeGen object is destroyed. This way, we neither need to worry
- // about explicitly managing ownership, nor do we need to worry about using
- // smart pointers in the presence of circular references.
- Instructions instructions_;
- BasicBlocks basic_blocks_;
-
- // Compile() must only ever be called once as it makes destructive changes
- // to the DAG.
- bool compiled_;
+ using MemoKey = Tuple4<uint16_t, uint32_t, Node, Node>;
+ struct MemoKeyLess {
+ bool operator()(const MemoKey& lhs, const MemoKey& rhs) const;
+ };
+
+ // AppendInstruction adds a new instruction, ensuring that |jt| and
+ // |jf| are within range as necessary for |code|.
+ Node AppendInstruction(uint16_t code, uint32_t k, Node jt, Node jf);
+
+ // WithinRange returns a node equivalent to |next| that is at most
+ // |range| instructions away from the (logical) beginning of the
+ // program.
+ Node WithinRange(Node next, size_t range);
+
+ // Append appends a new instruction to the physical end (i.e.,
+ // logical beginning) of |program_|.
+ Node Append(uint16_t code, uint32_t k, size_t jt, size_t jf);
+
+ // Offset returns how many instructions exist in |program_| after |target|.
+ size_t Offset(Node target) const;
+
+ // NOTE: program_ is the compiled program in *reverse*, so that
+ // indices remain stable as we add instructions.
+ Program program_;
+
+ std::map<MemoKey, Node, MemoKeyLess> memos_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeGen);
};
} // namespace sandbox
« no previous file with comments | « sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc ('k') | sandbox/linux/seccomp-bpf/codegen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698