lldb 0.2.0 → 0.3.0
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/CHANGELOG.md +43 -4
- data/README.md +86 -2
- data/Rakefile +36 -0
- data/bindings/constants.yml +137 -0
- data/bindings/surface.yml +3072 -0
- data/ext/lldb/discovery.rb +101 -0
- data/ext/lldb/extconf.rb +206 -88
- data/ext/lldb/lldb_wrapper.cpp +7934 -877
- data/ext/lldb/lldb_wrapper.h +596 -333
- data/lib/lldb/address.rb +81 -0
- data/lib/lldb/api_support.rb +23 -6
- data/lib/lldb/attach_info.rb +122 -0
- data/lib/lldb/block.rb +121 -0
- data/lib/lldb/breakpoint.rb +11 -6
- data/lib/lldb/breakpoint_location.rb +20 -5
- data/lib/lldb/broadcaster.rb +79 -0
- data/lib/lldb/command_interpreter.rb +9 -4
- data/lib/lldb/command_return_object.rb +24 -5
- data/lib/lldb/compile_unit.rb +64 -0
- data/lib/lldb/context.rb +81 -0
- data/lib/lldb/debugger.rb +55 -12
- data/lib/lldb/error.rb +50 -3
- data/lib/lldb/event.rb +109 -0
- data/lib/lldb/expression_options.rb +124 -0
- data/lib/lldb/ffi_bindings.rb +313 -31
- data/lib/lldb/file_spec.rb +90 -0
- data/lib/lldb/file_spec_list.rb +78 -0
- data/lib/lldb/frame.rb +109 -17
- data/lib/lldb/function.rb +121 -0
- data/lib/lldb/instruction.rb +83 -0
- data/lib/lldb/instruction_list.rb +68 -0
- data/lib/lldb/launch_info.rb +145 -19
- data/lib/lldb/line_entry.rb +75 -0
- data/lib/lldb/listener.rb +96 -0
- data/lib/lldb/memory_region_info.rb +8 -3
- data/lib/lldb/module.rb +46 -5
- data/lib/lldb/native.rb +36 -0
- data/lib/lldb/native_buffer.rb +32 -0
- data/lib/lldb/native_handle.rb +60 -0
- data/lib/lldb/native_lifecycle.rb +64 -0
- data/lib/lldb/native_string_array.rb +34 -0
- data/lib/lldb/process.rb +102 -40
- data/lib/lldb/symbol.rb +117 -0
- data/lib/lldb/symbol_context.rb +9 -4
- data/lib/lldb/target.rb +69 -67
- data/lib/lldb/thread.rb +51 -18
- data/lib/lldb/type.rb +40 -3
- data/lib/lldb/type_member.rb +67 -0
- data/lib/lldb/types.rb +69 -4
- data/lib/lldb/value.rb +27 -17
- data/lib/lldb/value_list.rb +9 -5
- data/lib/lldb/version.rb +1 -1
- data/lib/lldb/watchpoint.rb +26 -9
- data/lib/lldb.rb +78 -10
- data/lldb.gemspec +4 -1
- data/rbs_collection.yaml +1 -1
- data/script/check_bindings +259 -0
- data/script/guard_c_exports +139 -0
- data/sig/lldb/ffi_bindings.rbs +247 -21
- data/sig/lldb/weak_ref.rbs +7 -0
- metadata +30 -6
- data/ext/lldb/Makefile +0 -24
- data/ext/lldb/liblldb_wrapper.dylib +0 -0
- data/ext/lldb/lldb_wrapper.o +0 -0
- data/ext/lldb/mkmf.log +0 -24
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class FileSpecList
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
9
|
+
# @rbs context: Context?
|
|
10
|
+
# @rbs return: void
|
|
11
|
+
def initialize(context: nil)
|
|
12
|
+
initialize_native_object(
|
|
13
|
+
FFIBindings.lldb_file_spec_list_create,
|
|
14
|
+
release: ->(released) { FFIBindings.lldb_file_spec_list_destroy(released) },
|
|
15
|
+
context: context
|
|
16
|
+
)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @rbs return: bool
|
|
20
|
+
def valid?
|
|
21
|
+
!@ptr.null? && FFIBindings.lldb_file_spec_list_is_valid(@ptr) != 0
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @rbs return: Integer
|
|
25
|
+
def size
|
|
26
|
+
return 0 unless valid?
|
|
27
|
+
|
|
28
|
+
FFIBindings.lldb_file_spec_list_get_size(@ptr)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
alias length size
|
|
32
|
+
|
|
33
|
+
# @rbs file_spec: FileSpec
|
|
34
|
+
# @rbs return: void
|
|
35
|
+
def append(file_spec)
|
|
36
|
+
ensure_open!
|
|
37
|
+
raise ArgumentError, 'file_spec must be a FileSpec' unless file_spec.is_a?(FileSpec)
|
|
38
|
+
|
|
39
|
+
FFIBindings.lldb_file_spec_list_append(@ptr, file_spec.to_ptr)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @rbs file_spec: FileSpec
|
|
43
|
+
# @rbs return: bool
|
|
44
|
+
def append_if_unique(file_spec)
|
|
45
|
+
ensure_open!
|
|
46
|
+
raise ArgumentError, 'file_spec must be a FileSpec' unless file_spec.is_a?(FileSpec)
|
|
47
|
+
|
|
48
|
+
FFIBindings.lldb_file_spec_list_append_if_unique(@ptr, file_spec.to_ptr) != 0
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs return: void
|
|
52
|
+
def clear
|
|
53
|
+
ensure_open!
|
|
54
|
+
FFIBindings.lldb_file_spec_list_clear(@ptr)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @rbs index: Integer
|
|
58
|
+
# @rbs return: FileSpec?
|
|
59
|
+
def [](index)
|
|
60
|
+
return nil unless valid?
|
|
61
|
+
|
|
62
|
+
ptr = FFIBindings.lldb_file_spec_list_get_file_spec_at_index(@ptr, index)
|
|
63
|
+
return nil if ptr.nil? || ptr.null?
|
|
64
|
+
|
|
65
|
+
FileSpec.from_ptr(ptr, context: context)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @rbs return: Array[FileSpec]
|
|
69
|
+
def to_a
|
|
70
|
+
(0...size).map { |index| self[index] }.compact
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @rbs return: FFI::Pointer
|
|
74
|
+
def to_ptr
|
|
75
|
+
@ptr
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
data/lib/lldb/frame.rb
CHANGED
|
@@ -4,16 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
module LLDB
|
|
6
6
|
class Frame
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
7
9
|
# @rbs return: Thread
|
|
8
10
|
attr_reader :thread
|
|
9
11
|
|
|
10
12
|
# @rbs ptr: FFI::Pointer
|
|
11
13
|
# @rbs thread: Thread
|
|
12
14
|
# @rbs return: void
|
|
13
|
-
def initialize(ptr, thread:)
|
|
14
|
-
@ptr = ptr # : FFI::Pointer
|
|
15
|
+
def initialize(ptr, thread:, context: thread.context)
|
|
15
16
|
@thread = thread
|
|
16
|
-
|
|
17
|
+
initialize_native_object(
|
|
18
|
+
ptr,
|
|
19
|
+
release: ->(released) { FFIBindings.lldb_frame_destroy(released) },
|
|
20
|
+
context: context
|
|
21
|
+
)
|
|
17
22
|
end
|
|
18
23
|
|
|
19
24
|
# @rbs ptr: FFI::Pointer
|
|
@@ -52,7 +57,68 @@ module LLDB
|
|
|
52
57
|
def file_path
|
|
53
58
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
file_spec&.path
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @rbs return: FileSpec?
|
|
64
|
+
def file_spec
|
|
65
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
66
|
+
|
|
67
|
+
file_ptr = FFIBindings.lldb_frame_get_file_spec(@ptr)
|
|
68
|
+
return nil if file_ptr.nil? || file_ptr.null?
|
|
69
|
+
|
|
70
|
+
FileSpec.from_ptr(file_ptr, context: context)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @rbs return: LineEntry?
|
|
74
|
+
def line_entry
|
|
75
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
76
|
+
|
|
77
|
+
line_ptr = FFIBindings.lldb_frame_get_line_entry(@ptr)
|
|
78
|
+
return nil if line_ptr.nil? || line_ptr.null?
|
|
79
|
+
|
|
80
|
+
target = @thread.process.target
|
|
81
|
+
LineEntry.new(line_ptr, target: target, context: context)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @rbs return: Function?
|
|
85
|
+
def function
|
|
86
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
87
|
+
|
|
88
|
+
function_ptr = FFIBindings.lldb_frame_get_function(@ptr)
|
|
89
|
+
return nil if function_ptr.nil? || function_ptr.null?
|
|
90
|
+
|
|
91
|
+
Function.new(function_ptr, target: @thread.process.target, context: context)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# @rbs return: Symbol?
|
|
95
|
+
def symbol
|
|
96
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
97
|
+
|
|
98
|
+
symbol_ptr = FFIBindings.lldb_frame_get_symbol(@ptr)
|
|
99
|
+
return nil if symbol_ptr.nil? || symbol_ptr.null?
|
|
100
|
+
|
|
101
|
+
Symbol.new(symbol_ptr, target: @thread.process.target, context: context)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @rbs return: CompileUnit?
|
|
105
|
+
def compile_unit
|
|
106
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
107
|
+
|
|
108
|
+
unit_ptr = FFIBindings.lldb_frame_get_compile_unit(@ptr)
|
|
109
|
+
return nil if unit_ptr.nil? || unit_ptr.null?
|
|
110
|
+
|
|
111
|
+
CompileUnit.new(unit_ptr, target: @thread.process.target, context: context)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# @rbs return: Block?
|
|
115
|
+
def block
|
|
116
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
117
|
+
|
|
118
|
+
block_ptr = FFIBindings.lldb_frame_get_block(@ptr)
|
|
119
|
+
return nil if block_ptr.nil? || block_ptr.null?
|
|
120
|
+
|
|
121
|
+
Block.new(block_ptr, target: @thread.process.target, context: context)
|
|
56
122
|
end
|
|
57
123
|
|
|
58
124
|
# @rbs return: Integer
|
|
@@ -64,21 +130,21 @@ module LLDB
|
|
|
64
130
|
|
|
65
131
|
# @rbs return: Integer
|
|
66
132
|
def pc
|
|
67
|
-
return
|
|
133
|
+
return INVALID_ADDRESS unless valid?
|
|
68
134
|
|
|
69
135
|
FFIBindings.lldb_frame_get_pc(@ptr)
|
|
70
136
|
end
|
|
71
137
|
|
|
72
138
|
# @rbs return: Integer
|
|
73
139
|
def sp
|
|
74
|
-
return
|
|
140
|
+
return INVALID_ADDRESS unless valid?
|
|
75
141
|
|
|
76
142
|
FFIBindings.lldb_frame_get_sp(@ptr)
|
|
77
143
|
end
|
|
78
144
|
|
|
79
145
|
# @rbs return: Integer
|
|
80
146
|
def fp
|
|
81
|
-
return
|
|
147
|
+
return INVALID_ADDRESS unless valid?
|
|
82
148
|
|
|
83
149
|
FFIBindings.lldb_frame_get_fp(@ptr)
|
|
84
150
|
end
|
|
@@ -101,19 +167,30 @@ module LLDB
|
|
|
101
167
|
value_ptr = FFIBindings.lldb_frame_find_variable(@ptr, name)
|
|
102
168
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
103
169
|
|
|
104
|
-
Value.new(value_ptr, parent: self)
|
|
170
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
105
171
|
end
|
|
106
172
|
|
|
107
173
|
# @rbs expression: String
|
|
174
|
+
# @rbs options: ExpressionOptions?
|
|
108
175
|
# @rbs return: Value?
|
|
109
|
-
def evaluate_expression(expression)
|
|
176
|
+
def evaluate_expression(expression, options: nil)
|
|
110
177
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
111
178
|
APISupport.require_method!(:lldb_frame_evaluate_expression, 'evaluate_expression')
|
|
112
179
|
|
|
113
|
-
value_ptr =
|
|
180
|
+
value_ptr = if options
|
|
181
|
+
unless options.is_a?(ExpressionOptions)
|
|
182
|
+
raise ArgumentError, 'options must be an ExpressionOptions'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
FFIBindings.lldb_frame_evaluate_expression_with_options(
|
|
186
|
+
@ptr, expression, options.to_ptr
|
|
187
|
+
)
|
|
188
|
+
else
|
|
189
|
+
FFIBindings.lldb_frame_evaluate_expression(@ptr, expression)
|
|
190
|
+
end
|
|
114
191
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
115
192
|
|
|
116
|
-
Value.new(value_ptr, parent: self)
|
|
193
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
117
194
|
end
|
|
118
195
|
|
|
119
196
|
# @rbs path: String
|
|
@@ -124,7 +201,7 @@ module LLDB
|
|
|
124
201
|
value_ptr = FFIBindings.lldb_frame_get_value_for_variable_path(@ptr, path)
|
|
125
202
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
126
203
|
|
|
127
|
-
Value.new(value_ptr, parent: self)
|
|
204
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
128
205
|
end
|
|
129
206
|
|
|
130
207
|
# @rbs scope: Integer
|
|
@@ -135,7 +212,7 @@ module LLDB
|
|
|
135
212
|
ctx_ptr = FFIBindings.lldb_frame_get_symbol_context(@ptr, scope)
|
|
136
213
|
return nil if ctx_ptr.nil? || ctx_ptr.null?
|
|
137
214
|
|
|
138
|
-
SymbolContext.new(ctx_ptr, parent: self)
|
|
215
|
+
SymbolContext.new(ctx_ptr, parent: self, context: context)
|
|
139
216
|
end
|
|
140
217
|
|
|
141
218
|
# @rbs return: String
|
|
@@ -173,7 +250,7 @@ module LLDB
|
|
|
173
250
|
)
|
|
174
251
|
raise LLDBError, 'Failed to get variables' if list_ptr.nil? || list_ptr.null?
|
|
175
252
|
|
|
176
|
-
ValueList.new(list_ptr, parent: self)
|
|
253
|
+
ValueList.new(list_ptr, parent: self, context: context)
|
|
177
254
|
end
|
|
178
255
|
|
|
179
256
|
# @rbs return: ValueList
|
|
@@ -184,7 +261,7 @@ module LLDB
|
|
|
184
261
|
list_ptr = FFIBindings.lldb_frame_get_registers(@ptr)
|
|
185
262
|
raise LLDBError, 'Failed to get registers' if list_ptr.nil? || list_ptr.null?
|
|
186
263
|
|
|
187
|
-
ValueList.new(list_ptr, parent: self)
|
|
264
|
+
ValueList.new(list_ptr, parent: self, context: context)
|
|
188
265
|
end
|
|
189
266
|
|
|
190
267
|
# @rbs return: bool
|
|
@@ -201,6 +278,21 @@ module LLDB
|
|
|
201
278
|
FFIBindings.lldb_frame_disassemble(@ptr)
|
|
202
279
|
end
|
|
203
280
|
|
|
281
|
+
# @rbs return: InstructionList?
|
|
282
|
+
def instruction_list
|
|
283
|
+
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
284
|
+
|
|
285
|
+
target = @thread.process.target
|
|
286
|
+
return nil unless target
|
|
287
|
+
|
|
288
|
+
list_ptr = FFIBindings.lldb_frame_get_instruction_list(@ptr, target.to_ptr)
|
|
289
|
+
return nil if list_ptr.nil? || list_ptr.null?
|
|
290
|
+
|
|
291
|
+
InstructionList.new(list_ptr, target: target, context: context)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
alias instructions instruction_list
|
|
295
|
+
|
|
204
296
|
# @rbs return: Module?
|
|
205
297
|
def get_module
|
|
206
298
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
@@ -208,7 +300,7 @@ module LLDB
|
|
|
208
300
|
mod_ptr = FFIBindings.lldb_frame_get_module(@ptr)
|
|
209
301
|
return nil if mod_ptr.nil? || mod_ptr.null?
|
|
210
302
|
|
|
211
|
-
Module.new(mod_ptr, target: @thread.process.target)
|
|
303
|
+
Module.new(mod_ptr, target: @thread.process.target, context: context)
|
|
212
304
|
end
|
|
213
305
|
|
|
214
306
|
# @rbs return: Thread?
|
|
@@ -218,7 +310,7 @@ module LLDB
|
|
|
218
310
|
thread_ptr = FFIBindings.lldb_frame_get_thread(@ptr)
|
|
219
311
|
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
220
312
|
|
|
221
|
-
Thread.new(thread_ptr, process: @thread.process)
|
|
313
|
+
Thread.new(thread_ptr, process: @thread.process, context: context)
|
|
222
314
|
end
|
|
223
315
|
|
|
224
316
|
# @rbs return: FFI::Pointer
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class Function
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
9
|
+
# @rbs target: Target?
|
|
10
|
+
# @rbs context: Context?
|
|
11
|
+
# @rbs return: void
|
|
12
|
+
def initialize(ptr, target: nil, context: nil)
|
|
13
|
+
@target = target
|
|
14
|
+
initialize_native_object(
|
|
15
|
+
ptr,
|
|
16
|
+
release: ->(released) { FFIBindings.lldb_function_destroy(released) },
|
|
17
|
+
context: context || target&.context
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @rbs return: bool
|
|
22
|
+
def valid?
|
|
23
|
+
!@ptr.null? && FFIBindings.lldb_function_is_valid(@ptr) != 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @rbs return: String?
|
|
27
|
+
def name
|
|
28
|
+
return nil unless valid?
|
|
29
|
+
|
|
30
|
+
FFIBindings.lldb_function_get_name(@ptr)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @rbs return: String?
|
|
34
|
+
def display_name
|
|
35
|
+
return nil unless valid?
|
|
36
|
+
|
|
37
|
+
FFIBindings.lldb_function_get_display_name(@ptr)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @rbs return: String?
|
|
41
|
+
def mangled_name
|
|
42
|
+
return nil unless valid?
|
|
43
|
+
|
|
44
|
+
FFIBindings.lldb_function_get_mangled_name(@ptr)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @rbs return: String?
|
|
48
|
+
def base_name
|
|
49
|
+
return nil unless valid?
|
|
50
|
+
|
|
51
|
+
FFIBindings.lldb_function_get_base_name(@ptr)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @rbs return: Address?
|
|
55
|
+
def start_address
|
|
56
|
+
address_at(:lldb_function_get_start_address)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @rbs return: Address?
|
|
60
|
+
def end_address
|
|
61
|
+
address_at(:lldb_function_get_end_address)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @rbs return: Integer
|
|
65
|
+
def prologue_byte_size
|
|
66
|
+
return 0 unless valid?
|
|
67
|
+
|
|
68
|
+
FFIBindings.lldb_function_get_prologue_byte_size(@ptr)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @rbs return: Type?
|
|
72
|
+
def type
|
|
73
|
+
return nil unless valid?
|
|
74
|
+
|
|
75
|
+
ptr = FFIBindings.lldb_function_get_type(@ptr)
|
|
76
|
+
return nil if ptr.nil? || ptr.null?
|
|
77
|
+
|
|
78
|
+
Type.new(ptr, context: context)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @rbs return: Block?
|
|
82
|
+
def block
|
|
83
|
+
return nil unless valid?
|
|
84
|
+
|
|
85
|
+
ptr = FFIBindings.lldb_function_get_block(@ptr)
|
|
86
|
+
return nil if ptr.nil? || ptr.null?
|
|
87
|
+
|
|
88
|
+
Block.new(ptr, target: @target, context: context)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @rbs return: bool
|
|
92
|
+
def optimized?
|
|
93
|
+
valid? && FFIBindings.lldb_function_is_optimized(@ptr) != 0
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# @rbs return: Integer
|
|
97
|
+
def language
|
|
98
|
+
return 0 unless valid?
|
|
99
|
+
|
|
100
|
+
FFIBindings.lldb_function_get_language(@ptr)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# @rbs return: FFI::Pointer
|
|
104
|
+
def to_ptr
|
|
105
|
+
@ptr
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# @rbs method_name: ::Symbol
|
|
111
|
+
# @rbs return: Address?
|
|
112
|
+
def address_at(method_name)
|
|
113
|
+
return nil unless valid?
|
|
114
|
+
|
|
115
|
+
ptr = FFIBindings.public_send(method_name, @ptr)
|
|
116
|
+
return nil if ptr.nil? || ptr.null?
|
|
117
|
+
|
|
118
|
+
Address.from_ptr(ptr, target: @target, context: context)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class Instruction
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
|
|
9
|
+
# @rbs target: Target?
|
|
10
|
+
# @rbs context: Context?
|
|
11
|
+
# @rbs return: void
|
|
12
|
+
def initialize(ptr, target: nil, context: nil)
|
|
13
|
+
@target = target
|
|
14
|
+
initialize_native_object(
|
|
15
|
+
ptr,
|
|
16
|
+
release: ->(released) { FFIBindings.lldb_instruction_destroy(released) },
|
|
17
|
+
context: context || target&.context
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @rbs return: bool
|
|
22
|
+
def valid?
|
|
23
|
+
!@ptr.null? && FFIBindings.lldb_instruction_is_valid(@ptr) != 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @rbs return: Address?
|
|
27
|
+
def address
|
|
28
|
+
return nil unless valid?
|
|
29
|
+
|
|
30
|
+
ptr = FFIBindings.lldb_instruction_get_address(@ptr)
|
|
31
|
+
return nil if ptr.nil? || ptr.null?
|
|
32
|
+
|
|
33
|
+
Address.from_ptr(ptr, target: @target, context: context)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @rbs return: String?
|
|
37
|
+
def mnemonic
|
|
38
|
+
return nil unless valid? && @target
|
|
39
|
+
|
|
40
|
+
FFIBindings.lldb_instruction_get_mnemonic(@ptr, @target.to_ptr)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @rbs return: String?
|
|
44
|
+
def operands
|
|
45
|
+
return nil unless valid? && @target
|
|
46
|
+
|
|
47
|
+
FFIBindings.lldb_instruction_get_operands(@ptr, @target.to_ptr)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @rbs return: String?
|
|
51
|
+
def comment
|
|
52
|
+
return nil unless valid? && @target
|
|
53
|
+
|
|
54
|
+
FFIBindings.lldb_instruction_get_comment(@ptr, @target.to_ptr)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @rbs return: Integer
|
|
58
|
+
def byte_size
|
|
59
|
+
return 0 unless valid?
|
|
60
|
+
|
|
61
|
+
FFIBindings.lldb_instruction_get_byte_size(@ptr)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @rbs return: String
|
|
65
|
+
def bytes
|
|
66
|
+
return ''.b unless valid? && @target
|
|
67
|
+
|
|
68
|
+
length = byte_size
|
|
69
|
+
return ''.b if length.zero?
|
|
70
|
+
|
|
71
|
+
buffer = FFI::MemoryPointer.new(:uint8, length)
|
|
72
|
+
written = FFIBindings.lldb_instruction_get_bytes(
|
|
73
|
+
@ptr, @target.to_ptr, buffer, length
|
|
74
|
+
)
|
|
75
|
+
buffer.get_bytes(0, [written, length].min).b
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# @rbs return: FFI::Pointer
|
|
79
|
+
def to_ptr
|
|
80
|
+
@ptr
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rbs_inline: enabled
|
|
4
|
+
|
|
5
|
+
module LLDB
|
|
6
|
+
class InstructionList
|
|
7
|
+
prepend NativeLifecycle
|
|
8
|
+
include Enumerable #[Instruction]
|
|
9
|
+
|
|
10
|
+
# @rbs target: Target?
|
|
11
|
+
# @rbs context: Context?
|
|
12
|
+
# @rbs return: void
|
|
13
|
+
def initialize(ptr, target: nil, context: nil)
|
|
14
|
+
@target = target
|
|
15
|
+
initialize_native_object(
|
|
16
|
+
ptr,
|
|
17
|
+
release: ->(released) { FFIBindings.lldb_instruction_list_destroy(released) },
|
|
18
|
+
context: context || target&.context
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @rbs return: bool
|
|
23
|
+
def valid?
|
|
24
|
+
!@ptr.null? && FFIBindings.lldb_instruction_list_is_valid(@ptr) != 0
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @rbs return: Integer
|
|
28
|
+
def size
|
|
29
|
+
return 0 unless valid?
|
|
30
|
+
|
|
31
|
+
FFIBindings.lldb_instruction_list_get_size(@ptr)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
alias length size
|
|
35
|
+
|
|
36
|
+
# @rbs index: Integer
|
|
37
|
+
# @rbs return: Instruction?
|
|
38
|
+
def [](index)
|
|
39
|
+
return nil unless valid?
|
|
40
|
+
|
|
41
|
+
ptr = FFIBindings.lldb_instruction_list_get_instruction_at_index(@ptr, index)
|
|
42
|
+
return nil if ptr.nil? || ptr.null?
|
|
43
|
+
|
|
44
|
+
Instruction.new(ptr, target: @target, context: context)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @rbs &block: (Instruction) -> void
|
|
48
|
+
# @rbs return: Enumerator[Instruction, void] | void
|
|
49
|
+
def each(&block)
|
|
50
|
+
return enum_for(:each) unless block_given?
|
|
51
|
+
|
|
52
|
+
(0...size).each do |index|
|
|
53
|
+
instruction = self[index]
|
|
54
|
+
block.call(instruction) if instruction
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @rbs return: Array[Instruction]
|
|
59
|
+
def to_a
|
|
60
|
+
(0...size).map { |index| self[index] }.compact
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @rbs return: FFI::Pointer
|
|
64
|
+
def to_ptr
|
|
65
|
+
@ptr
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|