1 """ This module implement Dwarf expression opcode parser. """
5 # DWARF Expression operators.
35 DW_OP_plus_uconst
= 0x23
148 DW_OP_deref_size
= 0x94
149 DW_OP_xderef_size
= 0x95
151 DW_OP_push_object_address
= 0x97
154 DW_OP_call_ref
= 0x9A
155 DW_OP_form_tls_address
= 0x9B
156 DW_OP_call_frame_cfa
= 0x9C
157 DW_OP_bit_piece
= 0x9D
158 DW_OP_implicit_value
= 0x9E
159 DW_OP_stack_value
= 0x9F
161 DW_OP_GNU_push_tls_address
= 0xE0
165 class DwarfOpcodeParser(object):
166 def updateRegInfoBitsize(self
, reg_info
, byte_order
):
167 """Update the regInfo bit size."""
169 # Evaluate Dwarf Expression
170 expr_result
= self
.evaluateDwarfExpression(
171 reg_info
["dynamic_size_dwarf_expr_bytes"], byte_order
175 reg_info
["bitsize"] = 32
176 elif expr_result
== 1:
177 reg_info
["bitsize"] = 64
179 def evaluateDwarfExpression(self
, dwarf_opcode
, byte_order
):
180 """Evaluate Dwarf Expression."""
182 dwarf_opcode
= [dwarf_opcode
[i
: i
+ 2] for i
in range(0, len(dwarf_opcode
), 2)]
184 for index
in range(len(dwarf_opcode
)):
185 if index
< len(dwarf_opcode
):
186 val
= int(dwarf_opcode
[index
], 16)
190 if val
== DW_OP_regx
:
191 # Read register number
192 self
.assertTrue(len(dwarf_opcode
) > (index
+ 1))
193 reg_no
= int(dwarf_opcode
.pop(index
+ 1), 16)
195 self
.reset_test_sequence()
196 # Read register value
197 self
.test_sequence
.add_log_lines(
199 "read packet: $p{0:x}#00".format(reg_no
),
202 "regex": r
"^\$([0-9a-fA-F]+)#",
203 "capture": {1: "p_response"},
209 Context
= self
.expect_gdbremote_sequence()
210 self
.assertIsNotNone(Context
)
211 p_response
= Context
.get("p_response")
212 self
.assertIsNotNone(p_response
)
214 if byte_order
== lldb
.eByteOrderLittle
:
215 # In case of little endian
216 # first decode the HEX ASCII bytes and then reverse it
217 # to get actual value of SR register
218 p_response
= "".join(
221 p_response
[i
: i
+ 2]
222 for i
in range(0, len(p_response
), 2)
226 # Push register value
227 dwarf_data
.append(int(p_response
, 16))
229 elif val
== DW_OP_lit1
:
233 elif val
== DW_OP_lit26
:
235 dwarf_data
.append(26)
237 elif val
== DW_OP_shl
:
238 # left shift and push the result back
239 self
.assertTrue(len(dwarf_data
) > 1)
240 shift_amount
= dwarf_data
.pop()
241 val_to_shift
= dwarf_data
.pop()
242 result
= val_to_shift
<< shift_amount
243 dwarf_data
.append(result
)
245 elif val
== DW_OP_shr
:
246 # Right shift and push the result back
247 self
.assertTrue(len(dwarf_data
) > 1)
248 shift_amount
= dwarf_data
.pop()
249 val_to_shift
= dwarf_data
.pop()
250 result
= val_to_shift
>> shift_amount
251 dwarf_data
.append(result
)
253 elif val
== DW_OP_and
:
254 # And of topmost 2 elements and push the result back
255 first_ele
= dwarf_data
.pop()
256 second_ele
= dwarf_data
.pop()
257 result
= first_ele
& second_ele
258 dwarf_data
.append(result
)
261 self
.assertTrue(False and "Unprocess Dwarf Opcode")
263 self
.assertTrue(len(dwarf_data
) == 1)
264 expr_result
= dwarf_data
.pop()