evoasm 0.0.2.pre7 → 0.1.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gdbinit +41 -0
- data/.gitignore +1 -2
- data/.gitmodules +3 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.md +660 -0
- data/Makefile +1 -1
- data/README.md +17 -9
- data/Rakefile +39 -107
- data/bin/gdb +1 -1
- data/bin/gdb_loop +4 -0
- data/docs/FindingInstructions.md +17 -0
- data/docs/JIT.md +14 -0
- data/docs/SymbolicRegression.md +102 -0
- data/docs/Visualization.md +29 -0
- data/docs/examples/bit_insts.rb +44 -0
- data/docs/examples/jit.rb +26 -0
- data/docs/examples/loss.gif +0 -0
- data/docs/examples/program.png +0 -0
- data/docs/examples/sym_reg.rb +64 -0
- data/docs/examples/vis.rb +38 -0
- data/evoasm.gemspec +21 -15
- data/ext/evoasm_ext/Rakefile +3 -0
- data/ext/evoasm_ext/compile.rake +35 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
- data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
- data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
- data/lib/evoasm.rb +28 -11
- data/lib/evoasm/buffer.rb +105 -0
- data/lib/evoasm/capstone.rb +100 -0
- data/lib/evoasm/domain.rb +116 -0
- data/lib/evoasm/error.rb +37 -16
- data/lib/evoasm/exception_error.rb +19 -0
- data/lib/evoasm/ffi_ext.rb +53 -0
- data/lib/evoasm/libevoasm.rb +286 -0
- data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
- data/lib/evoasm/parameter.rb +20 -0
- data/lib/evoasm/population.rb +145 -0
- data/lib/evoasm/population/parameters.rb +227 -0
- data/lib/evoasm/population/plotter.rb +89 -0
- data/lib/evoasm/prng.rb +64 -0
- data/lib/evoasm/program.rb +195 -12
- data/lib/evoasm/program/io.rb +144 -0
- data/lib/evoasm/test.rb +8 -0
- data/lib/evoasm/version.rb +1 -1
- data/lib/evoasm/x64.rb +115 -0
- data/lib/evoasm/x64/cpu_state.rb +95 -0
- data/lib/evoasm/x64/instruction.rb +109 -0
- data/lib/evoasm/x64/operand.rb +156 -0
- data/lib/evoasm/x64/parameters.rb +211 -0
- data/test/helpers/population_helper.rb +128 -0
- data/test/helpers/test_helper.rb +1 -0
- data/test/helpers/x64_helper.rb +24 -0
- data/test/integration/bitwise_reverse_test.rb +41 -0
- data/test/integration/gcd_test.rb +52 -0
- data/test/integration/popcnt_test.rb +46 -0
- data/test/integration/sym_reg_test.rb +68 -0
- data/test/unit/evoasm/buffer_test.rb +48 -0
- data/test/unit/evoasm/capstone_test.rb +18 -0
- data/test/unit/evoasm/domain_test.rb +55 -0
- data/test/unit/evoasm/population/parameters_test.rb +106 -0
- data/test/unit/evoasm/population_test.rb +96 -0
- data/test/unit/evoasm/prng_test.rb +47 -0
- data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
- data/test/unit/evoasm/x64/encoding_test.rb +320 -0
- data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
- data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
- data/test/unit/evoasm/x64/instruction_test.rb +62 -0
- data/test/unit/evoasm/x64/parameters_test.rb +65 -0
- data/test/unit/evoasm/x64_test.rb +52 -0
- metadata +195 -89
- data/Gemfile.rake +0 -8
- data/Gemfile.rake.lock +0 -51
- data/LICENSE.txt +0 -373
- data/data/tables/README.md +0 -19
- data/data/tables/x64.csv +0 -1684
- data/data/templates/evoasm-x64.c.erb +0 -319
- data/data/templates/evoasm-x64.h.erb +0 -126
- data/examples/abs.yml +0 -20
- data/examples/popcnt.yml +0 -17
- data/examples/sym_reg.yml +0 -26
- data/exe/evoasm-search +0 -13
- data/ext/evoasm_ext/evoasm-alloc.c +0 -145
- data/ext/evoasm_ext/evoasm-alloc.h +0 -59
- data/ext/evoasm_ext/evoasm-arch.c +0 -44
- data/ext/evoasm_ext/evoasm-arch.h +0 -161
- data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
- data/ext/evoasm_ext/evoasm-buf.c +0 -130
- data/ext/evoasm_ext/evoasm-buf.h +0 -47
- data/ext/evoasm_ext/evoasm-error.c +0 -31
- data/ext/evoasm_ext/evoasm-error.h +0 -75
- data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
- data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
- data/ext/evoasm_ext/evoasm-log.h +0 -69
- data/ext/evoasm_ext/evoasm-misc.c +0 -23
- data/ext/evoasm_ext/evoasm-misc.h +0 -282
- data/ext/evoasm_ext/evoasm-param.h +0 -37
- data/ext/evoasm_ext/evoasm-search.c +0 -2145
- data/ext/evoasm_ext/evoasm-search.h +0 -214
- data/ext/evoasm_ext/evoasm-util.h +0 -40
- data/ext/evoasm_ext/evoasm-x64.c +0 -275624
- data/ext/evoasm_ext/evoasm-x64.h +0 -5436
- data/ext/evoasm_ext/evoasm.c +0 -7
- data/ext/evoasm_ext/evoasm.h +0 -23
- data/ext/evoasm_ext/evoasm_ext.c +0 -1757
- data/ext/evoasm_ext/extconf.rb +0 -31
- data/lib/evoasm/cli.rb +0 -6
- data/lib/evoasm/cli/search.rb +0 -127
- data/lib/evoasm/core_ext.rb +0 -1
- data/lib/evoasm/core_ext/array.rb +0 -9
- data/lib/evoasm/core_ext/integer.rb +0 -10
- data/lib/evoasm/core_ext/kwstruct.rb +0 -13
- data/lib/evoasm/core_ext/range.rb +0 -5
- data/lib/evoasm/examples.rb +0 -27
- data/lib/evoasm/gen.rb +0 -8
- data/lib/evoasm/gen/enum.rb +0 -169
- data/lib/evoasm/gen/name_util.rb +0 -80
- data/lib/evoasm/gen/state.rb +0 -176
- data/lib/evoasm/gen/state_dsl.rb +0 -152
- data/lib/evoasm/gen/strio.rb +0 -27
- data/lib/evoasm/gen/translator.rb +0 -1102
- data/lib/evoasm/gen/version.rb +0 -5
- data/lib/evoasm/gen/x64.rb +0 -237
- data/lib/evoasm/gen/x64/funcs.rb +0 -495
- data/lib/evoasm/gen/x64/inst.rb +0 -781
- data/lib/evoasm/search.rb +0 -40
- data/lib/evoasm/tasks/gen_task.rb +0 -86
- data/lib/evoasm/tasks/template_task.rb +0 -52
- data/test/test_helper.rb +0 -1
- data/test/x64/test_helper.rb +0 -19
- data/test/x64/x64_test.rb +0 -87
data/lib/evoasm.rb
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
require 'evoasm/version'
|
|
2
|
-
require 'evoasm/core_ext'
|
|
3
2
|
|
|
4
3
|
module Evoasm
|
|
5
|
-
def self.
|
|
4
|
+
def self.root_dir
|
|
6
5
|
File.expand_path File.join(__dir__, '..')
|
|
7
6
|
end
|
|
8
7
|
|
|
9
|
-
def self.
|
|
10
|
-
File.join
|
|
8
|
+
def self.data_dir
|
|
9
|
+
File.join root_dir, 'data'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.test_dir
|
|
13
|
+
File.join root_dir, 'test'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.data_dir
|
|
17
|
+
File.join root_dir, 'data'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.ext_dir
|
|
21
|
+
File.join root_dir, 'ext'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.log_level=(log_level)
|
|
25
|
+
Libevoasm.set_log_level log_level
|
|
11
26
|
end
|
|
12
|
-
end
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
p e
|
|
28
|
+
def self.architecture
|
|
29
|
+
Libevoasm.get_current_arch
|
|
30
|
+
end
|
|
18
31
|
end
|
|
19
32
|
|
|
20
|
-
require 'evoasm/
|
|
21
|
-
require 'evoasm/program'
|
|
33
|
+
require 'evoasm/libevoasm'
|
|
22
34
|
require 'evoasm/error'
|
|
35
|
+
|
|
36
|
+
Evoasm::Libevoasm.init(0, FFI::Pointer::NULL, FFI::Pointer::NULL)
|
|
37
|
+
|
|
38
|
+
require 'evoasm/population'
|
|
39
|
+
require 'evoasm/buffer'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'evoasm/exception_error'
|
|
2
|
+
|
|
3
|
+
module Evoasm
|
|
4
|
+
# Represents an executable area of memory
|
|
5
|
+
class Buffer < FFI::AutoPointer
|
|
6
|
+
|
|
7
|
+
# @!visibility private
|
|
8
|
+
def self.release(ptr)
|
|
9
|
+
Libevoasm.buf_destroy(ptr)
|
|
10
|
+
Libevoasm.buf_free(ptr)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @param capacity [Integer] the buffer's capacity in bytes
|
|
14
|
+
# @param type [:mmap, :malloc] the buffer type, only buffers created with +:mmap+ are executable
|
|
15
|
+
def initialize(capacity, type = :mmap)
|
|
16
|
+
ptr = Libevoasm.buf_alloc
|
|
17
|
+
unless Libevoasm.buf_init ptr, type, capacity
|
|
18
|
+
Libevoasm.buf_free ptr
|
|
19
|
+
raise Error.last
|
|
20
|
+
end
|
|
21
|
+
super(ptr)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @!attribute [r] capacity
|
|
25
|
+
# @return [Integer] the buffer's capacity
|
|
26
|
+
def capacity
|
|
27
|
+
Libevoasm.buf_get_capa self
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @!attribute [r] position
|
|
31
|
+
# @return [Integer] the buffer cursor's current position
|
|
32
|
+
def position
|
|
33
|
+
Libevoasm.buf_get_pos self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Resets the buffers position to zero
|
|
37
|
+
# @return [void]
|
|
38
|
+
def reset
|
|
39
|
+
Libevoasm.buf_reset self
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @!attribute [r] type
|
|
43
|
+
# @return [:mmap, :malloc] the buffer's current position
|
|
44
|
+
def type
|
|
45
|
+
Libevoasm.buf_get_type self
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Gives the buffer's content as string
|
|
49
|
+
# @return [String]
|
|
50
|
+
def to_s
|
|
51
|
+
ptr = Libevoasm.buf_get_data self
|
|
52
|
+
ptr.read_string capacity
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @!visibility private
|
|
56
|
+
def __log__(log_level)
|
|
57
|
+
Libevoasm.buf_log self, log_level
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Writes data into the buffer and advances the buffer position
|
|
61
|
+
# @param data [String] the data to write into the buffer
|
|
62
|
+
def write(data)
|
|
63
|
+
data_ptr = FFI::MemoryPointer.new :uint8, data.size
|
|
64
|
+
data_ptr.write_string data
|
|
65
|
+
|
|
66
|
+
if Libevoasm.buf_write(self, data_ptr, data.size) != 0
|
|
67
|
+
raise Error.last
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Executes the buffer's content.
|
|
72
|
+
# @raise [ExceptionError] if a hardware exception occurred
|
|
73
|
+
def execute!
|
|
74
|
+
begin
|
|
75
|
+
|
|
76
|
+
unless Libevoasm.buf_protect self, :rx
|
|
77
|
+
raise Error.last
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
current_arch = Libevoasm.get_current_arch
|
|
81
|
+
return_value = nil
|
|
82
|
+
exception_enum = Libevoasm.enum_type(:"#{current_arch}_exception")
|
|
83
|
+
# catch everything
|
|
84
|
+
exception_mask = exception_enum.flags(exception_enum.symbols, shift: true)
|
|
85
|
+
|
|
86
|
+
#FIXME: should be intptr_t, but FFI sucks
|
|
87
|
+
return_value_ptr = FFI::MemoryPointer.new :size_t, 1
|
|
88
|
+
|
|
89
|
+
success = Libevoasm.buf_safe_exec(self, exception_mask, return_value_ptr)
|
|
90
|
+
return_value = return_value_ptr.read_size_t
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
if success
|
|
94
|
+
return return_value
|
|
95
|
+
else
|
|
96
|
+
raise ExceptionError.new(current_arch, exception_enum[return_value])
|
|
97
|
+
end
|
|
98
|
+
ensure
|
|
99
|
+
unless Libevoasm.buf_protect self, :rw
|
|
100
|
+
raise Error.last
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'ffi'
|
|
2
|
+
|
|
3
|
+
module Evoasm
|
|
4
|
+
|
|
5
|
+
# @!visibility private
|
|
6
|
+
module Capstone
|
|
7
|
+
class Error < StandardError; end
|
|
8
|
+
|
|
9
|
+
module Libcapstone
|
|
10
|
+
extend FFI::Library
|
|
11
|
+
|
|
12
|
+
ffi_lib ['capstone', 'libcapstone.so.3']
|
|
13
|
+
|
|
14
|
+
class Insn < FFI::Struct
|
|
15
|
+
layout :id, :uint,
|
|
16
|
+
:address, :uint64,
|
|
17
|
+
:size, :uint16,
|
|
18
|
+
:bytes, [:uchar, 16],
|
|
19
|
+
:mnemonic, [:char, 32],
|
|
20
|
+
:op_str, [:char, 160],
|
|
21
|
+
:detail, :pointer
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
enum :cs_mode, [
|
|
25
|
+
:mode_64, 1 << 3
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
enum :cs_arch, [
|
|
29
|
+
:arch_x86, 3
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
enum :cs_err, [
|
|
33
|
+
:err_ok, 0,
|
|
34
|
+
:err_mem,
|
|
35
|
+
:err_arch,
|
|
36
|
+
:err_handle,
|
|
37
|
+
:err_csh,
|
|
38
|
+
:err_mode,
|
|
39
|
+
:err_option,
|
|
40
|
+
:err_detail,
|
|
41
|
+
:err_memsetup,
|
|
42
|
+
:err_version,
|
|
43
|
+
:err_diet,
|
|
44
|
+
:err_skipdata,
|
|
45
|
+
:err_x86_att,
|
|
46
|
+
:err_x86_intel,
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
typedef :pointer, :cs_insn
|
|
50
|
+
typedef :size_t, :csh
|
|
51
|
+
typedef :pointer, :csh_ptr
|
|
52
|
+
|
|
53
|
+
attach_function :cs_close, [:csh_ptr], :cs_err
|
|
54
|
+
attach_function :cs_open, [:cs_arch, :cs_mode, :csh_ptr], :cs_err
|
|
55
|
+
attach_function :cs_strerror, [:cs_err], :string
|
|
56
|
+
attach_function :cs_free, [:pointer, :size_t], :void
|
|
57
|
+
attach_function :cs_disasm, [:csh, :pointer, :size_t, :uint64, :size_t, :pointer], :size_t
|
|
58
|
+
attach_function :cs_errno, [:csh], :cs_err
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.disassemble_x64(asm, addr = nil)
|
|
62
|
+
result = []
|
|
63
|
+
handle_ptr = FFI::MemoryPointer.new(:size_t, 1)
|
|
64
|
+
|
|
65
|
+
err = Libcapstone.cs_open :arch_x86, :mode_64, handle_ptr
|
|
66
|
+
if err != :err_ok
|
|
67
|
+
raise Error, cs_strerror(err);
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
handle = handle_ptr.read_size_t
|
|
71
|
+
|
|
72
|
+
insns_ptr = FFI::MemoryPointer.new :pointer
|
|
73
|
+
count = Libcapstone.cs_disasm(handle, asm, asm.bytesize, addr ? addr : 0, 0, insns_ptr)
|
|
74
|
+
insns = insns_ptr.read_pointer
|
|
75
|
+
if count > 0
|
|
76
|
+
count.times do |c|
|
|
77
|
+
insn_ptr = insns + c * Libcapstone::Insn.size
|
|
78
|
+
insn = Libcapstone::Insn.new insn_ptr
|
|
79
|
+
line = []
|
|
80
|
+
line << insn[:address] if addr
|
|
81
|
+
line << insn[:mnemonic].to_s << insn[:op_str].to_s
|
|
82
|
+
result << line
|
|
83
|
+
end
|
|
84
|
+
err = :err_ok
|
|
85
|
+
else
|
|
86
|
+
err = Libcapstone.cs_errno handle
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
Libcapstone.cs_free insns, count
|
|
90
|
+
Libcapstone.cs_close handle_ptr
|
|
91
|
+
|
|
92
|
+
if err != :err_ok
|
|
93
|
+
raise Error, Libcapstone.cs_strerror(err);
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
result
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
require 'evoasm/ffi_ext'
|
|
2
|
+
require 'evoasm/prng'
|
|
3
|
+
|
|
4
|
+
module Evoasm
|
|
5
|
+
# @!visibility private
|
|
6
|
+
class Domain < FFI::AutoPointer
|
|
7
|
+
class << self
|
|
8
|
+
def release(ptr)
|
|
9
|
+
Libevoasm.domain_free ptr
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def wrap(ptr)
|
|
13
|
+
type = Libevoasm.domain_get_type ptr
|
|
14
|
+
case type
|
|
15
|
+
when :enum
|
|
16
|
+
EnumerationDomain.new_from_pointer ptr
|
|
17
|
+
when :range
|
|
18
|
+
RangeDomain.new_from_pointer ptr
|
|
19
|
+
when :int8, :int16, :int32, :int64
|
|
20
|
+
TypeDomain.new_from_pointer ptr
|
|
21
|
+
else
|
|
22
|
+
raise "invalid domain type #{type}"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def for(value)
|
|
27
|
+
case value
|
|
28
|
+
when self
|
|
29
|
+
value
|
|
30
|
+
when Range
|
|
31
|
+
RangeDomain.new value.min, value.max
|
|
32
|
+
when Array
|
|
33
|
+
EnumerationDomain.new *value
|
|
34
|
+
else
|
|
35
|
+
raise ArgumentError, "cannot convert into domain"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
protected
|
|
40
|
+
|
|
41
|
+
alias new_from_pointer new
|
|
42
|
+
|
|
43
|
+
def new(type, var_args)
|
|
44
|
+
ptr = Libevoasm.domain_alloc
|
|
45
|
+
success = Libevoasm.domain_init ptr, type, *var_args
|
|
46
|
+
|
|
47
|
+
if success
|
|
48
|
+
super(ptr)
|
|
49
|
+
else
|
|
50
|
+
Libevoasm.domain_free ptr
|
|
51
|
+
raise Error.last
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def rand(prng = PRNG.default)
|
|
57
|
+
Libevoasm.domain_rand self, prng
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def bounds
|
|
61
|
+
return nil if is_a?(EnumerationDomain)
|
|
62
|
+
|
|
63
|
+
min = FFI::MemoryPointer.new :int64
|
|
64
|
+
max = FFI::MemoryPointer.new :int64
|
|
65
|
+
|
|
66
|
+
Libevoasm.domain_get_bounds self, min, max
|
|
67
|
+
|
|
68
|
+
[min.read_int64, max.read_int64]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def min
|
|
72
|
+
bounds[0]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def max
|
|
76
|
+
bounds[1]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# @!visibility private
|
|
81
|
+
class EnumerationDomain < Domain
|
|
82
|
+
def self.new(*values)
|
|
83
|
+
values = values.flatten
|
|
84
|
+
var_args = [:uint, values.size, *values.flat_map { |v| [:int64, v]}]
|
|
85
|
+
super(:enum, var_args)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def length
|
|
89
|
+
Libevoasm.enum_domain_get_len self
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def values
|
|
93
|
+
Array.new(length) do |index|
|
|
94
|
+
Libevoasm.enum_domain_get_val self, index
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @!visibility private
|
|
100
|
+
class RangeDomain < Domain
|
|
101
|
+
def self.new(min, max)
|
|
102
|
+
super(:range, [:int64, min, :int64, max])
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# @!visibility private
|
|
107
|
+
class TypeDomain < Domain
|
|
108
|
+
def self.new(type)
|
|
109
|
+
super(type, [])
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def type
|
|
113
|
+
Libevoasm.domain_get_type self
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
data/lib/evoasm/error.rb
CHANGED
|
@@ -1,20 +1,41 @@
|
|
|
1
1
|
module Evoasm
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
# Represents an low-level error (originating from the backend library).
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
|
|
5
|
+
# @return [Integer] the line number at which this error occurred
|
|
6
|
+
attr_reader :line
|
|
7
|
+
|
|
8
|
+
# @return [Symbol] the error type
|
|
9
|
+
attr_reader :type
|
|
10
|
+
|
|
11
|
+
# @return [Symbol] the error code
|
|
12
|
+
attr_reader :code
|
|
13
|
+
|
|
14
|
+
# @return [String] the filename of the source file this error occurred in
|
|
15
|
+
attr_reader :filename
|
|
16
|
+
|
|
17
|
+
# @!visibility private
|
|
18
|
+
def self.last
|
|
19
|
+
self.new(Libevoasm.get_last_error)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @!visibility private
|
|
23
|
+
def initialize(ptr)
|
|
24
|
+
message = Libevoasm.error_get_msg ptr
|
|
25
|
+
|
|
26
|
+
@type = Libevoasm.error_get_type ptr
|
|
27
|
+
@code = Libevoasm.error_get_code ptr
|
|
28
|
+
@filename = Libevoasm.error_get_filename ptr
|
|
29
|
+
@line = Libevoasm.error_get_line ptr
|
|
30
|
+
|
|
31
|
+
super(message)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @!visibility private
|
|
35
|
+
def backtrace
|
|
36
|
+
backtrace = super
|
|
37
|
+
backtrace.unshift "#{@filename}:#{@line}" if backtrace
|
|
38
|
+
backtrace
|
|
18
39
|
end
|
|
19
40
|
end
|
|
20
41
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Evoasm
|
|
2
|
+
# Represents a hardware exception (e.g. division by zero).
|
|
3
|
+
class ExceptionError < StandardError
|
|
4
|
+
|
|
5
|
+
# @return [Symbol] the exception name
|
|
6
|
+
attr_reader :exception_name
|
|
7
|
+
|
|
8
|
+
# @return [Symbol] the architecture
|
|
9
|
+
attr_reader :architecture
|
|
10
|
+
|
|
11
|
+
# @!visibility private
|
|
12
|
+
def initialize(architecture, exception_name)
|
|
13
|
+
@architecture = architecture
|
|
14
|
+
@exception_name = exception_name
|
|
15
|
+
|
|
16
|
+
super("#{exception_name} was signalled")
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|