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
162 DW_OP_APPLE_uninit
= 0xF0
166 class DwarfOpcodeParser(object):
168 def updateRegInfoBitsize(self
, reg_info
, byte_order
):
169 """ Update the regInfo bit size. """
171 # Evaluate Dwarf Expression
172 expr_result
= self
.evaluateDwarfExpression(reg_info
["dynamic_size_dwarf_expr_bytes"],
176 reg_info
["bitsize"] = 32
177 elif expr_result
== 1:
178 reg_info
["bitsize"] = 64
181 def evaluateDwarfExpression(self
, dwarf_opcode
, byte_order
):
182 """Evaluate Dwarf Expression. """
184 dwarf_opcode
= [dwarf_opcode
[i
:i
+2] for i
in range(0,len(dwarf_opcode
),2)]
186 for index
in range(len(dwarf_opcode
)):
188 if index
< len(dwarf_opcode
):
189 val
= int(dwarf_opcode
[index
], 16)
193 if val
== DW_OP_regx
:
194 # Read register number
195 self
.assertTrue(len(dwarf_opcode
) > (index
+ 1))
196 reg_no
= int(dwarf_opcode
.pop(index
+ 1), 16)
198 self
.reset_test_sequence()
199 # Read register value
200 self
.test_sequence
.add_log_lines(
201 ["read packet: $p{0:x}#00".format(reg_no
),
202 {"direction": "send", "regex": r
"^\$([0-9a-fA-F]+)#",
203 "capture": {1: "p_response"}}],True)
205 Context
= self
.expect_gdbremote_sequence()
206 self
.assertIsNotNone(Context
)
207 p_response
= Context
.get("p_response")
208 self
.assertIsNotNone(p_response
)
210 if byte_order
== lldb
.eByteOrderLittle
:
211 # In case of little endian
212 # first decode the HEX ASCII bytes and then reverse it
213 # to get actual value of SR register
214 p_response
= "".join(reversed([p_response
[i
:i
+2] for i
in range(0,
215 len(p_response
),2)]))
216 # Push register value
217 dwarf_data
.append(int(p_response
,16))
219 elif val
== DW_OP_lit1
:
223 elif val
== DW_OP_lit26
:
225 dwarf_data
.append(26)
227 elif val
== DW_OP_shl
:
228 # left shift and push the result back
229 self
.assertTrue(len(dwarf_data
) > 1)
230 shift_amount
= dwarf_data
.pop()
231 val_to_shift
= dwarf_data
.pop()
232 result
= val_to_shift
<< shift_amount
233 dwarf_data
.append(result
)
235 elif val
== DW_OP_shr
:
236 # Right shift and push the result back
237 self
.assertTrue(len(dwarf_data
) > 1)
238 shift_amount
= dwarf_data
.pop()
239 val_to_shift
= dwarf_data
.pop()
240 result
= val_to_shift
>> shift_amount
241 dwarf_data
.append(result
)
243 elif val
== DW_OP_and
:
244 # And of topmost 2 elements and push the result back
245 first_ele
= dwarf_data
.pop()
246 second_ele
= dwarf_data
.pop()
247 result
= first_ele
& second_ele
248 dwarf_data
.append(result
)
251 self
.assertTrue(False and "Unprocess Dwarf Opcode")
253 self
.assertTrue(len(dwarf_data
) == 1)
254 expr_result
= dwarf_data
.pop()