xref: /llvm-project/lldb/test/API/functionalities/gdb_remote_client/TestWasm.py (revision 80fcecb13c388ff087a27a4b0e7ca3dd8c98eaa4)
1c1121908SPaolo Severiniimport lldb
2c1121908SPaolo Severiniimport binascii
3c1121908SPaolo Severinifrom lldbsuite.test.lldbtest import *
4c1121908SPaolo Severinifrom lldbsuite.test.decorators import *
533c0f93fSPavel Labathfrom lldbsuite.test.gdbclientutils import *
633c0f93fSPavel Labathfrom lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
7c1121908SPaolo Severini
8c1121908SPaolo SeveriniLLDB_INVALID_ADDRESS = lldb.LLDB_INVALID_ADDRESS
9c1121908SPaolo Severiniload_address = 0x400000000
10c1121908SPaolo Severini
112238dcc3SJonas Devlieghere
12c1121908SPaolo Severinidef format_register_value(val):
13c1121908SPaolo Severini    """
14c1121908SPaolo Severini    Encode each byte by two hex digits in little-endian order.
15c1121908SPaolo Severini    """
16c1121908SPaolo Severini    result = ""
172238dcc3SJonas Devlieghere    mask = 0xFF
18c1121908SPaolo Severini    shift = 0
19c1121908SPaolo Severini    for i in range(0, 8):
20c1121908SPaolo Severini        x = (val & mask) >> shift
212238dcc3SJonas Devlieghere        result += format(x, "02x")
22c1121908SPaolo Severini        mask <<= 8
23c1121908SPaolo Severini        shift += 8
24c1121908SPaolo Severini    return result
25c1121908SPaolo Severini
26c1121908SPaolo Severini
27c1121908SPaolo Severiniclass MyResponder(MockGDBServerResponder):
282238dcc3SJonas Devlieghere    current_pc = load_address + 0x0A
29c1121908SPaolo Severini
30c1121908SPaolo Severini    def __init__(self, obj_path, module_name=""):
31c1121908SPaolo Severini        self._obj_path = obj_path
32c1121908SPaolo Severini        self._module_name = module_name or obj_path
33c1121908SPaolo Severini        MockGDBServerResponder.__init__(self)
34c1121908SPaolo Severini
35c1121908SPaolo Severini    def respond(self, packet):
36c1121908SPaolo Severini        if packet[0:13] == "qRegisterInfo":
37c1121908SPaolo Severini            return self.qRegisterInfo(packet[13:])
38c1121908SPaolo Severini        return MockGDBServerResponder.respond(self, packet)
39c1121908SPaolo Severini
40c1121908SPaolo Severini    def qSupported(self, client_supported):
41c1121908SPaolo Severini        return "qXfer:libraries:read+;PacketSize=1000;vContSupported-"
42c1121908SPaolo Severini
43c1121908SPaolo Severini    def qHostInfo(self):
44c1121908SPaolo Severini        return ""
45c1121908SPaolo Severini
46c1121908SPaolo Severini    def QEnableErrorStrings(self):
47c1121908SPaolo Severini        return ""
48c1121908SPaolo Severini
49c1121908SPaolo Severini    def qfThreadInfo(self):
50c1121908SPaolo Severini        return "OK"
51c1121908SPaolo Severini
52c1121908SPaolo Severini    def qRegisterInfo(self, index):
532238dcc3SJonas Devlieghere        if index == 0:
54c1121908SPaolo Severini            return "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;"
55c1121908SPaolo Severini        return "E45"
56c1121908SPaolo Severini
57c1121908SPaolo Severini    def qProcessInfo(self):
582238dcc3SJonas Devlieghere        return "pid:1;ppid:1;uid:1;gid:1;euid:1;egid:1;name:%s;triple:%s;ptrsize:4" % (
592238dcc3SJonas Devlieghere            hex_encode_bytes("lldb"),
602238dcc3SJonas Devlieghere            hex_encode_bytes("wasm32-unknown-unknown-wasm"),
612238dcc3SJonas Devlieghere        )
62c1121908SPaolo Severini
63c1121908SPaolo Severini    def haltReason(self):
64c1121908SPaolo Severini        return "T05thread:1;"
65c1121908SPaolo Severini
66c1121908SPaolo Severini    def readRegister(self, register):
67c1121908SPaolo Severini        return format_register_value(self.current_pc)
68c1121908SPaolo Severini
69c1121908SPaolo Severini    def qXferRead(self, obj, annex, offset, length):
70c1121908SPaolo Severini        if obj == "libraries":
712238dcc3SJonas Devlieghere            xml = (
722238dcc3SJonas Devlieghere                '<library-list><library name="%s"><section address="%d"/></library></library-list>'
732238dcc3SJonas Devlieghere                % (self._module_name, load_address)
742238dcc3SJonas Devlieghere            )
75c1121908SPaolo Severini            return xml, False
76c1121908SPaolo Severini        else:
77c1121908SPaolo Severini            return None, False
78c1121908SPaolo Severini
79c1121908SPaolo Severini    def readMemory(self, addr, length):
80c1121908SPaolo Severini        if addr < load_address:
81c1121908SPaolo Severini            return "E02"
82c1121908SPaolo Severini        result = ""
832238dcc3SJonas Devlieghere        with open(self._obj_path, mode="rb") as file:
84c1121908SPaolo Severini            file_content = bytearray(file.read())
85c1121908SPaolo Severini            addr_from = addr - load_address
86c1121908SPaolo Severini            addr_to = addr_from + min(length, len(file_content) - addr_from)
87c1121908SPaolo Severini            for i in range(addr_from, addr_to):
882238dcc3SJonas Devlieghere                result += format(file_content[i], "02x")
89c1121908SPaolo Severini            file.close()
90c1121908SPaolo Severini        return result
91c1121908SPaolo Severini
92c1121908SPaolo Severini
93c1121908SPaolo Severiniclass TestWasm(GDBRemoteTestBase):
9456b03c35SRaphael Isemann    @skipIfAsan
95d41d5286SPavel Labath    @skipIfXmlSupportMissing
96c1121908SPaolo Severini    def test_load_module_with_embedded_symbols_from_remote(self):
97c1121908SPaolo Severini        """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module with embedded DWARF symbols"""
98c1121908SPaolo Severini
99c1121908SPaolo Severini        yaml_path = "test_wasm_embedded_debug_sections.yaml"
100c1121908SPaolo Severini        yaml_base, ext = os.path.splitext(yaml_path)
101c1121908SPaolo Severini        obj_path = self.getBuildArtifact(yaml_base)
102c1121908SPaolo Severini        self.yaml2obj(yaml_path, obj_path)
103c1121908SPaolo Severini
104c1121908SPaolo Severini        self.server.responder = MyResponder(obj_path, "test_wasm")
105c1121908SPaolo Severini
106c1121908SPaolo Severini        target = self.dbg.CreateTarget("")
107c1121908SPaolo Severini        process = self.connect(target)
1082238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
1092238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
1102238dcc3SJonas Devlieghere        )
111c1121908SPaolo Severini
112c1121908SPaolo Severini        num_modules = target.GetNumModules()
113*80fcecb1SJonas Devlieghere        self.assertEqual(1, num_modules)
114c1121908SPaolo Severini
115c1121908SPaolo Severini        module = target.GetModuleAtIndex(0)
116c1121908SPaolo Severini        num_sections = module.GetNumSections()
117*80fcecb1SJonas Devlieghere        self.assertEqual(5, num_sections)
118c1121908SPaolo Severini
119c1121908SPaolo Severini        code_section = module.GetSectionAtIndex(0)
120*80fcecb1SJonas Devlieghere        self.assertEqual("code", code_section.GetName())
121*80fcecb1SJonas Devlieghere        self.assertEqual(
1222238dcc3SJonas Devlieghere            load_address | code_section.GetFileOffset(),
1232238dcc3SJonas Devlieghere            code_section.GetLoadAddress(target),
1242238dcc3SJonas Devlieghere        )
125c1121908SPaolo Severini
126c1121908SPaolo Severini        debug_info_section = module.GetSectionAtIndex(1)
127*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_info", debug_info_section.GetName())
128*80fcecb1SJonas Devlieghere        self.assertEqual(
1292238dcc3SJonas Devlieghere            load_address | debug_info_section.GetFileOffset(),
1302238dcc3SJonas Devlieghere            debug_info_section.GetLoadAddress(target),
1312238dcc3SJonas Devlieghere        )
132c1121908SPaolo Severini
133c1121908SPaolo Severini        debug_abbrev_section = module.GetSectionAtIndex(2)
134*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
135*80fcecb1SJonas Devlieghere        self.assertEqual(
1362238dcc3SJonas Devlieghere            load_address | debug_abbrev_section.GetFileOffset(),
1372238dcc3SJonas Devlieghere            debug_abbrev_section.GetLoadAddress(target),
1382238dcc3SJonas Devlieghere        )
139c1121908SPaolo Severini
140c1121908SPaolo Severini        debug_line_section = module.GetSectionAtIndex(3)
141*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_line", debug_line_section.GetName())
142*80fcecb1SJonas Devlieghere        self.assertEqual(
1432238dcc3SJonas Devlieghere            load_address | debug_line_section.GetFileOffset(),
1442238dcc3SJonas Devlieghere            debug_line_section.GetLoadAddress(target),
1452238dcc3SJonas Devlieghere        )
146c1121908SPaolo Severini
147c1121908SPaolo Severini        debug_str_section = module.GetSectionAtIndex(4)
148*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_str", debug_str_section.GetName())
149*80fcecb1SJonas Devlieghere        self.assertEqual(
1502238dcc3SJonas Devlieghere            load_address | debug_line_section.GetFileOffset(),
1512238dcc3SJonas Devlieghere            debug_line_section.GetLoadAddress(target),
1522238dcc3SJonas Devlieghere        )
153c1121908SPaolo Severini
15456b03c35SRaphael Isemann    @skipIfAsan
155d41d5286SPavel Labath    @skipIfXmlSupportMissing
156c1121908SPaolo Severini    def test_load_module_with_stripped_symbols_from_remote(self):
157c1121908SPaolo Severini        """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module with symbols stripped into a separate Wasm file"""
158c1121908SPaolo Severini
159c1121908SPaolo Severini        sym_yaml_path = "test_sym.yaml"
160c1121908SPaolo Severini        sym_yaml_base, ext = os.path.splitext(sym_yaml_path)
161c1121908SPaolo Severini        sym_obj_path = self.getBuildArtifact(sym_yaml_base) + ".wasm"
162c1121908SPaolo Severini        self.yaml2obj(sym_yaml_path, sym_obj_path)
163c1121908SPaolo Severini
164c1121908SPaolo Severini        yaml_path = "test_wasm_external_debug_sections.yaml"
165c1121908SPaolo Severini        yaml_base, ext = os.path.splitext(yaml_path)
166c1121908SPaolo Severini        obj_path = self.getBuildArtifact(yaml_base) + ".wasm"
167c1121908SPaolo Severini        self.yaml2obj(yaml_path, obj_path)
168c1121908SPaolo Severini
169c1121908SPaolo Severini        self.server.responder = MyResponder(obj_path, "test_wasm")
170c1121908SPaolo Severini
171c1121908SPaolo Severini        folder, _ = os.path.split(obj_path)
1722238dcc3SJonas Devlieghere        self.runCmd(
1732238dcc3SJonas Devlieghere            "settings set target.debug-file-search-paths " + os.path.abspath(folder)
1742238dcc3SJonas Devlieghere        )
175c1121908SPaolo Severini
176c1121908SPaolo Severini        target = self.dbg.CreateTarget("")
177c1121908SPaolo Severini        process = self.connect(target)
1782238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
1792238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
1802238dcc3SJonas Devlieghere        )
181c1121908SPaolo Severini
182c1121908SPaolo Severini        num_modules = target.GetNumModules()
183*80fcecb1SJonas Devlieghere        self.assertEqual(1, num_modules)
184c1121908SPaolo Severini
185c1121908SPaolo Severini        module = target.GetModuleAtIndex(0)
186c1121908SPaolo Severini        num_sections = module.GetNumSections()
187*80fcecb1SJonas Devlieghere        self.assertEqual(5, num_sections)
188c1121908SPaolo Severini
189c1121908SPaolo Severini        code_section = module.GetSectionAtIndex(0)
190*80fcecb1SJonas Devlieghere        self.assertEqual("code", code_section.GetName())
191*80fcecb1SJonas Devlieghere        self.assertEqual(
1922238dcc3SJonas Devlieghere            load_address | code_section.GetFileOffset(),
1932238dcc3SJonas Devlieghere            code_section.GetLoadAddress(target),
1942238dcc3SJonas Devlieghere        )
195c1121908SPaolo Severini
196c1121908SPaolo Severini        debug_info_section = module.GetSectionAtIndex(1)
197*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_info", debug_info_section.GetName())
198*80fcecb1SJonas Devlieghere        self.assertEqual(
1992238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target)
2002238dcc3SJonas Devlieghere        )
201c1121908SPaolo Severini
202c1121908SPaolo Severini        debug_abbrev_section = module.GetSectionAtIndex(2)
203*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
204*80fcecb1SJonas Devlieghere        self.assertEqual(
2052238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target)
2062238dcc3SJonas Devlieghere        )
207c1121908SPaolo Severini
208c1121908SPaolo Severini        debug_line_section = module.GetSectionAtIndex(3)
209*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_line", debug_line_section.GetName())
210*80fcecb1SJonas Devlieghere        self.assertEqual(
2112238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
2122238dcc3SJonas Devlieghere        )
213c1121908SPaolo Severini
214c1121908SPaolo Severini        debug_str_section = module.GetSectionAtIndex(4)
215*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_str", debug_str_section.GetName())
216*80fcecb1SJonas Devlieghere        self.assertEqual(
2172238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
2182238dcc3SJonas Devlieghere        )
219c1121908SPaolo Severini
22056b03c35SRaphael Isemann    @skipIfAsan
221d41d5286SPavel Labath    @skipIfXmlSupportMissing
222c1121908SPaolo Severini    def test_load_module_from_file(self):
223c1121908SPaolo Severini        """Test connecting to a WebAssembly engine via GDB-remote and loading a Wasm module from a file"""
224c1121908SPaolo Severini
225c1121908SPaolo Severini        yaml_path = "test_wasm_embedded_debug_sections.yaml"
226c1121908SPaolo Severini        yaml_base, ext = os.path.splitext(yaml_path)
227c1121908SPaolo Severini        obj_path = self.getBuildArtifact(yaml_base)
228c1121908SPaolo Severini        self.yaml2obj(yaml_path, obj_path)
229c1121908SPaolo Severini
230c1121908SPaolo Severini        self.server.responder = MyResponder(obj_path)
231c1121908SPaolo Severini
232c1121908SPaolo Severini        target = self.dbg.CreateTarget("")
233c1121908SPaolo Severini        process = self.connect(target)
2342238dcc3SJonas Devlieghere        lldbutil.expect_state_changes(
2352238dcc3SJonas Devlieghere            self, self.dbg.GetListener(), process, [lldb.eStateStopped]
2362238dcc3SJonas Devlieghere        )
237c1121908SPaolo Severini
238c1121908SPaolo Severini        num_modules = target.GetNumModules()
239*80fcecb1SJonas Devlieghere        self.assertEqual(1, num_modules)
240c1121908SPaolo Severini
241c1121908SPaolo Severini        module = target.GetModuleAtIndex(0)
242c1121908SPaolo Severini        num_sections = module.GetNumSections()
243*80fcecb1SJonas Devlieghere        self.assertEqual(5, num_sections)
244c1121908SPaolo Severini
245c1121908SPaolo Severini        code_section = module.GetSectionAtIndex(0)
246*80fcecb1SJonas Devlieghere        self.assertEqual("code", code_section.GetName())
247*80fcecb1SJonas Devlieghere        self.assertEqual(
2482238dcc3SJonas Devlieghere            load_address | code_section.GetFileOffset(),
2492238dcc3SJonas Devlieghere            code_section.GetLoadAddress(target),
2502238dcc3SJonas Devlieghere        )
251c1121908SPaolo Severini
252c1121908SPaolo Severini        debug_info_section = module.GetSectionAtIndex(1)
253*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_info", debug_info_section.GetName())
254*80fcecb1SJonas Devlieghere        self.assertEqual(
2552238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_info_section.GetLoadAddress(target)
2562238dcc3SJonas Devlieghere        )
257c1121908SPaolo Severini
258c1121908SPaolo Severini        debug_abbrev_section = module.GetSectionAtIndex(2)
259*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_abbrev", debug_abbrev_section.GetName())
260*80fcecb1SJonas Devlieghere        self.assertEqual(
2612238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_abbrev_section.GetLoadAddress(target)
2622238dcc3SJonas Devlieghere        )
263c1121908SPaolo Severini
264c1121908SPaolo Severini        debug_line_section = module.GetSectionAtIndex(3)
265*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_line", debug_line_section.GetName())
266*80fcecb1SJonas Devlieghere        self.assertEqual(
2672238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
2682238dcc3SJonas Devlieghere        )
269c1121908SPaolo Severini
270c1121908SPaolo Severini        debug_str_section = module.GetSectionAtIndex(4)
271*80fcecb1SJonas Devlieghere        self.assertEqual(".debug_str", debug_str_section.GetName())
272*80fcecb1SJonas Devlieghere        self.assertEqual(
2732238dcc3SJonas Devlieghere            LLDB_INVALID_ADDRESS, debug_line_section.GetLoadAddress(target)
2742238dcc3SJonas Devlieghere        )
275