1import lldb 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test.decorators import * 4from lldbsuite.test.gdbclientutils import * 5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 6from lldbsuite.support import seven 7 8class MyResponder(MockGDBServerResponder): 9 """ 10 A responder which simulates a process with a single shared library loaded. 11 Its parameters allow configuration of various properties of the library. 12 """ 13 14 def __init__(self, testcase, triple, library_name, auxv_entry, region_info): 15 MockGDBServerResponder.__init__(self) 16 self.testcase = testcase 17 self._triple = triple 18 self._library_name = library_name 19 self._auxv_entry = auxv_entry 20 self._region_info = region_info 21 22 def qSupported(self, client_supported): 23 return (super().qSupported(client_supported) + 24 ";qXfer:auxv:read+;qXfer:libraries-svr4:read+") 25 26 def qXferRead(self, obj, annex, offset, length): 27 if obj == "features" and annex == "target.xml": 28 return """<?xml version="1.0"?> 29 <target version="1.0"> 30 <architecture>i386:x86-64</architecture> 31 <feature name="org.gnu.gdb.i386.core"> 32 <reg name="rip" bitsize="64" regnum="0" type="code_ptr" group="general"/> 33 </feature> 34 </target>""", False 35 elif obj == "auxv": 36 # 0x09 = AT_ENTRY, which lldb uses to compute the load bias of the 37 # main binary. 38 return hex_decode_bytes(self._auxv_entry + 39 "09000000000000000000ee000000000000000000000000000000000000000000"), False 40 elif obj == "libraries-svr4": 41 return """<?xml version="1.0"?> 42 <library-list-svr4 version="1.0"> 43 <library name="%s" lm="0xdeadbeef" l_addr="0xef0000" l_ld="0xdeadbeef"/> 44 </library-list-svr4>""" % self._library_name, False 45 else: 46 return None, False 47 48 def qfThreadInfo(self): 49 return "m47" 50 51 def qsThreadInfo(self): 52 return "l" 53 54 def qProcessInfo(self): 55 return "pid:47;ptrsize:8;endian:little;triple:%s;" % hex_encode_bytes(self._triple) 56 57 def setBreakpoint(self, packet): 58 return "OK" 59 60 def readMemory(self, addr, length): 61 if addr == 0xee1000: 62 return "00"*0x30 + "0020ee0000000000" 63 elif addr == 0xee2000: 64 return "01000000000000000030ee0000000000dead00000000000000000000000000000000000000000000" 65 elif addr == 0xef0000: 66 with open(self.testcase.getBuildArtifact("libmodule_load.so"), "rb") as f: 67 contents = f.read(-1) 68 return hex_encode_bytes(seven.bitcast_to_string(contents)) 69 return ("baadf00d00"*1000)[0:length*2] 70 71 def qMemoryRegionInfo(self, addr): 72 if addr < 0xee0000: 73 return "start:0;size:ee0000;" 74 elif addr < 0xef0000: 75 return "start:ee0000;size:10000;" 76 elif addr < 0xf00000: 77 return "start:ef0000;size:1000;permissions:rx;" + self._region_info 78 else: 79 return "start:ef1000;size:ffffffffff10f000" 80 81class TestGdbClientModuleLoad(GDBRemoteTestBase): 82 83 mydir = TestBase.compute_mydir(__file__) 84 85 @skipIfXmlSupportMissing 86 def test_android_app_process(self): 87 """ 88 This test simulates the scenario where the (android) dynamic linker 89 reports incorrect file name of the main executable. Lldb uses 90 qMemoryRegionInfo to get the correct value. 91 """ 92 region_info = "name:%s;" % ( 93 hex_encode_bytes(self.getBuildArtifact("libmodule_load.so"))) 94 self.server.responder = MyResponder(self, "x86_64-pc-linux-android", 95 "bogus-name", "", region_info) 96 self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so")) 97 target = self.createTarget("module_load.yaml") 98 99 process = self.connect(target) 100 self.assertTrue(process.IsValid(), "Process is valid") 101 102 lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 103 [lldb.eStateStopped]) 104 105 self.filecheck("image list", __file__, "-check-prefix=ANDROID") 106# ANDROID: [ 0] {{.*}} 0x0000000000ee0000 {{.*}}module_load 107# ANDROID: [ 1] {{.*}} 0x0000000000ef0000 {{.*}}libmodule_load.so 108 109 @skipIfXmlSupportMissing 110 def test_vdso(self): 111 """ 112 This test checks vdso loading in the situation where the process does 113 not have memory region information about the vdso address. This can 114 happen in core files, as they don't store this data. 115 We want to check that the vdso is loaded exactly once. 116 """ 117 # vdso address 118 AT_SYSINFO_EHDR = "21000000000000000000ef0000000000" 119 self.server.responder = MyResponder(self, "x86_64-pc-linux", 120 "linux-vdso.so.1", AT_SYSINFO_EHDR, "") 121 self.yaml2obj("module_load.yaml", self.getBuildArtifact("libmodule_load.so")) 122 target = self.createTarget("module_load.yaml") 123 124 process = self.connect(target) 125 self.assertTrue(process.IsValid(), "Process is valid") 126 127 lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, 128 [lldb.eStateStopped]) 129 130 self.filecheck("image list", __file__, "-check-prefix=VDSO") 131# VDSO: [ 0] {{.*}} 0x0000000000ee0000 {{.*}}module_load 132# VDSO: [ 1] {{.*}} 0x0000000000ef0000 {{.*}}[vdso] 133 self.assertEquals(self.target().GetNumModules(), 2) 134