// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SANDBOX_LINUX_BPF_DSL_CODEGEN_H__
#define SANDBOX_LINUX_BPF_DSL_CODEGEN_H__

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <tuple>
#include <vector>

#include "base/macros.h"
#include "sandbox/sandbox_export.h"

struct sock_filter;

namespace sandbox {

// 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
// forward and don't exceed the limit of 255 instructions imposed by
// the instruction set.
//
// Callers would typically create a new CodeGen object and then use it
// to build a DAG of instruction nodes. They'll eventually call
// Compile() to convert this DAG to a Program.
//
//   CodeGen gen;
//   CodeGen::Node allow, branch, dag;
//
//   allow =
//     gen.MakeInstruction(BPF_RET+BPF_K,
//                         ErrorCode(ErrorCode::ERR_ALLOWED).err()));
//   branch =
//     gen.MakeInstruction(BPF_JMP+BPF_EQ+BPF_K, __NR_getpid,
//                         Trap(GetPidHandler, NULL), allow);
//   dag =
//     gen.MakeInstruction(BPF_LD+BPF_W+BPF_ABS,
//                         offsetof(struct arch_seccomp_data, nr), branch);
//
//   // Simplified code follows; in practice, it is important to avoid calling
//   // any C++ destructors after starting the sandbox.
//   CodeGen::Program program = gen.Compile(dag);
//   const struct sock_fprog prog = {
//     static_cast<unsigned short>(program.size()), &program[0] };
//   prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
//
class SANDBOX_EXPORT CodeGen {
 public:
  // A vector of BPF instructions that need to be installed as a filter
  // program in the kernel.
  typedef std::vector<struct sock_filter> Program;

  // Node represents a node within the instruction DAG being compiled.
  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 = -1;

  CodeGen();
  ~CodeGen();

  // MakeInstruction creates a node representing the specified
  // 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,
                       uint32_t k,
                       Node jt = kNullNode,
                       Node jf = kNullNode);

  // Compile linearizes the instruction DAG rooted at |head| into a
  // program that can be executed by a BPF virtual machine.
  Program Compile(Node head);

 private:
  using MemoKey = std::tuple<uint16_t, uint32_t, Node, Node>;

  // 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_;

  // equivalent_ stores the most recent semantically-equivalent node for each
  // instruction in program_. A node is defined as semantically-equivalent to N
  // if it has the same instruction code and constant as N and its successor
  // nodes (if any) are semantically-equivalent to N's successor nodes, or
  // if it's an unconditional jump to a node semantically-equivalent to N.
  std::vector<Node> equivalent_;

  std::map<MemoKey, Node> memos_;

  DISALLOW_COPY_AND_ASSIGN(CodeGen);
};

}  // namespace sandbox

#endif  // SANDBOX_LINUX_BPF_DSL_CODEGEN_H__
