Class: SeccompTools::Asm::Compiler

Inherits:
Object
  • Object
show all
Defined in:
lib/seccomp-tools/asm/compiler.rb

Overview

Compile seccomp rules.

Instance Method Summary collapse

Constructor Details

#initialize(arch) ⇒ Compiler

Instantiate a SeccompTools::Asm::Compiler object.

Parameters:

  • arch (Symbol)

    Architecture.



17
18
19
20
21
22
23
# File 'lib/seccomp-tools/asm/compiler.rb', line 17

def initialize(arch)
  @arch = arch
  @insts = []
  @labels = {}
  @insts_linenum = {}
  @input = []
end

Instance Method Details

#compile!Array<SeccompTools::BPF>

Compiles the processed instructions.

Returns:

Raises:

  • (ArgumentError)

    Raises the error found during compilation.



66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/seccomp-tools/asm/compiler.rb', line 66

def compile!
  @insts.map.with_index do |inst, idx|
    @line = idx
    case inst.first
    when :assign then compile_assign(inst[1], inst[2])
    when :alu then compile_alu(inst[1], inst[2])
    when :ret then compile_ret(inst[1])
    when :cmp then compile_cmp(inst[1], inst[2], inst[3], inst[4])
    when :jmp_abs then compile_jmp_abs(inst[1])
    end
  end
rescue ArgumentError => e
  invalid(@insts_linenum[@line], e.message)
end

#process(line) ⇒ void

This method returns an undefined value.

Before compile assembly codes, process each lines.

With this we can support label in seccomp rules.

Parameters:

  • line (String)

    One line of seccomp rule.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/seccomp-tools/asm/compiler.rb', line 31

def process(line)
  @input << line.strip
  line = remove_comment(line)
  @token = Tokenizer.new(line)
  return if line.empty?

  begin
    res = case line
          when /\?/ then cmp
          when /^#{Tokenizer::LABEL_REGEXP}:/ then define_label
          when /^return/ then ret
          when /^A\s*=\s*-A/ then alu_neg
          when /^(A|X)\s*=[^=]/ then assign
          when /^mem\[\d+\]\s*=\s*(A|X)/ then store
          when /^A\s*.{1,2}=/ then alu
          when /^(goto|jmp|jump)/ then jmp_abs
          end
  rescue ArgumentError => e
    invalid(@input.size - 1, e.message)
  end
  invalid(@input.size - 1) if res.nil?
  if res.first == :label
    @labels[res.last] = @insts.size
  else
    @insts << res
    @insts_linenum[@insts.size - 1] = @input.size - 1
  end
end