345 lines · python
1"""2Test platform locate module callback functionality3"""4 5import ctypes6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from pathlib import Path9 10import lldb11 12UNITTESTS_TARGET_INPUTS_PATH = "../../../../unittests/Target/Inputs"13MODULE_PLATFORM_PATH = "/system/lib64/AndroidModule.so"14MODULE_TRIPLE = "aarch64-none-linux"15MODULE_RESOLVED_TRIPLE = "aarch64--linux-android"16MODULE_UUID = "80008338-82A0-51E5-5922-C905D23890DA-BDDEFECC"17MODULE_FUNCTION = "boom"18MODULE_HIDDEN_FUNCTION = "boom_hidden"19MODULE_FILE = "AndroidModule.so"20MODULE_NON_EXISTENT_FILE = "non-existent-file"21SYMBOL_FILE = "AndroidModule.unstripped.so"22BREAKPAD_SYMBOL_FILE = "AndroidModule.so.sym"23SYMBOL_STRIPPED = "stripped"24SYMBOL_UNSTRIPPED = "unstripped"25 26 27class LocateModuleCallbackTestCase(TestBase):28 def setUp(self):29 TestBase.setUp(self)30 self.platform = self.dbg.GetSelectedPlatform()31 self.target = self.dbg.CreateTarget("")32 self.assertTrue(self.target)33 34 self.input_dir = (35 Path(self.getSourceDir()) / UNITTESTS_TARGET_INPUTS_PATH36 ).resolve()37 self.assertTrue(self.input_dir.is_dir())38 39 def check_module_spec(self, module_spec: lldb.SBModuleSpec):40 self.assertEqual(41 MODULE_UUID.replace("-", ""),42 ctypes.string_at(43 int(module_spec.GetUUIDBytes()),44 module_spec.GetUUIDLength(),45 )46 .hex()47 .upper(),48 )49 50 self.assertEqual(MODULE_TRIPLE, module_spec.GetTriple())51 52 self.assertEqual(53 MODULE_PLATFORM_PATH, Path(module_spec.GetFileSpec().fullpath).as_posix()54 )55 56 def check_module(self, module: lldb.SBModule, symbol_file: str, symbol_kind: str):57 self.assertTrue(module.IsValid())58 59 self.assertEqual(60 MODULE_UUID,61 module.GetUUIDString(),62 )63 64 self.assertEqual(MODULE_RESOLVED_TRIPLE, module.GetTriple())65 66 self.assertEqual(67 MODULE_PLATFORM_PATH, Path(module.GetPlatformFileSpec().fullpath).as_posix()68 )69 70 self.assertTrue(71 (self.input_dir / MODULE_FILE)72 .resolve()73 .samefile(Path(module.GetFileSpec().fullpath).resolve())74 )75 76 self.assertTrue(77 (self.input_dir / symbol_file)78 .resolve()79 .samefile(Path(module.GetSymbolFileSpec().fullpath).resolve())80 )81 82 sc_list = module.FindFunctions(MODULE_FUNCTION, lldb.eSymbolTypeCode)83 self.assertEqual(1, sc_list.GetSize())84 sc_list = module.FindFunctions(MODULE_HIDDEN_FUNCTION, lldb.eSymbolTypeCode)85 self.assertEqual(0 if symbol_kind == SYMBOL_STRIPPED else 1, sc_list.GetSize())86 87 def test_set_non_callable(self):88 # The callback should be callable.89 non_callable = "a"90 91 with self.assertRaises(TypeError, msg="Need a callable object or None!"):92 self.platform.SetLocateModuleCallback(non_callable)93 94 def test_set_wrong_args(self):95 # The callback should accept 3 argument.96 def test_args2(a, b):97 pass98 99 with self.assertRaises(TypeError, msg="Expected 3 argument callable object"):100 self.platform.SetLocateModuleCallback(test_args2)101 102 def test_default(self):103 # The default behavior is to locate the module with LLDB implementation104 # and AddModule should fail.105 module = self.target.AddModule(106 MODULE_PLATFORM_PATH,107 MODULE_TRIPLE,108 MODULE_UUID,109 )110 111 self.assertFalse(module)112 113 def test_set_none(self):114 # SetLocateModuleCallback should succeed to clear the callback with None.115 # and AddModule should fail.116 self.assertTrue(self.platform.SetLocateModuleCallback(None).Success())117 118 module = self.target.AddModule(119 MODULE_PLATFORM_PATH,120 MODULE_TRIPLE,121 MODULE_UUID,122 )123 124 self.assertFalse(module)125 126 def test_return_error(self):127 # The callback fails, AddModule should fail.128 def test_locate_module(129 module_spec: lldb.SBModuleSpec,130 module_file_spec: lldb.SBFileSpec,131 symbol_file_spec: lldb.SBFileSpec,132 ):133 self.check_module_spec(module_spec)134 return lldb.SBError("locate module callback failed")135 136 self.assertTrue(137 self.platform.SetLocateModuleCallback(test_locate_module).Success()138 )139 140 module = self.target.AddModule(141 MODULE_PLATFORM_PATH,142 MODULE_TRIPLE,143 MODULE_UUID,144 )145 146 self.assertFalse(module)147 148 def test_return_no_files(self):149 # The callback succeeds but not return any files, AddModule should fail.150 def test_locate_module(151 module_spec: lldb.SBModuleSpec,152 module_file_spec: lldb.SBFileSpec,153 symbol_file_spec: lldb.SBFileSpec,154 ):155 self.check_module_spec(module_spec)156 return lldb.SBError()157 158 self.assertTrue(159 self.platform.SetLocateModuleCallback(test_locate_module).Success()160 )161 162 module = self.target.AddModule(163 MODULE_PLATFORM_PATH,164 MODULE_TRIPLE,165 MODULE_UUID,166 )167 168 self.assertFalse(module)169 170 def test_return_non_existent_module(self):171 # The callback returns non-existent module file, AddModule should fail.172 def test_locate_module(173 module_spec: lldb.SBModuleSpec,174 module_file_spec: lldb.SBFileSpec,175 symbol_file_spec: lldb.SBFileSpec,176 ):177 self.check_module_spec(module_spec)178 179 module_file_spec.SetDirectory(str(self.input_dir))180 module_file_spec.SetFilename(MODULE_NON_EXISTENT_FILE)181 182 return lldb.SBError()183 184 self.assertTrue(185 self.platform.SetLocateModuleCallback(test_locate_module).Success()186 )187 188 module = self.target.AddModule(189 MODULE_PLATFORM_PATH,190 MODULE_TRIPLE,191 MODULE_UUID,192 )193 194 self.assertFalse(module)195 196 def test_return_module_with_non_existent_symbol(self):197 # The callback returns a module and non-existent symbol file,198 # AddModule should fail.199 def test_locate_module(200 module_spec: lldb.SBModuleSpec,201 module_file_spec: lldb.SBFileSpec,202 symbol_file_spec: lldb.SBFileSpec,203 ):204 self.check_module_spec(module_spec)205 206 module_file_spec.SetDirectory(str(self.input_dir))207 module_file_spec.SetFilename(MODULE_FILE)208 209 symbol_file_spec.SetDirectory(str(self.input_dir))210 symbol_file_spec.SetFilename(MODULE_NON_EXISTENT_FILE)211 212 return lldb.SBError()213 214 self.assertTrue(215 self.platform.SetLocateModuleCallback(test_locate_module).Success()216 )217 218 module = self.target.AddModule(219 MODULE_PLATFORM_PATH,220 MODULE_TRIPLE,221 MODULE_UUID,222 )223 224 self.assertFalse(module)225 226 def test_return_non_existent_symbol(self):227 # The callback returns non-existent symbol file, AddModule should fail.228 def test_locate_module(229 module_spec: lldb.SBModuleSpec,230 module_file_spec: lldb.SBFileSpec,231 symbol_file_spec: lldb.SBFileSpec,232 ):233 self.check_module_spec(module_spec)234 235 symbol_file_spec.SetDirectory(str(self.input_dir))236 symbol_file_spec.SetFilename(MODULE_NON_EXISTENT_FILE)237 238 return lldb.SBError()239 240 self.assertTrue(241 self.platform.SetLocateModuleCallback(test_locate_module).Success()242 )243 244 module = self.target.AddModule(245 MODULE_PLATFORM_PATH,246 MODULE_TRIPLE,247 MODULE_UUID,248 )249 250 self.assertFalse(module)251 252 def test_return_module(self):253 # The callback returns the module file, AddModule should succeed.254 def test_locate_module(255 module_spec: lldb.SBModuleSpec,256 module_file_spec: lldb.SBFileSpec,257 symbol_file_spec: lldb.SBFileSpec,258 ):259 self.check_module_spec(module_spec)260 261 module_file_spec.SetDirectory(str(self.input_dir))262 module_file_spec.SetFilename(MODULE_FILE)263 264 return lldb.SBError()265 266 self.assertTrue(267 self.platform.SetLocateModuleCallback(test_locate_module).Success()268 )269 270 module = self.target.AddModule(271 MODULE_PLATFORM_PATH,272 MODULE_TRIPLE,273 MODULE_UUID,274 )275 276 self.check_module(277 module=module, symbol_file=MODULE_FILE, symbol_kind=SYMBOL_STRIPPED278 )279 280 def test_return_module_with_symbol(self):281 # The callback returns the module file and the symbol file,282 # AddModule should succeed.283 def test_locate_module(284 module_spec: lldb.SBModuleSpec,285 module_file_spec: lldb.SBFileSpec,286 symbol_file_spec: lldb.SBFileSpec,287 ):288 self.check_module_spec(module_spec)289 290 module_file_spec.SetDirectory(str(self.input_dir))291 module_file_spec.SetFilename(MODULE_FILE)292 293 symbol_file_spec.SetDirectory(str(self.input_dir))294 symbol_file_spec.SetFilename(SYMBOL_FILE)295 296 return lldb.SBError()297 298 self.assertTrue(299 self.platform.SetLocateModuleCallback(test_locate_module).Success()300 )301 302 module = self.target.AddModule(303 MODULE_PLATFORM_PATH,304 MODULE_TRIPLE,305 MODULE_UUID,306 )307 308 self.check_module(309 module=module, symbol_file=SYMBOL_FILE, symbol_kind=SYMBOL_UNSTRIPPED310 )311 312 def test_return_module_with_breakpad_symbol(self):313 # The callback returns the module file and the breakpad symbol file,314 # AddModule should succeed.315 def test_locate_module(316 module_spec: lldb.SBModuleSpec,317 module_file_spec: lldb.SBFileSpec,318 symbol_file_spec: lldb.SBFileSpec,319 ):320 self.check_module_spec(module_spec)321 322 module_file_spec.SetDirectory(str(self.input_dir))323 module_file_spec.SetFilename(MODULE_FILE)324 325 symbol_file_spec.SetDirectory(str(self.input_dir))326 symbol_file_spec.SetFilename(BREAKPAD_SYMBOL_FILE)327 328 return lldb.SBError()329 330 self.assertTrue(331 self.platform.SetLocateModuleCallback(test_locate_module).Success()332 )333 334 module = self.target.AddModule(335 MODULE_PLATFORM_PATH,336 MODULE_TRIPLE,337 MODULE_UUID,338 )339 340 self.check_module(341 module=module,342 symbol_file=BREAKPAD_SYMBOL_FILE,343 symbol_kind=SYMBOL_UNSTRIPPED,344 )345