blob: d64d9be498624e8923090e71e252d60471a737e0 [file] [edit]
"""
Test loading of a kext binary.
"""
import os
import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class LoadKextTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
def test_load_kext(self):
"""Test that lldb can load a kext binary."""
# Create kext from YAML.
self.yaml2obj("mykext.yaml", self.getBuildArtifact("mykext"))
target = self.dbg.CreateTarget(self.getBuildArtifact("mykext"))
self.assertTrue(target.IsValid())
self.assertEqual(target.GetNumModules(), 1)
mod = target.GetModuleAtIndex(0)
self.assertEqual(mod.GetFileSpec().GetFilename(), "mykext")
@skipUnlessDarwin
def test_kext_lookup_by_bundle_id_and_uuid(self):
"""Resolve a kext by bundle ID and UUID out of the darwin-kernel
platform's index of the local filesystem."""
# Restore the global state this test changes even if it fails partway.
def cleanup():
self.runCmd("platform select host")
self.runCmd("settings clear platform.plugin.darwin-kernel.kext-directories")
self.runCmd("settings clear symbols.enable-external-lookup")
self.addTearDownHook(cleanup)
# A kext is only indexed if it is a .kext bundle with a CFBundleID in
# its Info.plist, and only the ones with a .dSYM sibling are searched.
extensions = self.getBuildArtifact("Extensions")
bundle = os.path.join(extensions, "mykext.kext")
macos = os.path.join(bundle, "Contents", "MacOS")
lldbutil.mkdir_p(macos)
lldbutil.mkdir_p(bundle + ".dSYM")
self.yaml2obj("mykext.yaml", os.path.join(macos, "mykext"))
# The index only considers executable files inside the bundle.
os.chmod(os.path.join(macos, "mykext"), 0o755)
with open(os.path.join(bundle, "Contents", "Info.plist"), "w") as f:
f.write(
'<?xml version="1.0" encoding="UTF-8"?>\n'
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" '
'"http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
'<plist version="1.0"><dict>\n'
" <key>CFBundleIdentifier</key><string>com.example.mykext</string>\n"
" <key>CFBundleExecutable</key><string>mykext</string>\n"
"</dict></plist>\n"
)
# The index has to be the only thing that can answer, or a symbol server
# could resolve the UUID and the test would pass without it.
self.runCmd("settings set symbols.enable-external-lookup false")
self.runCmd(
"settings set platform.plugin.darwin-kernel.kext-directories " + extensions
)
self.runCmd("platform select darwin-kernel")
target = self.dbg.CreateTarget("")
self.assertTrue(target.IsValid())
# The bundle ID travels as the file name, which is how the kext dynamic
# loader asks for a kext.
module = target.AddModule(
"com.example.mykext", None, "17A97B33-09B7-3195-9408-DBD965D578A5"
)
self.assertTrue(module.IsValid(), "found the kext in the index")
# Assert on the whole path, not just the file name: the shared module
# list matches on UUID alone, so a module the other tests in this file
# registered under a bare name would satisfy a file name check.
self.assertEqual(module.GetFileSpec().fullpath, os.path.join(macos, "mykext"))
@skipUnlessDarwin
def test_kernel_lookup_by_uuid_without_a_process(self):
"""Search the darwin-kernel platform for a kernel before there is a
process to search on behalf of."""
# PlatformDarwinKernel only indexes a kernel binary that has a .dSYM
# sibling, and only that branch goes looking for a symbol file.
kernel_dir = self.getBuildArtifact("kernels")
lldbutil.mkdir_p(kernel_dir)
kernel = os.path.join(kernel_dir, "kernel.test")
self.yaml2obj("mykext.yaml", kernel)
lldbutil.mkdir_p(kernel + ".dSYM")
self.runCmd(
"settings set platform.plugin.darwin-kernel.kext-directories " + kernel_dir
)
self.runCmd("platform select darwin-kernel")
def cleanup():
self.runCmd("platform select host")
self.runCmd("settings clear platform.plugin.darwin-kernel.kext-directories")
self.addTearDownHook(cleanup)
target = self.dbg.CreateTarget("")
self.assertTrue(target.IsValid())
# A UUID with no file name reaches the kernel branch of
# PlatformDarwinKernel::GetSharedModule, which matches the binary above
# and then searches for its symbols. There is no process here, and the
# search must not need one.
target.AddModule(None, None, "17A97B33-09B7-3195-9408-DBD965D578A5")