forked from OSchip/llvm-project
Have kernel binary scanner load dSYMs as binary+dSYM if best thing found
lldb's PlatforDarwinKernel scans the local filesystem (well known locations, plus user-specified directories) for kernels and kexts when doing kernel debugging, and loads them automatically. Sometimes kernel developers want to debug with *only* a dSYM, in which case they give lldb the DWARF binary + the dSYM as a binary and symbol file. This patch adds code to lldb to do this automatically if that's the best thing lldb can find. A few other bits of cleanup in PlatformDarwinKernel that I undertook at the same time: 1. Remove the 'platform.plugin.darwin-kernel.search-locally-for-kexts' setting. When I added the local filesystem index at start of kernel debugging, I thought people might object to the cost of the search and want a way to disable it. No one has. 2. Change the behavior of 'plugin.dynamic-loader.darwin-kernel.load-kexts' setting so it does not disable the local filesystem scan, or use of the local filesystem binaries. 3. PlatformDarwinKernel::GetSharedModule into GetSharedModuleKext and GetSharedModuleKernel for easier readability & maintenance. 4. Added accounting of .dSYM.yaa files (an archive format akin to tar) that I come across during the scan. I'm not using these for now; it would be very expensive to expand the archives & see if the UUID matches what I'm searching for. <rdar://problem/69774993> Differential Revision: https://reviews.llvm.org/D88632
This commit is contained in:
parent
5136f4748a
commit
a1e97923a0
|
@ -517,12 +517,8 @@ DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel(Process *process,
|
|||
Status error;
|
||||
PlatformSP platform_sp(
|
||||
Platform::Create(PlatformDarwinKernel::GetPluginNameStatic(), error));
|
||||
// Only select the darwin-kernel Platform if we've been asked to load kexts.
|
||||
// It can take some time to scan over all of the kext info.plists and that
|
||||
// shouldn't be done if kext loading is explicitly disabled.
|
||||
if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts()) {
|
||||
if (platform_sp.get())
|
||||
process->GetTarget().SetPlatform(platform_sp);
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
|
|
|
@ -199,13 +199,6 @@ public:
|
|||
|
||||
virtual ~PlatformDarwinKernelProperties() {}
|
||||
|
||||
bool GetSearchForKexts() const {
|
||||
const uint32_t idx = ePropertySearchForKexts;
|
||||
return m_collection_sp->GetPropertyAtIndexAsBoolean(
|
||||
NULL, idx,
|
||||
g_platformdarwinkernel_properties[idx].default_uint_value != 0);
|
||||
}
|
||||
|
||||
FileSpecList GetKextDirectories() const {
|
||||
const uint32_t idx = ePropertyKextDirectories;
|
||||
const OptionValueFileSpecList *option_value =
|
||||
|
@ -245,14 +238,12 @@ PlatformDarwinKernel::PlatformDarwinKernel(
|
|||
m_name_to_kext_path_map_with_dsyms(),
|
||||
m_name_to_kext_path_map_without_dsyms(), m_search_directories(),
|
||||
m_search_directories_no_recursing(), m_kernel_binaries_with_dsyms(),
|
||||
m_kernel_binaries_without_dsyms(),
|
||||
m_ios_debug_session(is_ios_debug_session)
|
||||
m_kernel_binaries_without_dsyms(), m_kernel_dsyms_no_binaries(),
|
||||
m_kernel_dsyms_yaas(), m_ios_debug_session(is_ios_debug_session)
|
||||
|
||||
{
|
||||
if (GetGlobalProperties()->GetSearchForKexts()) {
|
||||
CollectKextAndKernelDirectories();
|
||||
SearchForKextsAndKernelsRecursively();
|
||||
}
|
||||
CollectKextAndKernelDirectories();
|
||||
SearchForKextsAndKernelsRecursively();
|
||||
}
|
||||
|
||||
/// Destructor.
|
||||
|
@ -293,6 +284,10 @@ void PlatformDarwinKernel::GetStatus(Stream &strm) {
|
|||
(int)m_kernel_binaries_with_dsyms.size());
|
||||
strm.Printf(" Number of Kernel binaries without dSYMs indexed: %d\n",
|
||||
(int)m_kernel_binaries_without_dsyms.size());
|
||||
strm.Printf(" Number of Kernel dSYMs with no binaries indexed: %d\n",
|
||||
(int)m_kernel_dsyms_no_binaries.size());
|
||||
strm.Printf(" Number of Kernel dSYM.yaa's indexed: %d\n",
|
||||
(int)m_kernel_dsyms_yaas.size());
|
||||
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
||||
if (log) {
|
||||
|
@ -305,14 +300,22 @@ void PlatformDarwinKernel::GetStatus(Stream &strm) {
|
|||
for (auto pos : m_name_to_kext_path_map_without_dsyms) {
|
||||
LLDB_LOGF(log, "%s", pos.second.GetPath().c_str());
|
||||
}
|
||||
LLDB_LOGF(log, "\nkernels with dSYMS");
|
||||
LLDB_LOGF(log, "\nkernel binaries with dSYMS");
|
||||
for (auto fs : m_kernel_binaries_with_dsyms) {
|
||||
LLDB_LOGF(log, "%s", fs.GetPath().c_str());
|
||||
}
|
||||
LLDB_LOGF(log, "\nkernels without dSYMS");
|
||||
LLDB_LOGF(log, "\nkernel binaries without dSYMS");
|
||||
for (auto fs : m_kernel_binaries_without_dsyms) {
|
||||
LLDB_LOGF(log, "%s", fs.GetPath().c_str());
|
||||
}
|
||||
LLDB_LOGF(log, "\nkernel dSYMS with no binaries");
|
||||
for (auto fs : m_kernel_dsyms_no_binaries) {
|
||||
LLDB_LOGF(log, "%s", fs.GetPath().c_str());
|
||||
}
|
||||
LLDB_LOGF(log, "\nkernels .dSYM.yaa's");
|
||||
for (auto fs : m_kernel_dsyms_yaas) {
|
||||
LLDB_LOGF(log, "%s", fs.GetPath().c_str());
|
||||
}
|
||||
LLDB_LOGF(log, "\n");
|
||||
}
|
||||
}
|
||||
|
@ -497,56 +500,79 @@ PlatformDarwinKernel::GetKernelsAndKextsInDirectoryHelper(
|
|||
file_spec.GetPath().c_str());
|
||||
|
||||
PlatformDarwinKernel *thisp = (PlatformDarwinKernel *)baton;
|
||||
|
||||
llvm::StringRef filename = file_spec.GetFilename().GetStringRef();
|
||||
bool is_kernel_filename =
|
||||
filename.startswith("kernel") || filename.startswith("mach");
|
||||
bool is_dsym_yaa = filename.endswith(".dSYM.yaa");
|
||||
|
||||
if (ft == llvm::sys::fs::file_type::regular_file ||
|
||||
ft == llvm::sys::fs::file_type::symlink_file) {
|
||||
ConstString filename = file_spec.GetFilename();
|
||||
if ((strncmp(filename.GetCString(), "kernel", 6) == 0 ||
|
||||
strncmp(filename.GetCString(), "mach", 4) == 0) &&
|
||||
file_spec_extension != g_dsym_suffix) {
|
||||
if (KernelHasdSYMSibling(file_spec))
|
||||
{
|
||||
LLDB_LOGF(log,
|
||||
"PlatformDarwinKernel registering kernel binary '%s' with "
|
||||
"dSYM sibling",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
|
||||
if (is_kernel_filename) {
|
||||
if (file_spec_extension != g_dsym_suffix && !is_dsym_yaa) {
|
||||
if (KernelHasdSYMSibling(file_spec)) {
|
||||
LLDB_LOGF(log,
|
||||
"PlatformDarwinKernel registering kernel binary '%s' with "
|
||||
"dSYM sibling",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_binaries_with_dsyms.push_back(file_spec);
|
||||
} else {
|
||||
LLDB_LOGF(
|
||||
log,
|
||||
"PlatformDarwinKernel registering kernel binary '%s', no dSYM",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLDB_LOGF(
|
||||
log, "PlatformDarwinKernel registering kernel binary '%s', no dSYM",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_binaries_without_dsyms.push_back(file_spec);
|
||||
if (is_dsym_yaa) {
|
||||
LLDB_LOGF(log, "PlatformDarwinKernel registering kernel .dSYM.yaa '%s'",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_dsyms_yaas.push_back(file_spec);
|
||||
}
|
||||
return FileSystem::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
} else if (ft == llvm::sys::fs::file_type::directory_file &&
|
||||
file_spec_extension == g_kext_suffix) {
|
||||
AddKextToMap(thisp, file_spec);
|
||||
// Look to see if there is a PlugIns subdir with more kexts
|
||||
FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns");
|
||||
std::string search_here_too;
|
||||
if (FileSystem::Instance().IsDirectory(contents_plugins)) {
|
||||
search_here_too = contents_plugins.GetPath();
|
||||
} else {
|
||||
FileSpec plugins(file_spec.GetPath() + "/PlugIns");
|
||||
if (FileSystem::Instance().IsDirectory(plugins)) {
|
||||
search_here_too = plugins.GetPath();
|
||||
} else {
|
||||
if (ft == llvm::sys::fs::file_type::directory_file) {
|
||||
if (file_spec_extension == g_kext_suffix) {
|
||||
AddKextToMap(thisp, file_spec);
|
||||
// Look to see if there is a PlugIns subdir with more kexts
|
||||
FileSpec contents_plugins(file_spec.GetPath() + "/Contents/PlugIns");
|
||||
std::string search_here_too;
|
||||
if (FileSystem::Instance().IsDirectory(contents_plugins)) {
|
||||
search_here_too = contents_plugins.GetPath();
|
||||
} else {
|
||||
FileSpec plugins(file_spec.GetPath() + "/PlugIns");
|
||||
if (FileSystem::Instance().IsDirectory(plugins)) {
|
||||
search_here_too = plugins.GetPath();
|
||||
}
|
||||
}
|
||||
|
||||
if (!search_here_too.empty()) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
FileSystem::Instance().EnumerateDirectory(
|
||||
search_here_too.c_str(), find_directories, find_files, find_other,
|
||||
recurse ? GetKernelsAndKextsInDirectoryWithRecursion
|
||||
: GetKernelsAndKextsInDirectoryNoRecursion,
|
||||
baton);
|
||||
}
|
||||
return FileSystem::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
// Do we have a kernel dSYM with no kernel binary?
|
||||
if (is_kernel_filename && file_spec_extension == g_dsym_suffix) {
|
||||
if (KerneldSYMHasNoSiblingBinary(file_spec)) {
|
||||
LLDB_LOGF(log,
|
||||
"PlatformDarwinKernel registering kernel dSYM '%s' with "
|
||||
"no binary sibling",
|
||||
file_spec.GetPath().c_str());
|
||||
thisp->m_kernel_dsyms_no_binaries.push_back(file_spec);
|
||||
return FileSystem::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!search_here_too.empty()) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
FileSystem::Instance().EnumerateDirectory(
|
||||
search_here_too.c_str(), find_directories, find_files, find_other,
|
||||
recurse ? GetKernelsAndKextsInDirectoryWithRecursion
|
||||
: GetKernelsAndKextsInDirectoryNoRecursion,
|
||||
baton);
|
||||
}
|
||||
return FileSystem::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
|
||||
// Don't recurse into dSYM/kext/bundle directories
|
||||
if (recurse && file_spec_extension != g_dsym_suffix &&
|
||||
file_spec_extension != g_kext_suffix &&
|
||||
|
@ -642,6 +668,63 @@ bool PlatformDarwinKernel::KernelHasdSYMSibling(const FileSpec &kernel_binary) {
|
|||
return FileSystem::Instance().IsDirectory(kernel_dsym);
|
||||
}
|
||||
|
||||
// Given a FileSpec of /dir/dir/mach.development.t7004.dSYM
|
||||
// Return true if only the dSYM exists, no binary next to it.
|
||||
// /dir/dir/mach.development.t7004.dSYM
|
||||
// but no
|
||||
// /dir/dir/mach.development.t7004
|
||||
bool PlatformDarwinKernel::KerneldSYMHasNoSiblingBinary(
|
||||
const FileSpec &kernel_dsym) {
|
||||
static ConstString g_dsym_suffix = ConstString(".dSYM");
|
||||
std::string possible_path = kernel_dsym.GetPath();
|
||||
if (kernel_dsym.GetFileNameExtension() != g_dsym_suffix)
|
||||
return false;
|
||||
|
||||
FileSpec binary_filespec = kernel_dsym;
|
||||
// Chop off the '.dSYM' extension on the filename
|
||||
binary_filespec.GetFilename() =
|
||||
binary_filespec.GetFileNameStrippingExtension();
|
||||
|
||||
// Is there a binary next to this this? Then return false.
|
||||
if (FileSystem::Instance().Exists(binary_filespec))
|
||||
return false;
|
||||
|
||||
// If we have at least one binary in the DWARF subdir, then
|
||||
// this is a properly formed dSYM and it has no binary next
|
||||
// to it.
|
||||
if (GetDWARFBinaryInDSYMBundle(kernel_dsym).size() > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: This method returns a vector of FileSpec's because a
|
||||
// dSYM bundle may contain multiple DWARF binaries, but it
|
||||
// only implements returning the base name binary for now;
|
||||
// it should iterate over every binary in the DWARF subdir
|
||||
// and return them all.
|
||||
std::vector<FileSpec>
|
||||
PlatformDarwinKernel::GetDWARFBinaryInDSYMBundle(FileSpec dsym_bundle) {
|
||||
std::vector<FileSpec> results;
|
||||
static ConstString g_dsym_suffix = ConstString(".dSYM");
|
||||
if (dsym_bundle.GetFileNameExtension() != g_dsym_suffix) {
|
||||
return results;
|
||||
}
|
||||
// Drop the '.dSYM' from the filename
|
||||
std::string filename =
|
||||
dsym_bundle.GetFileNameStrippingExtension().GetCString();
|
||||
std::string dirname = dsym_bundle.GetDirectory().GetCString();
|
||||
|
||||
std::string binary_filepath = dsym_bundle.GetPath();
|
||||
binary_filepath += "/Contents/Resources/DWARF/";
|
||||
binary_filepath += filename;
|
||||
|
||||
FileSpec binary_fspec(binary_filepath);
|
||||
if (FileSystem::Instance().Exists(binary_fspec))
|
||||
results.push_back(binary_fspec);
|
||||
return results;
|
||||
}
|
||||
|
||||
Status PlatformDarwinKernel::GetSharedModule(
|
||||
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
|
||||
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
|
||||
|
@ -653,111 +736,176 @@ Status PlatformDarwinKernel::GetSharedModule(
|
|||
// Treat the file's path as a kext bundle ID (e.g.
|
||||
// "com.apple.driver.AppleIRController") and search our kext index.
|
||||
std::string kext_bundle_id = platform_file.GetPath();
|
||||
if (!kext_bundle_id.empty()) {
|
||||
ConstString kext_bundle_cs(kext_bundle_id.c_str());
|
||||
|
||||
// First look through the kext bundles that had a dsym next to them
|
||||
if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle_cs) > 0) {
|
||||
for (BundleIDToKextIterator it =
|
||||
m_name_to_kext_path_map_with_dsyms.begin();
|
||||
it != m_name_to_kext_path_map_with_dsyms.end(); ++it) {
|
||||
if (it->first == kext_bundle_cs) {
|
||||
error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
|
||||
module_spec.GetArchitecture(),
|
||||
module_sp);
|
||||
if (module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!kext_bundle_id.empty() && module_spec.GetUUID().IsValid()) {
|
||||
if (kext_bundle_id == "mach_kernel") {
|
||||
return GetSharedModuleKernel(module_spec, process, module_sp,
|
||||
module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
} else {
|
||||
return GetSharedModuleKext(module_spec, process, module_sp,
|
||||
module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Give the generic methods, including possibly calling into DebugSymbols
|
||||
// framework on macOS systems, a chance.
|
||||
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
|
||||
return PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success() && module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, look through the kext binarys without dSYMs
|
||||
if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle_cs) > 0) {
|
||||
for (BundleIDToKextIterator it =
|
||||
m_name_to_kext_path_map_without_dsyms.begin();
|
||||
it != m_name_to_kext_path_map_without_dsyms.end(); ++it) {
|
||||
if (it->first == kext_bundle_cs) {
|
||||
error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
|
||||
module_spec.GetArchitecture(),
|
||||
module_sp);
|
||||
if (module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
Status PlatformDarwinKernel::GetSharedModuleKext(
|
||||
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
|
||||
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) {
|
||||
Status error;
|
||||
module_sp.reset();
|
||||
const FileSpec &platform_file = module_spec.GetFileSpec();
|
||||
|
||||
// Treat the file's path as a kext bundle ID (e.g.
|
||||
// "com.apple.driver.AppleIRController") and search our kext index.
|
||||
ConstString kext_bundle(platform_file.GetPath().c_str());
|
||||
// First look through the kext bundles that had a dsym next to them
|
||||
if (m_name_to_kext_path_map_with_dsyms.count(kext_bundle) > 0) {
|
||||
for (BundleIDToKextIterator it = m_name_to_kext_path_map_with_dsyms.begin();
|
||||
it != m_name_to_kext_path_map_with_dsyms.end(); ++it) {
|
||||
if (it->first == kext_bundle) {
|
||||
error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
|
||||
module_spec.GetArchitecture(),
|
||||
module_sp);
|
||||
if (module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kext_bundle_id == "mach_kernel" && module_spec.GetUUID().IsValid()) {
|
||||
// First try all kernel binaries that have a dSYM next to them
|
||||
for (auto possible_kernel : m_kernel_binaries_with_dsyms) {
|
||||
if (FileSystem::Instance().Exists(possible_kernel)) {
|
||||
ModuleSpec kern_spec(possible_kernel);
|
||||
kern_spec.GetUUID() = module_spec.GetUUID();
|
||||
ModuleSP module_sp(new Module(kern_spec));
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->MatchesModuleSpec(kern_spec)) {
|
||||
// module_sp is an actual kernel binary we want to add.
|
||||
if (process) {
|
||||
process->GetTarget().GetImages().AppendIfNeeded(module_sp);
|
||||
error.Clear();
|
||||
return error;
|
||||
} else {
|
||||
error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
|
||||
NULL, NULL);
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->GetObjectFile()->GetType() !=
|
||||
ObjectFile::Type::eTypeCoreFile) {
|
||||
return error;
|
||||
}
|
||||
module_sp.reset();
|
||||
}
|
||||
// Give the generic methods, including possibly calling into DebugSymbols
|
||||
// framework on macOS systems, a chance.
|
||||
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success() && module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// Lastly, look through the kext binarys without dSYMs
|
||||
if (m_name_to_kext_path_map_without_dsyms.count(kext_bundle) > 0) {
|
||||
for (BundleIDToKextIterator it =
|
||||
m_name_to_kext_path_map_without_dsyms.begin();
|
||||
it != m_name_to_kext_path_map_without_dsyms.end(); ++it) {
|
||||
if (it->first == kext_bundle) {
|
||||
error = ExamineKextForMatchingUUID(it->second, module_spec.GetUUID(),
|
||||
module_spec.GetArchitecture(),
|
||||
module_sp);
|
||||
if (module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// Give the generic methods, including possibly calling into DebugSymbols
|
||||
// framework on macOS systems, a chance.
|
||||
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success() && module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
Status PlatformDarwinKernel::GetSharedModuleKernel(
|
||||
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
|
||||
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) {
|
||||
Status error;
|
||||
module_sp.reset();
|
||||
|
||||
// Next try all kernel binaries that don't have a dSYM
|
||||
for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
|
||||
if (FileSystem::Instance().Exists(possible_kernel)) {
|
||||
ModuleSpec kern_spec(possible_kernel);
|
||||
kern_spec.GetUUID() = module_spec.GetUUID();
|
||||
ModuleSP module_sp(new Module(kern_spec));
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->MatchesModuleSpec(kern_spec)) {
|
||||
// module_sp is an actual kernel binary we want to add.
|
||||
if (process) {
|
||||
process->GetTarget().GetImages().AppendIfNeeded(module_sp);
|
||||
error.Clear();
|
||||
// First try all kernel binaries that have a dSYM next to them
|
||||
for (auto possible_kernel : m_kernel_binaries_with_dsyms) {
|
||||
if (FileSystem::Instance().Exists(possible_kernel)) {
|
||||
ModuleSpec kern_spec(possible_kernel);
|
||||
kern_spec.GetUUID() = module_spec.GetUUID();
|
||||
module_sp.reset(new Module(kern_spec));
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->MatchesModuleSpec(kern_spec)) {
|
||||
// module_sp is an actual kernel binary we want to add.
|
||||
if (process) {
|
||||
process->GetTarget().GetImages().AppendIfNeeded(module_sp);
|
||||
error.Clear();
|
||||
return error;
|
||||
} else {
|
||||
error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->GetObjectFile()->GetType() !=
|
||||
ObjectFile::Type::eTypeCoreFile) {
|
||||
return error;
|
||||
} else {
|
||||
error = ModuleList::GetSharedModule(kern_spec, module_sp, NULL,
|
||||
NULL, NULL);
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->GetObjectFile()->GetType() !=
|
||||
ObjectFile::Type::eTypeCoreFile) {
|
||||
return error;
|
||||
}
|
||||
module_sp.reset();
|
||||
}
|
||||
module_sp.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next try all dSYMs that have no kernel binary next to them (load
|
||||
// the kernel DWARF stub as the main binary)
|
||||
for (auto possible_kernel_dsym : m_kernel_dsyms_no_binaries) {
|
||||
std::vector<FileSpec> objfile_names =
|
||||
GetDWARFBinaryInDSYMBundle(possible_kernel_dsym);
|
||||
for (FileSpec objfile : objfile_names) {
|
||||
ModuleSpec kern_spec(objfile);
|
||||
kern_spec.GetUUID() = module_spec.GetUUID();
|
||||
kern_spec.GetSymbolFileSpec() = possible_kernel_dsym;
|
||||
|
||||
module_sp.reset(new Module(kern_spec));
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->MatchesModuleSpec(kern_spec)) {
|
||||
// module_sp is an actual kernel binary we want to add.
|
||||
if (process) {
|
||||
process->GetTarget().GetImages().AppendIfNeeded(module_sp);
|
||||
error.Clear();
|
||||
return error;
|
||||
} else {
|
||||
error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->GetObjectFile()->GetType() !=
|
||||
ObjectFile::Type::eTypeCoreFile) {
|
||||
return error;
|
||||
}
|
||||
module_sp.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Give the generic methods, including possibly calling into DebugSymbols
|
||||
// framework on macOS systems, a chance.
|
||||
error = PlatformDarwin::GetSharedModule(module_spec, process, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success() && module_sp.get()) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// Lastly, try all kernel binaries that don't have a dSYM
|
||||
for (auto possible_kernel : m_kernel_binaries_without_dsyms) {
|
||||
if (FileSystem::Instance().Exists(possible_kernel)) {
|
||||
ModuleSpec kern_spec(possible_kernel);
|
||||
kern_spec.GetUUID() = module_spec.GetUUID();
|
||||
module_sp.reset(new Module(kern_spec));
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->MatchesModuleSpec(kern_spec)) {
|
||||
// module_sp is an actual kernel binary we want to add.
|
||||
if (process) {
|
||||
process->GetTarget().GetImages().AppendIfNeeded(module_sp);
|
||||
error.Clear();
|
||||
return error;
|
||||
} else {
|
||||
error = ModuleList::GetSharedModule(kern_spec, module_sp, nullptr,
|
||||
nullptr, nullptr);
|
||||
if (module_sp && module_sp->GetObjectFile() &&
|
||||
module_sp->GetObjectFile()->GetType() !=
|
||||
ObjectFile::Type::eTypeCoreFile) {
|
||||
return error;
|
||||
}
|
||||
module_sp.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,30 @@ protected:
|
|||
|
||||
// Returns true if there is a .dSYM bundle next to the kernel
|
||||
static bool
|
||||
KernelHasdSYMSibling(const lldb_private::FileSpec &kext_bundle_filepath);
|
||||
KernelHasdSYMSibling(const lldb_private::FileSpec &kernel_filepath);
|
||||
|
||||
// Returns true if there is a .dSYM bundle with NO kernel binary next to it
|
||||
static bool KerneldSYMHasNoSiblingBinary(
|
||||
const lldb_private::FileSpec &kernel_dsym_filepath);
|
||||
|
||||
// Given a dsym_bundle argument ('.../foo.dSYM'), return a FileSpec
|
||||
// with the binary inside it ('.../foo.dSYM/Contents/Resources/DWARF/foo').
|
||||
// A dSYM bundle may have multiple DWARF binaries in them, so a vector
|
||||
// of matches is returned.
|
||||
static std::vector<lldb_private::FileSpec>
|
||||
GetDWARFBinaryInDSYMBundle(lldb_private::FileSpec dsym_bundle);
|
||||
|
||||
lldb_private::Status
|
||||
GetSharedModuleKext(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
|
||||
|
||||
lldb_private::Status GetSharedModuleKernel(
|
||||
const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
|
||||
|
||||
lldb_private::Status
|
||||
ExamineKextForMatchingUUID(const lldb_private::FileSpec &kext_bundle_path,
|
||||
|
@ -170,6 +193,13 @@ public:
|
|||
// on local
|
||||
// filesystem, with
|
||||
// dSYMs next to them
|
||||
KernelBinaryCollection m_kernel_dsyms_no_binaries; // list of kernel
|
||||
// dsyms with no
|
||||
// binaries next to
|
||||
// them
|
||||
KernelBinaryCollection m_kernel_dsyms_yaas; // list of kernel
|
||||
// .dSYM.yaa files
|
||||
|
||||
lldb_private::LazyBool m_ios_debug_session;
|
||||
|
||||
PlatformDarwinKernel(const PlatformDarwinKernel &) = delete;
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
include "../../../../include/lldb/Core/PropertiesBase.td"
|
||||
|
||||
let Definition = "platformdarwinkernel" in {
|
||||
def SearchForKexts: Property<"search-locally-for-kexts", "Boolean">,
|
||||
Global,
|
||||
DefaultTrue,
|
||||
Desc<"Automatically search for kexts on the local system when doing kernel debugging.">;
|
||||
def KextDirectories: Property<"kext-directories", "FileSpecList">,
|
||||
DefaultStringValue<"">,
|
||||
Desc<"Directories/KDKs to search for kexts in when starting a kernel debug session.">;
|
||||
|
|
Loading…
Reference in New Issue