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.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.gdbinit +41 -0
  3. data/.gitignore +1 -2
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +660 -0
  8. data/Makefile +1 -1
  9. data/README.md +17 -9
  10. data/Rakefile +39 -107
  11. data/bin/gdb +1 -1
  12. data/bin/gdb_loop +4 -0
  13. data/docs/FindingInstructions.md +17 -0
  14. data/docs/JIT.md +14 -0
  15. data/docs/SymbolicRegression.md +102 -0
  16. data/docs/Visualization.md +29 -0
  17. data/docs/examples/bit_insts.rb +44 -0
  18. data/docs/examples/jit.rb +26 -0
  19. data/docs/examples/loss.gif +0 -0
  20. data/docs/examples/program.png +0 -0
  21. data/docs/examples/sym_reg.rb +64 -0
  22. data/docs/examples/vis.rb +38 -0
  23. data/evoasm.gemspec +21 -15
  24. data/ext/evoasm_ext/Rakefile +3 -0
  25. data/ext/evoasm_ext/compile.rake +35 -0
  26. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
  27. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
  28. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
  29. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
  30. data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
  31. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
  32. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
  33. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
  34. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
  35. data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
  36. data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
  37. data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
  38. data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
  39. data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
  40. data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
  41. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
  42. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
  43. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
  44. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
  45. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
  46. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
  47. data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
  48. data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
  49. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
  50. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
  51. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
  52. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
  53. data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
  54. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
  55. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
  56. data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
  57. data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
  58. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
  59. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
  60. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
  61. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
  62. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
  63. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
  64. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
  65. data/lib/evoasm.rb +28 -11
  66. data/lib/evoasm/buffer.rb +105 -0
  67. data/lib/evoasm/capstone.rb +100 -0
  68. data/lib/evoasm/domain.rb +116 -0
  69. data/lib/evoasm/error.rb +37 -16
  70. data/lib/evoasm/exception_error.rb +19 -0
  71. data/lib/evoasm/ffi_ext.rb +53 -0
  72. data/lib/evoasm/libevoasm.rb +286 -0
  73. data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
  74. data/lib/evoasm/parameter.rb +20 -0
  75. data/lib/evoasm/population.rb +145 -0
  76. data/lib/evoasm/population/parameters.rb +227 -0
  77. data/lib/evoasm/population/plotter.rb +89 -0
  78. data/lib/evoasm/prng.rb +64 -0
  79. data/lib/evoasm/program.rb +195 -12
  80. data/lib/evoasm/program/io.rb +144 -0
  81. data/lib/evoasm/test.rb +8 -0
  82. data/lib/evoasm/version.rb +1 -1
  83. data/lib/evoasm/x64.rb +115 -0
  84. data/lib/evoasm/x64/cpu_state.rb +95 -0
  85. data/lib/evoasm/x64/instruction.rb +109 -0
  86. data/lib/evoasm/x64/operand.rb +156 -0
  87. data/lib/evoasm/x64/parameters.rb +211 -0
  88. data/test/helpers/population_helper.rb +128 -0
  89. data/test/helpers/test_helper.rb +1 -0
  90. data/test/helpers/x64_helper.rb +24 -0
  91. data/test/integration/bitwise_reverse_test.rb +41 -0
  92. data/test/integration/gcd_test.rb +52 -0
  93. data/test/integration/popcnt_test.rb +46 -0
  94. data/test/integration/sym_reg_test.rb +68 -0
  95. data/test/unit/evoasm/buffer_test.rb +48 -0
  96. data/test/unit/evoasm/capstone_test.rb +18 -0
  97. data/test/unit/evoasm/domain_test.rb +55 -0
  98. data/test/unit/evoasm/population/parameters_test.rb +106 -0
  99. data/test/unit/evoasm/population_test.rb +96 -0
  100. data/test/unit/evoasm/prng_test.rb +47 -0
  101. data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
  102. data/test/unit/evoasm/x64/encoding_test.rb +320 -0
  103. data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
  104. data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
  105. data/test/unit/evoasm/x64/instruction_test.rb +62 -0
  106. data/test/unit/evoasm/x64/parameters_test.rb +65 -0
  107. data/test/unit/evoasm/x64_test.rb +52 -0
  108. metadata +195 -89
  109. data/Gemfile.rake +0 -8
  110. data/Gemfile.rake.lock +0 -51
  111. data/LICENSE.txt +0 -373
  112. data/data/tables/README.md +0 -19
  113. data/data/tables/x64.csv +0 -1684
  114. data/data/templates/evoasm-x64.c.erb +0 -319
  115. data/data/templates/evoasm-x64.h.erb +0 -126
  116. data/examples/abs.yml +0 -20
  117. data/examples/popcnt.yml +0 -17
  118. data/examples/sym_reg.yml +0 -26
  119. data/exe/evoasm-search +0 -13
  120. data/ext/evoasm_ext/evoasm-alloc.c +0 -145
  121. data/ext/evoasm_ext/evoasm-alloc.h +0 -59
  122. data/ext/evoasm_ext/evoasm-arch.c +0 -44
  123. data/ext/evoasm_ext/evoasm-arch.h +0 -161
  124. data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
  125. data/ext/evoasm_ext/evoasm-buf.c +0 -130
  126. data/ext/evoasm_ext/evoasm-buf.h +0 -47
  127. data/ext/evoasm_ext/evoasm-error.c +0 -31
  128. data/ext/evoasm_ext/evoasm-error.h +0 -75
  129. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
  130. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
  131. data/ext/evoasm_ext/evoasm-log.h +0 -69
  132. data/ext/evoasm_ext/evoasm-misc.c +0 -23
  133. data/ext/evoasm_ext/evoasm-misc.h +0 -282
  134. data/ext/evoasm_ext/evoasm-param.h +0 -37
  135. data/ext/evoasm_ext/evoasm-search.c +0 -2145
  136. data/ext/evoasm_ext/evoasm-search.h +0 -214
  137. data/ext/evoasm_ext/evoasm-util.h +0 -40
  138. data/ext/evoasm_ext/evoasm-x64.c +0 -275624
  139. data/ext/evoasm_ext/evoasm-x64.h +0 -5436
  140. data/ext/evoasm_ext/evoasm.c +0 -7
  141. data/ext/evoasm_ext/evoasm.h +0 -23
  142. data/ext/evoasm_ext/evoasm_ext.c +0 -1757
  143. data/ext/evoasm_ext/extconf.rb +0 -31
  144. data/lib/evoasm/cli.rb +0 -6
  145. data/lib/evoasm/cli/search.rb +0 -127
  146. data/lib/evoasm/core_ext.rb +0 -1
  147. data/lib/evoasm/core_ext/array.rb +0 -9
  148. data/lib/evoasm/core_ext/integer.rb +0 -10
  149. data/lib/evoasm/core_ext/kwstruct.rb +0 -13
  150. data/lib/evoasm/core_ext/range.rb +0 -5
  151. data/lib/evoasm/examples.rb +0 -27
  152. data/lib/evoasm/gen.rb +0 -8
  153. data/lib/evoasm/gen/enum.rb +0 -169
  154. data/lib/evoasm/gen/name_util.rb +0 -80
  155. data/lib/evoasm/gen/state.rb +0 -176
  156. data/lib/evoasm/gen/state_dsl.rb +0 -152
  157. data/lib/evoasm/gen/strio.rb +0 -27
  158. data/lib/evoasm/gen/translator.rb +0 -1102
  159. data/lib/evoasm/gen/version.rb +0 -5
  160. data/lib/evoasm/gen/x64.rb +0 -237
  161. data/lib/evoasm/gen/x64/funcs.rb +0 -495
  162. data/lib/evoasm/gen/x64/inst.rb +0 -781
  163. data/lib/evoasm/search.rb +0 -40
  164. data/lib/evoasm/tasks/gen_task.rb +0 -86
  165. data/lib/evoasm/tasks/template_task.rb +0 -52
  166. data/test/test_helper.rb +0 -1
  167. data/test/x64/test_helper.rb +0 -19
  168. 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.root
4
+ def self.root_dir
6
5
  File.expand_path File.join(__dir__, '..')
7
6
  end
8
7
 
9
- def self.data
10
- File.join root, 'data'
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
- begin
15
- require 'evoasm_ext'
16
- rescue LoadError => e
17
- p e
28
+ def self.architecture
29
+ Libevoasm.get_current_arch
30
+ end
18
31
  end
19
32
 
20
- require 'evoasm/search'
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
- class Error
3
- def message
4
- msg = __message
5
-
6
- case code
7
- when :not_encodable
8
- "#{msg} #{parameter}"
9
- when :missing_param
10
- "#{msg} (#{parameter})"
11
- when :missing_feature
12
- "missing features #{features.join ', '}"
13
- when :invalid_access
14
- "#{msg} (#{instruction}/#{register})"
15
- else
16
- msg || code
17
- end
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