lldb 0.1.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 +47 -3
- 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 +7977 -856
- data/ext/lldb/lldb_wrapper.h +599 -324
- data/lib/lldb/address.rb +81 -0
- data/lib/lldb/api_support.rb +91 -0
- 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 +51 -3
- data/lib/lldb/event.rb +109 -0
- data/lib/lldb/expression_options.rb +124 -0
- data/lib/lldb/ffi_bindings.rb +326 -31
- data/lib/lldb/file_spec.rb +90 -0
- data/lib/lldb/file_spec_list.rb +78 -0
- data/lib/lldb/frame.rb +113 -18
- 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 +109 -0
- 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 +121 -38
- data/lib/lldb/symbol.rb +117 -0
- data/lib/lldb/symbol_context.rb +9 -4
- data/lib/lldb/target.rb +73 -67
- data/lib/lldb/thread.rb +56 -19
- 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 +80 -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 +258 -21
- data/sig/lldb/weak_ref.rbs +7 -0
- metadata +32 -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
|
|
@@ -96,22 +162,35 @@ module LLDB
|
|
|
96
162
|
# @rbs return: Value?
|
|
97
163
|
def find_variable(name)
|
|
98
164
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
165
|
+
APISupport.require_method!(:lldb_frame_find_variable, 'find_variable')
|
|
99
166
|
|
|
100
167
|
value_ptr = FFIBindings.lldb_frame_find_variable(@ptr, name)
|
|
101
168
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
102
169
|
|
|
103
|
-
Value.new(value_ptr, parent: self)
|
|
170
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
104
171
|
end
|
|
105
172
|
|
|
106
173
|
# @rbs expression: String
|
|
174
|
+
# @rbs options: ExpressionOptions?
|
|
107
175
|
# @rbs return: Value?
|
|
108
|
-
def evaluate_expression(expression)
|
|
176
|
+
def evaluate_expression(expression, options: nil)
|
|
109
177
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
110
|
-
|
|
111
|
-
|
|
178
|
+
APISupport.require_method!(:lldb_frame_evaluate_expression, 'evaluate_expression')
|
|
179
|
+
|
|
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
|
|
112
191
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
113
192
|
|
|
114
|
-
Value.new(value_ptr, parent: self)
|
|
193
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
115
194
|
end
|
|
116
195
|
|
|
117
196
|
# @rbs path: String
|
|
@@ -122,7 +201,7 @@ module LLDB
|
|
|
122
201
|
value_ptr = FFIBindings.lldb_frame_get_value_for_variable_path(@ptr, path)
|
|
123
202
|
return nil if value_ptr.nil? || value_ptr.null?
|
|
124
203
|
|
|
125
|
-
Value.new(value_ptr, parent: self)
|
|
204
|
+
Value.new(value_ptr, parent: self, context: context)
|
|
126
205
|
end
|
|
127
206
|
|
|
128
207
|
# @rbs scope: Integer
|
|
@@ -133,7 +212,7 @@ module LLDB
|
|
|
133
212
|
ctx_ptr = FFIBindings.lldb_frame_get_symbol_context(@ptr, scope)
|
|
134
213
|
return nil if ctx_ptr.nil? || ctx_ptr.null?
|
|
135
214
|
|
|
136
|
-
SymbolContext.new(ctx_ptr, parent: self)
|
|
215
|
+
SymbolContext.new(ctx_ptr, parent: self, context: context)
|
|
137
216
|
end
|
|
138
217
|
|
|
139
218
|
# @rbs return: String
|
|
@@ -171,17 +250,18 @@ module LLDB
|
|
|
171
250
|
)
|
|
172
251
|
raise LLDBError, 'Failed to get variables' if list_ptr.nil? || list_ptr.null?
|
|
173
252
|
|
|
174
|
-
ValueList.new(list_ptr, parent: self)
|
|
253
|
+
ValueList.new(list_ptr, parent: self, context: context)
|
|
175
254
|
end
|
|
176
255
|
|
|
177
256
|
# @rbs return: ValueList
|
|
178
257
|
def get_registers
|
|
179
258
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
259
|
+
APISupport.require_method!(:lldb_frame_get_registers, 'get_registers')
|
|
180
260
|
|
|
181
261
|
list_ptr = FFIBindings.lldb_frame_get_registers(@ptr)
|
|
182
262
|
raise LLDBError, 'Failed to get registers' if list_ptr.nil? || list_ptr.null?
|
|
183
263
|
|
|
184
|
-
ValueList.new(list_ptr, parent: self)
|
|
264
|
+
ValueList.new(list_ptr, parent: self, context: context)
|
|
185
265
|
end
|
|
186
266
|
|
|
187
267
|
# @rbs return: bool
|
|
@@ -198,6 +278,21 @@ module LLDB
|
|
|
198
278
|
FFIBindings.lldb_frame_disassemble(@ptr)
|
|
199
279
|
end
|
|
200
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
|
+
|
|
201
296
|
# @rbs return: Module?
|
|
202
297
|
def get_module
|
|
203
298
|
raise InvalidObjectError, 'Frame is not valid' unless valid?
|
|
@@ -205,7 +300,7 @@ module LLDB
|
|
|
205
300
|
mod_ptr = FFIBindings.lldb_frame_get_module(@ptr)
|
|
206
301
|
return nil if mod_ptr.nil? || mod_ptr.null?
|
|
207
302
|
|
|
208
|
-
Module.new(mod_ptr, target: @thread.process.target)
|
|
303
|
+
Module.new(mod_ptr, target: @thread.process.target, context: context)
|
|
209
304
|
end
|
|
210
305
|
|
|
211
306
|
# @rbs return: Thread?
|
|
@@ -215,7 +310,7 @@ module LLDB
|
|
|
215
310
|
thread_ptr = FFIBindings.lldb_frame_get_thread(@ptr)
|
|
216
311
|
return nil if thread_ptr.nil? || thread_ptr.null?
|
|
217
312
|
|
|
218
|
-
Thread.new(thread_ptr, process: @thread.process)
|
|
313
|
+
Thread.new(thread_ptr, process: @thread.process, context: context)
|
|
219
314
|
end
|
|
220
315
|
|
|
221
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
|