xref: /llvm-project/lldb/packages/Python/lldbsuite/test/lldbdwarf.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1f440244dSNitesh Jain""" This module implement Dwarf expression opcode parser. """
2f440244dSNitesh Jain
3f440244dSNitesh Jainimport lldb
4f440244dSNitesh Jain
5f440244dSNitesh Jain# DWARF Expression operators.
6f440244dSNitesh JainDW_OP_addr = 0x03
7f440244dSNitesh JainDW_OP_deref = 0x06
8f440244dSNitesh JainDW_OP_const1u = 0x08
9f440244dSNitesh JainDW_OP_const1s = 0x09
10f440244dSNitesh JainDW_OP_const2u = 0x0A
11f440244dSNitesh JainDW_OP_const2s = 0x0B
12f440244dSNitesh JainDW_OP_const4u = 0x0C
13f440244dSNitesh JainDW_OP_const4s = 0x0D
14f440244dSNitesh JainDW_OP_const8u = 0x0E
15f440244dSNitesh JainDW_OP_const8s = 0x0F
16f440244dSNitesh JainDW_OP_constu = 0x10
17f440244dSNitesh JainDW_OP_consts = 0x11
18f440244dSNitesh JainDW_OP_dup = 0x12
19f440244dSNitesh JainDW_OP_drop = 0x13
20f440244dSNitesh JainDW_OP_over = 0x14
21f440244dSNitesh JainDW_OP_pick = 0x15
22f440244dSNitesh JainDW_OP_swap = 0x16
23f440244dSNitesh JainDW_OP_rot = 0x17
24f440244dSNitesh JainDW_OP_xderef = 0x18
25f440244dSNitesh JainDW_OP_abs = 0x19
26f440244dSNitesh JainDW_OP_and = 0x1A
27f440244dSNitesh JainDW_OP_div = 0x1B
28f440244dSNitesh JainDW_OP_minus = 0x1C
29f440244dSNitesh JainDW_OP_mod = 0x1D
30f440244dSNitesh JainDW_OP_mul = 0x1E
31f440244dSNitesh JainDW_OP_neg = 0x1F
32f440244dSNitesh JainDW_OP_not = 0x20
33f440244dSNitesh JainDW_OP_or = 0x21
34f440244dSNitesh JainDW_OP_plus = 0x22
35f440244dSNitesh JainDW_OP_plus_uconst = 0x23
36f440244dSNitesh JainDW_OP_shl = 0x24
37f440244dSNitesh JainDW_OP_shr = 0x25
38f440244dSNitesh JainDW_OP_shra = 0x26
39f440244dSNitesh JainDW_OP_xor = 0x27
40f440244dSNitesh JainDW_OP_skip = 0x2F
41f440244dSNitesh JainDW_OP_bra = 0x28
42f440244dSNitesh JainDW_OP_eq = 0x29
43f440244dSNitesh JainDW_OP_ge = 0x2A
44f440244dSNitesh JainDW_OP_gt = 0x2B
45f440244dSNitesh JainDW_OP_le = 0x2C
46f440244dSNitesh JainDW_OP_lt = 0x2D
47f440244dSNitesh JainDW_OP_ne = 0x2E
48f440244dSNitesh JainDW_OP_lit0 = 0x30
49f440244dSNitesh JainDW_OP_lit1 = 0x31
50f440244dSNitesh JainDW_OP_lit2 = 0x32
51f440244dSNitesh JainDW_OP_lit3 = 0x33
52f440244dSNitesh JainDW_OP_lit4 = 0x34
53f440244dSNitesh JainDW_OP_lit5 = 0x35
54f440244dSNitesh JainDW_OP_lit6 = 0x36
55f440244dSNitesh JainDW_OP_lit7 = 0x37
56f440244dSNitesh JainDW_OP_lit8 = 0x38
57f440244dSNitesh JainDW_OP_lit9 = 0x39
58f440244dSNitesh JainDW_OP_lit10 = 0x3A
59f440244dSNitesh JainDW_OP_lit11 = 0x3B
60f440244dSNitesh JainDW_OP_lit12 = 0x3C
61f440244dSNitesh JainDW_OP_lit13 = 0x3D
62f440244dSNitesh JainDW_OP_lit14 = 0x3E
63f440244dSNitesh JainDW_OP_lit15 = 0x3F
64f440244dSNitesh JainDW_OP_lit16 = 0x40
65f440244dSNitesh JainDW_OP_lit17 = 0x41
66f440244dSNitesh JainDW_OP_lit18 = 0x42
67f440244dSNitesh JainDW_OP_lit19 = 0x43
68f440244dSNitesh JainDW_OP_lit20 = 0x44
69f440244dSNitesh JainDW_OP_lit21 = 0x45
70f440244dSNitesh JainDW_OP_lit22 = 0x46
71f440244dSNitesh JainDW_OP_lit23 = 0x47
72f440244dSNitesh JainDW_OP_lit24 = 0x48
73f440244dSNitesh JainDW_OP_lit25 = 0x49
74f440244dSNitesh JainDW_OP_lit26 = 0x4A
75f440244dSNitesh JainDW_OP_lit27 = 0x4B
76f440244dSNitesh JainDW_OP_lit28 = 0x4C
77f440244dSNitesh JainDW_OP_lit29 = 0x4D
78f440244dSNitesh JainDW_OP_lit30 = 0x4E
79f440244dSNitesh JainDW_OP_lit31 = 0x4F
80f440244dSNitesh JainDW_OP_reg0 = 0x50
81f440244dSNitesh JainDW_OP_reg1 = 0x51
82f440244dSNitesh JainDW_OP_reg2 = 0x52
83f440244dSNitesh JainDW_OP_reg3 = 0x53
84f440244dSNitesh JainDW_OP_reg4 = 0x54
85f440244dSNitesh JainDW_OP_reg5 = 0x55
86f440244dSNitesh JainDW_OP_reg6 = 0x56
87f440244dSNitesh JainDW_OP_reg7 = 0x57
88f440244dSNitesh JainDW_OP_reg8 = 0x58
89f440244dSNitesh JainDW_OP_reg9 = 0x59
90f440244dSNitesh JainDW_OP_reg10 = 0x5A
91f440244dSNitesh JainDW_OP_reg11 = 0x5B
92f440244dSNitesh JainDW_OP_reg12 = 0x5C
93f440244dSNitesh JainDW_OP_reg13 = 0x5D
94f440244dSNitesh JainDW_OP_reg14 = 0x5E
95f440244dSNitesh JainDW_OP_reg15 = 0x5F
96f440244dSNitesh JainDW_OP_reg16 = 0x60
97f440244dSNitesh JainDW_OP_reg17 = 0x61
98f440244dSNitesh JainDW_OP_reg18 = 0x62
99f440244dSNitesh JainDW_OP_reg19 = 0x63
100f440244dSNitesh JainDW_OP_reg20 = 0x64
101f440244dSNitesh JainDW_OP_reg21 = 0x65
102f440244dSNitesh JainDW_OP_reg22 = 0x66
103f440244dSNitesh JainDW_OP_reg23 = 0x67
104f440244dSNitesh JainDW_OP_reg24 = 0x68
105f440244dSNitesh JainDW_OP_reg25 = 0x69
106f440244dSNitesh JainDW_OP_reg26 = 0x6A
107f440244dSNitesh JainDW_OP_reg27 = 0x6B
108f440244dSNitesh JainDW_OP_reg28 = 0x6C
109f440244dSNitesh JainDW_OP_reg29 = 0x6D
110f440244dSNitesh JainDW_OP_reg30 = 0x6E
111f440244dSNitesh JainDW_OP_reg31 = 0x6F
112f440244dSNitesh JainDW_OP_breg0 = 0x70
113f440244dSNitesh JainDW_OP_breg1 = 0x71
114f440244dSNitesh JainDW_OP_breg2 = 0x72
115f440244dSNitesh JainDW_OP_breg3 = 0x73
116f440244dSNitesh JainDW_OP_breg4 = 0x74
117f440244dSNitesh JainDW_OP_breg5 = 0x75
118f440244dSNitesh JainDW_OP_breg6 = 0x76
119f440244dSNitesh JainDW_OP_breg7 = 0x77
120f440244dSNitesh JainDW_OP_breg8 = 0x78
121f440244dSNitesh JainDW_OP_breg9 = 0x79
122f440244dSNitesh JainDW_OP_breg10 = 0x7A
123f440244dSNitesh JainDW_OP_breg11 = 0x7B
124f440244dSNitesh JainDW_OP_breg12 = 0x7C
125f440244dSNitesh JainDW_OP_breg13 = 0x7D
126f440244dSNitesh JainDW_OP_breg14 = 0x7E
127f440244dSNitesh JainDW_OP_breg15 = 0x7F
128f440244dSNitesh JainDW_OP_breg16 = 0x80
129f440244dSNitesh JainDW_OP_breg17 = 0x81
130f440244dSNitesh JainDW_OP_breg18 = 0x82
131f440244dSNitesh JainDW_OP_breg19 = 0x83
132f440244dSNitesh JainDW_OP_breg20 = 0x84
133f440244dSNitesh JainDW_OP_breg21 = 0x85
134f440244dSNitesh JainDW_OP_breg22 = 0x86
135f440244dSNitesh JainDW_OP_breg23 = 0x87
136f440244dSNitesh JainDW_OP_breg24 = 0x88
137f440244dSNitesh JainDW_OP_breg25 = 0x89
138f440244dSNitesh JainDW_OP_breg26 = 0x8A
139f440244dSNitesh JainDW_OP_breg27 = 0x8B
140f440244dSNitesh JainDW_OP_breg28 = 0x8C
141f440244dSNitesh JainDW_OP_breg29 = 0x8D
142f440244dSNitesh JainDW_OP_breg30 = 0x8E
143f440244dSNitesh JainDW_OP_breg31 = 0x8F
144f440244dSNitesh JainDW_OP_regx = 0x90
145f440244dSNitesh JainDW_OP_fbreg = 0x91
146f440244dSNitesh JainDW_OP_bregx = 0x92
147f440244dSNitesh JainDW_OP_piece = 0x93
148f440244dSNitesh JainDW_OP_deref_size = 0x94
149f440244dSNitesh JainDW_OP_xderef_size = 0x95
150f440244dSNitesh JainDW_OP_nop = 0x96
151f440244dSNitesh JainDW_OP_push_object_address = 0x97
152f440244dSNitesh JainDW_OP_call2 = 0x98
153f440244dSNitesh JainDW_OP_call4 = 0x99
154f440244dSNitesh JainDW_OP_call_ref = 0x9A
155f440244dSNitesh JainDW_OP_form_tls_address = 0x9B
156f440244dSNitesh JainDW_OP_call_frame_cfa = 0x9C
157f440244dSNitesh JainDW_OP_bit_piece = 0x9D
158f440244dSNitesh JainDW_OP_implicit_value = 0x9E
159f440244dSNitesh JainDW_OP_stack_value = 0x9F
160f440244dSNitesh JainDW_OP_lo_user = 0xE0
161f440244dSNitesh JainDW_OP_GNU_push_tls_address = 0xE0
162f440244dSNitesh JainDW_OP_hi_user = 0xFF
163f440244dSNitesh Jain
164f440244dSNitesh Jain
165f440244dSNitesh Jainclass DwarfOpcodeParser(object):
166f440244dSNitesh Jain    def updateRegInfoBitsize(self, reg_info, byte_order):
167f440244dSNitesh Jain        """Update the regInfo bit size."""
168f440244dSNitesh Jain
169f440244dSNitesh Jain        # Evaluate Dwarf Expression
170*2238dcc3SJonas Devlieghere        expr_result = self.evaluateDwarfExpression(
171*2238dcc3SJonas Devlieghere            reg_info["dynamic_size_dwarf_expr_bytes"], byte_order
172*2238dcc3SJonas Devlieghere        )
173f440244dSNitesh Jain
174f440244dSNitesh Jain        if expr_result == 0:
175f440244dSNitesh Jain            reg_info["bitsize"] = 32
176f440244dSNitesh Jain        elif expr_result == 1:
177f440244dSNitesh Jain            reg_info["bitsize"] = 64
178f440244dSNitesh Jain
179f440244dSNitesh Jain    def evaluateDwarfExpression(self, dwarf_opcode, byte_order):
180f440244dSNitesh Jain        """Evaluate Dwarf Expression."""
181f440244dSNitesh Jain
182f440244dSNitesh Jain        dwarf_opcode = [dwarf_opcode[i : i + 2] for i in range(0, len(dwarf_opcode), 2)]
183f440244dSNitesh Jain        dwarf_data = []
184f440244dSNitesh Jain        for index in range(len(dwarf_opcode)):
185f440244dSNitesh Jain            if index < len(dwarf_opcode):
186f440244dSNitesh Jain                val = int(dwarf_opcode[index], 16)
187f440244dSNitesh Jain            else:
188f440244dSNitesh Jain                break
189f440244dSNitesh Jain
190f440244dSNitesh Jain            if val == DW_OP_regx:
191f440244dSNitesh Jain                # Read register number
192f440244dSNitesh Jain                self.assertTrue(len(dwarf_opcode) > (index + 1))
193f440244dSNitesh Jain                reg_no = int(dwarf_opcode.pop(index + 1), 16)
194f440244dSNitesh Jain
195f440244dSNitesh Jain                self.reset_test_sequence()
196f440244dSNitesh Jain                # Read register value
197f440244dSNitesh Jain                self.test_sequence.add_log_lines(
198*2238dcc3SJonas Devlieghere                    [
199*2238dcc3SJonas Devlieghere                        "read packet: $p{0:x}#00".format(reg_no),
200*2238dcc3SJonas Devlieghere                        {
201*2238dcc3SJonas Devlieghere                            "direction": "send",
202*2238dcc3SJonas Devlieghere                            "regex": r"^\$([0-9a-fA-F]+)#",
203*2238dcc3SJonas Devlieghere                            "capture": {1: "p_response"},
204*2238dcc3SJonas Devlieghere                        },
205*2238dcc3SJonas Devlieghere                    ],
206*2238dcc3SJonas Devlieghere                    True,
207*2238dcc3SJonas Devlieghere                )
208f440244dSNitesh Jain
209f440244dSNitesh Jain                Context = self.expect_gdbremote_sequence()
210f440244dSNitesh Jain                self.assertIsNotNone(Context)
211f440244dSNitesh Jain                p_response = Context.get("p_response")
212f440244dSNitesh Jain                self.assertIsNotNone(p_response)
213f440244dSNitesh Jain
214f440244dSNitesh Jain                if byte_order == lldb.eByteOrderLittle:
215f440244dSNitesh Jain                    # In case of little endian
216f440244dSNitesh Jain                    # first decode the HEX ASCII bytes and then reverse it
217f440244dSNitesh Jain                    # to get actual value of SR register
218*2238dcc3SJonas Devlieghere                    p_response = "".join(
219*2238dcc3SJonas Devlieghere                        reversed(
220*2238dcc3SJonas Devlieghere                            [
221*2238dcc3SJonas Devlieghere                                p_response[i : i + 2]
222*2238dcc3SJonas Devlieghere                                for i in range(0, len(p_response), 2)
223*2238dcc3SJonas Devlieghere                            ]
224*2238dcc3SJonas Devlieghere                        )
225*2238dcc3SJonas Devlieghere                    )
226f440244dSNitesh Jain                # Push register value
227f440244dSNitesh Jain                dwarf_data.append(int(p_response, 16))
228f440244dSNitesh Jain
229f440244dSNitesh Jain            elif val == DW_OP_lit1:
230f440244dSNitesh Jain                # Push literal 1
231f440244dSNitesh Jain                dwarf_data.append(1)
232f440244dSNitesh Jain
233f440244dSNitesh Jain            elif val == DW_OP_lit26:
234f440244dSNitesh Jain                # Push literal 26
235f440244dSNitesh Jain                dwarf_data.append(26)
236f440244dSNitesh Jain
237f440244dSNitesh Jain            elif val == DW_OP_shl:
238f440244dSNitesh Jain                # left shift and push the result back
239f440244dSNitesh Jain                self.assertTrue(len(dwarf_data) > 1)
240f440244dSNitesh Jain                shift_amount = dwarf_data.pop()
241f440244dSNitesh Jain                val_to_shift = dwarf_data.pop()
242f440244dSNitesh Jain                result = val_to_shift << shift_amount
243f440244dSNitesh Jain                dwarf_data.append(result)
244f440244dSNitesh Jain
245f440244dSNitesh Jain            elif val == DW_OP_shr:
246f440244dSNitesh Jain                # Right shift and push the result back
247f440244dSNitesh Jain                self.assertTrue(len(dwarf_data) > 1)
248f440244dSNitesh Jain                shift_amount = dwarf_data.pop()
249f440244dSNitesh Jain                val_to_shift = dwarf_data.pop()
250f440244dSNitesh Jain                result = val_to_shift >> shift_amount
251f440244dSNitesh Jain                dwarf_data.append(result)
252f440244dSNitesh Jain
253f440244dSNitesh Jain            elif val == DW_OP_and:
254f440244dSNitesh Jain                # And of topmost 2 elements and push the result back
255f440244dSNitesh Jain                first_ele = dwarf_data.pop()
256f440244dSNitesh Jain                second_ele = dwarf_data.pop()
257f440244dSNitesh Jain                result = first_ele & second_ele
258f440244dSNitesh Jain                dwarf_data.append(result)
259f440244dSNitesh Jain
260f440244dSNitesh Jain            else:
261f440244dSNitesh Jain                self.assertTrue(False and "Unprocess Dwarf Opcode")
262f440244dSNitesh Jain
263f440244dSNitesh Jain        self.assertTrue(len(dwarf_data) == 1)
264f440244dSNitesh Jain        expr_result = dwarf_data.pop()
265f440244dSNitesh Jain        return expr_result
266