mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 07:31:28 +00:00
[lldb] Convert LocateSymbolFile into a plugin (#71151)
This commit contains the initial scaffolding to convert the functionality currently implemented in LocateSymbolFile to a plugin architecture. The plugin approach allows us to easily add new ways to find symbols and fixes some issues with the current implementation. For instance, currently we (ab)use the host OS to include support for querying the DebugSymbols framework on macOS. The plugin approach retains all the benefits (including the ability to compile this out on other platforms) while maintaining a higher level of separation with the platform independent code. To limit the scope of this patch, I've only converted a single function: LocateExecutableObjectFile. Future commits will convert the remaining LocateSymbolFile functions and eventually remove LocateSymbolFile. To make reviewing easier, that will done as follow-ups.
This commit is contained in:
parent
eb166030a1
commit
c3a302d399
@ -345,6 +345,19 @@ public:
|
|||||||
static SymbolVendorCreateInstance
|
static SymbolVendorCreateInstance
|
||||||
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx);
|
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx);
|
||||||
|
|
||||||
|
// SymbolLocator
|
||||||
|
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
|
||||||
|
SymbolLocatorCreateInstance create_callback,
|
||||||
|
SymbolLocatorLocateExecutableObjectFile
|
||||||
|
locate_executable_object_file = nullptr);
|
||||||
|
|
||||||
|
static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback);
|
||||||
|
|
||||||
|
static SymbolLocatorCreateInstance
|
||||||
|
GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx);
|
||||||
|
|
||||||
|
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
|
||||||
|
|
||||||
// Trace
|
// Trace
|
||||||
static bool RegisterPlugin(
|
static bool RegisterPlugin(
|
||||||
llvm::StringRef name, llvm::StringRef description,
|
llvm::StringRef name, llvm::StringRef description,
|
||||||
|
@ -24,12 +24,6 @@ class UUID;
|
|||||||
|
|
||||||
class Symbols {
|
class Symbols {
|
||||||
public:
|
public:
|
||||||
// Locate the executable file given a module specification.
|
|
||||||
//
|
|
||||||
// Locating the file should happen only on the local computer or using the
|
|
||||||
// current computers global settings.
|
|
||||||
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
|
|
||||||
|
|
||||||
// Locate the symbol file given a module specification.
|
// Locate the symbol file given a module specification.
|
||||||
//
|
//
|
||||||
// Locating the file should happen only on the local computer or using the
|
// Locating the file should happen only on the local computer or using the
|
||||||
|
23
lldb/include/lldb/Symbol/SymbolLocator.h
Normal file
23
lldb/include/lldb/Symbol/SymbolLocator.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//===-- SymbolLocator.h -----------------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLDB_SYMBOL_SYMBOLLOCATOR_H
|
||||||
|
#define LLDB_SYMBOL_SYMBOLLOCATOR_H
|
||||||
|
|
||||||
|
#include "lldb/Core/PluginInterface.h"
|
||||||
|
|
||||||
|
namespace lldb_private {
|
||||||
|
|
||||||
|
class SymbolLocator : public PluginInterface {
|
||||||
|
public:
|
||||||
|
SymbolLocator() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
#endif // LLDB_SYMBOL_SYMBOLFILELOCATOR_H
|
@ -217,6 +217,7 @@ class SymbolContextScope;
|
|||||||
class SymbolContextSpecifier;
|
class SymbolContextSpecifier;
|
||||||
class SymbolFile;
|
class SymbolFile;
|
||||||
class SymbolFileType;
|
class SymbolFileType;
|
||||||
|
class SymbolLocator;
|
||||||
class SymbolVendor;
|
class SymbolVendor;
|
||||||
class Symtab;
|
class Symtab;
|
||||||
class SyntheticChildren;
|
class SyntheticChildren;
|
||||||
|
@ -89,6 +89,9 @@ typedef SymbolVendor *(*SymbolVendorCreateInstance)(
|
|||||||
const lldb::ModuleSP &module_sp,
|
const lldb::ModuleSP &module_sp,
|
||||||
lldb_private::Stream
|
lldb_private::Stream
|
||||||
*feedback_strm); // Module can be NULL for default system symbol vendor
|
*feedback_strm); // Module can be NULL for default system symbol vendor
|
||||||
|
typedef SymbolLocator *(*SymbolLocatorCreateInstance)();
|
||||||
|
typedef std::optional<ModuleSpec> (*SymbolLocatorLocateExecutableObjectFile)(
|
||||||
|
const ModuleSpec &module_spec);
|
||||||
typedef bool (*BreakpointHitCallback)(void *baton,
|
typedef bool (*BreakpointHitCallback)(void *baton,
|
||||||
StoppointCallbackContext *context,
|
StoppointCallbackContext *context,
|
||||||
lldb::user_id_t break_id,
|
lldb::user_id_t break_id,
|
||||||
|
@ -221,7 +221,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
|
|||||||
module_spec.GetSymbolFileSpec() =
|
module_spec.GetSymbolFileSpec() =
|
||||||
Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
|
Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
|
||||||
ModuleSpec objfile_module_spec =
|
ModuleSpec objfile_module_spec =
|
||||||
Symbols::LocateExecutableObjectFile(module_spec);
|
PluginManager::LocateExecutableObjectFile(module_spec);
|
||||||
module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
|
module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec();
|
||||||
if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
|
if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) &&
|
||||||
FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
|
FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "lldb/Core/ModuleList.h"
|
#include "lldb/Core/ModuleList.h"
|
||||||
#include "lldb/Core/Module.h"
|
#include "lldb/Core/Module.h"
|
||||||
#include "lldb/Core/ModuleSpec.h"
|
#include "lldb/Core/ModuleSpec.h"
|
||||||
|
#include "lldb/Core/PluginManager.h"
|
||||||
#include "lldb/Host/FileSystem.h"
|
#include "lldb/Host/FileSystem.h"
|
||||||
#include "lldb/Interpreter/OptionValueFileSpec.h"
|
#include "lldb/Interpreter/OptionValueFileSpec.h"
|
||||||
#include "lldb/Interpreter/OptionValueFileSpecList.h"
|
#include "lldb/Interpreter/OptionValueFileSpecList.h"
|
||||||
@ -906,7 +907,7 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp,
|
|||||||
// Fixup the incoming path in case the path points to a valid file, yet the
|
// Fixup the incoming path in case the path points to a valid file, yet the
|
||||||
// arch or UUID (if one was passed in) don't match.
|
// arch or UUID (if one was passed in) don't match.
|
||||||
ModuleSpec located_binary_modulespec =
|
ModuleSpec located_binary_modulespec =
|
||||||
Symbols::LocateExecutableObjectFile(module_spec);
|
PluginManager::LocateExecutableObjectFile(module_spec);
|
||||||
|
|
||||||
// Don't look for the file if it appears to be the same one we already
|
// Don't look for the file if it appears to be the same one we already
|
||||||
// checked for above...
|
// checked for above...
|
||||||
|
@ -1081,6 +1081,59 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
|
|||||||
return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
|
return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark SymbolLocator
|
||||||
|
|
||||||
|
struct SymbolLocatorInstance
|
||||||
|
: public PluginInstance<SymbolLocatorCreateInstance> {
|
||||||
|
SymbolLocatorInstance(
|
||||||
|
llvm::StringRef name, llvm::StringRef description,
|
||||||
|
CallbackType create_callback,
|
||||||
|
SymbolLocatorLocateExecutableObjectFile locate_executable_object_file)
|
||||||
|
: PluginInstance<SymbolLocatorCreateInstance>(name, description,
|
||||||
|
create_callback),
|
||||||
|
locate_executable_object_file(locate_executable_object_file) {}
|
||||||
|
|
||||||
|
SymbolLocatorLocateExecutableObjectFile locate_executable_object_file;
|
||||||
|
};
|
||||||
|
typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances;
|
||||||
|
|
||||||
|
static SymbolLocatorInstances &GetSymbolLocatorInstances() {
|
||||||
|
static SymbolLocatorInstances g_instances;
|
||||||
|
return g_instances;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginManager::RegisterPlugin(
|
||||||
|
llvm::StringRef name, llvm::StringRef description,
|
||||||
|
SymbolLocatorCreateInstance create_callback,
|
||||||
|
SymbolLocatorLocateExecutableObjectFile locate_executable_object_file) {
|
||||||
|
return GetSymbolLocatorInstances().RegisterPlugin(
|
||||||
|
name, description, create_callback, locate_executable_object_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PluginManager::UnregisterPlugin(
|
||||||
|
SymbolLocatorCreateInstance create_callback) {
|
||||||
|
return GetSymbolLocatorInstances().UnregisterPlugin(create_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolLocatorCreateInstance
|
||||||
|
PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) {
|
||||||
|
return GetSymbolLocatorInstances().GetCallbackAtIndex(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModuleSpec
|
||||||
|
PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
|
||||||
|
auto &instances = GetSymbolLocatorInstances().GetInstances();
|
||||||
|
for (auto &instance : instances) {
|
||||||
|
if (instance.locate_executable_object_file) {
|
||||||
|
std::optional<ModuleSpec> result =
|
||||||
|
instance.locate_executable_object_file(module_spec);
|
||||||
|
if (result)
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Trace
|
#pragma mark Trace
|
||||||
|
|
||||||
struct TraceInstance
|
struct TraceInstance
|
||||||
|
@ -20,6 +20,7 @@ add_subdirectory(ScriptInterpreter)
|
|||||||
add_subdirectory(StructuredData)
|
add_subdirectory(StructuredData)
|
||||||
add_subdirectory(SymbolFile)
|
add_subdirectory(SymbolFile)
|
||||||
add_subdirectory(SystemRuntime)
|
add_subdirectory(SystemRuntime)
|
||||||
|
add_subdirectory(SymbolLocator)
|
||||||
add_subdirectory(SymbolVendor)
|
add_subdirectory(SymbolVendor)
|
||||||
add_subdirectory(Trace)
|
add_subdirectory(Trace)
|
||||||
add_subdirectory(TraceExporter)
|
add_subdirectory(TraceExporter)
|
||||||
|
@ -282,7 +282,7 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) {
|
|||||||
search_paths);
|
search_paths);
|
||||||
if (module_spec.GetSymbolFileSpec()) {
|
if (module_spec.GetSymbolFileSpec()) {
|
||||||
ModuleSpec executable_module_spec =
|
ModuleSpec executable_module_spec =
|
||||||
Symbols::LocateExecutableObjectFile(module_spec);
|
PluginManager::LocateExecutableObjectFile(module_spec);
|
||||||
if (FileSystem::Instance().Exists(
|
if (FileSystem::Instance().Exists(
|
||||||
executable_module_spec.GetFileSpec())) {
|
executable_module_spec.GetFileSpec())) {
|
||||||
module_spec.GetFileSpec() =
|
module_spec.GetFileSpec() =
|
||||||
|
4
lldb/source/Plugins/SymbolLocator/CMakeLists.txt
Normal file
4
lldb/source/Plugins/SymbolLocator/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
add_subdirectory(Default)
|
||||||
|
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
add_subdirectory(DebugSymbols)
|
||||||
|
endif()
|
@ -0,0 +1,8 @@
|
|||||||
|
add_lldb_library(lldbPluginSymbolLocatorDebugSymbols PLUGIN
|
||||||
|
SymbolLocatorDebugSymbols.cpp
|
||||||
|
|
||||||
|
LINK_LIBS
|
||||||
|
lldbCore
|
||||||
|
lldbHost
|
||||||
|
lldbSymbol
|
||||||
|
)
|
@ -0,0 +1,327 @@
|
|||||||
|
//===-- SymbolLocatorDebugSymbols.cpp -------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "SymbolLocatorDebugSymbols.h"
|
||||||
|
|
||||||
|
#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
|
||||||
|
#include "lldb/Core/Debugger.h"
|
||||||
|
#include "lldb/Core/Module.h"
|
||||||
|
#include "lldb/Core/ModuleList.h"
|
||||||
|
#include "lldb/Core/ModuleSpec.h"
|
||||||
|
#include "lldb/Core/PluginManager.h"
|
||||||
|
#include "lldb/Core/Progress.h"
|
||||||
|
#include "lldb/Core/Section.h"
|
||||||
|
#include "lldb/Host/FileSystem.h"
|
||||||
|
#include "lldb/Host/Host.h"
|
||||||
|
#include "lldb/Host/HostInfo.h"
|
||||||
|
#include "lldb/Symbol/LocateSymbolFile.h"
|
||||||
|
#include "lldb/Symbol/ObjectFile.h"
|
||||||
|
#include "lldb/Target/Target.h"
|
||||||
|
#include "lldb/Utility/ArchSpec.h"
|
||||||
|
#include "lldb/Utility/DataBuffer.h"
|
||||||
|
#include "lldb/Utility/DataExtractor.h"
|
||||||
|
#include "lldb/Utility/LLDBLog.h"
|
||||||
|
#include "lldb/Utility/Log.h"
|
||||||
|
#include "lldb/Utility/StreamString.h"
|
||||||
|
#include "lldb/Utility/Timer.h"
|
||||||
|
#include "lldb/Utility/UUID.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/SmallSet.h"
|
||||||
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "llvm/Support/ThreadPool.h"
|
||||||
|
|
||||||
|
#include "Host/macosx/cfcpp/CFCBundle.h"
|
||||||
|
#include "Host/macosx/cfcpp/CFCData.h"
|
||||||
|
#include "Host/macosx/cfcpp/CFCReleaser.h"
|
||||||
|
#include "Host/macosx/cfcpp/CFCString.h"
|
||||||
|
|
||||||
|
#include "mach/machine.h"
|
||||||
|
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <optional>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_private;
|
||||||
|
|
||||||
|
static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)(
|
||||||
|
CFUUIDRef uuid, CFURLRef exec_url) = nullptr;
|
||||||
|
static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) =
|
||||||
|
nullptr;
|
||||||
|
|
||||||
|
LLDB_PLUGIN_DEFINE(SymbolLocatorDebugSymbols)
|
||||||
|
|
||||||
|
SymbolLocatorDebugSymbols::SymbolLocatorDebugSymbols() : SymbolLocator() {}
|
||||||
|
|
||||||
|
void SymbolLocatorDebugSymbols::Initialize() {
|
||||||
|
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||||
|
GetPluginDescriptionStatic(), CreateInstance,
|
||||||
|
LocateExecutableObjectFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymbolLocatorDebugSymbols::Terminate() {
|
||||||
|
PluginManager::UnregisterPlugin(CreateInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::StringRef SymbolLocatorDebugSymbols::GetPluginDescriptionStatic() {
|
||||||
|
return "DebugSymbols symbol locator.";
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolLocator *SymbolLocatorDebugSymbols::CreateInstance() {
|
||||||
|
return new SymbolLocatorDebugSymbols();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile(
|
||||||
|
const ModuleSpec &module_spec) {
|
||||||
|
Log *log = GetLog(LLDBLog::Host);
|
||||||
|
if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
|
||||||
|
LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
ModuleSpec return_module_spec;
|
||||||
|
return_module_spec = module_spec;
|
||||||
|
return_module_spec.GetFileSpec().Clear();
|
||||||
|
return_module_spec.GetSymbolFileSpec().Clear();
|
||||||
|
|
||||||
|
const UUID *uuid = module_spec.GetUUIDPtr();
|
||||||
|
const ArchSpec *arch = module_spec.GetArchitecturePtr();
|
||||||
|
|
||||||
|
int items_found = 0;
|
||||||
|
|
||||||
|
if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
|
||||||
|
g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
|
||||||
|
void *handle = dlopen(
|
||||||
|
"/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols",
|
||||||
|
RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (handle) {
|
||||||
|
g_dlsym_DBGCopyFullDSYMURLForUUID =
|
||||||
|
(CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle,
|
||||||
|
"DBGCopyFullDSYMURLForUUID");
|
||||||
|
g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym(
|
||||||
|
handle, "DBGCopyDSYMPropertyLists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr ||
|
||||||
|
g_dlsym_DBGCopyDSYMPropertyLists == nullptr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uuid && uuid->IsValid()) {
|
||||||
|
// Try and locate the dSYM file using DebugSymbols first
|
||||||
|
llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
|
||||||
|
if (module_uuid.size() == 16) {
|
||||||
|
CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
|
||||||
|
NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
|
||||||
|
module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
|
||||||
|
module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
|
||||||
|
module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
|
||||||
|
|
||||||
|
if (module_uuid_ref.get()) {
|
||||||
|
CFCReleaser<CFURLRef> exec_url;
|
||||||
|
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
|
||||||
|
if (exec_fspec) {
|
||||||
|
char exec_cf_path[PATH_MAX];
|
||||||
|
if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
|
||||||
|
exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
|
||||||
|
NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
|
||||||
|
FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID(
|
||||||
|
module_uuid_ref.get(), exec_url.get()));
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
if (dsym_url.get()) {
|
||||||
|
if (::CFURLGetFileSystemRepresentation(
|
||||||
|
dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"DebugSymbols framework returned dSYM path of %s for "
|
||||||
|
"UUID %s -- looking for the dSYM",
|
||||||
|
path, uuid->GetAsString().c_str());
|
||||||
|
FileSpec dsym_filespec(path);
|
||||||
|
if (path[0] == '~')
|
||||||
|
FileSystem::Instance().Resolve(dsym_filespec);
|
||||||
|
|
||||||
|
if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
|
||||||
|
dsym_filespec =
|
||||||
|
Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
|
||||||
|
++items_found;
|
||||||
|
} else {
|
||||||
|
++items_found;
|
||||||
|
}
|
||||||
|
return_module_spec.GetSymbolFileSpec() = dsym_filespec;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
if (log) {
|
||||||
|
if (::CFURLGetFileSystemRepresentation(
|
||||||
|
dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"DebugSymbols framework returned dSYM path of %s for "
|
||||||
|
"UUID %s -- looking for an exec file",
|
||||||
|
path, uuid->GetAsString().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFCReleaser<CFDictionaryRef> dict(
|
||||||
|
g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get()));
|
||||||
|
CFDictionaryRef uuid_dict = NULL;
|
||||||
|
if (dict.get()) {
|
||||||
|
CFCString uuid_cfstr(uuid->GetAsString().c_str());
|
||||||
|
uuid_dict = static_cast<CFDictionaryRef>(
|
||||||
|
::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if we have the file on the local filesystem.
|
||||||
|
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
|
||||||
|
ModuleSpec exe_spec;
|
||||||
|
exe_spec.GetFileSpec() = module_spec.GetFileSpec();
|
||||||
|
exe_spec.GetUUID() = module_spec.GetUUID();
|
||||||
|
ModuleSP module_sp;
|
||||||
|
module_sp.reset(new Module(exe_spec));
|
||||||
|
if (module_sp && module_sp->GetObjectFile() &&
|
||||||
|
module_sp->MatchesModuleSpec(exe_spec)) {
|
||||||
|
success = true;
|
||||||
|
return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
|
||||||
|
LLDB_LOGF(log, "using original binary filepath %s for UUID %s",
|
||||||
|
module_spec.GetFileSpec().GetPath().c_str(),
|
||||||
|
uuid->GetAsString().c_str());
|
||||||
|
++items_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the requested image is in our shared cache.
|
||||||
|
if (!success) {
|
||||||
|
SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
|
||||||
|
module_spec.GetFileSpec().GetPath());
|
||||||
|
|
||||||
|
// If we found it and it has the correct UUID, let's proceed with
|
||||||
|
// creating a module from the memory contents.
|
||||||
|
if (image_info.uuid && (!module_spec.GetUUID() ||
|
||||||
|
module_spec.GetUUID() == image_info.uuid)) {
|
||||||
|
success = true;
|
||||||
|
return_module_spec.GetFileSpec() = module_spec.GetFileSpec();
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"using binary from shared cache for filepath %s for "
|
||||||
|
"UUID %s",
|
||||||
|
module_spec.GetFileSpec().GetPath().c_str(),
|
||||||
|
uuid->GetAsString().c_str());
|
||||||
|
++items_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the DBGSymbolRichExecutable filepath if present
|
||||||
|
if (!success && uuid_dict) {
|
||||||
|
CFStringRef exec_cf_path =
|
||||||
|
static_cast<CFStringRef>(::CFDictionaryGetValue(
|
||||||
|
uuid_dict, CFSTR("DBGSymbolRichExecutable")));
|
||||||
|
if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
|
||||||
|
exec_cf_path, path, sizeof(path))) {
|
||||||
|
LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s",
|
||||||
|
path, uuid->GetAsString().c_str());
|
||||||
|
++items_found;
|
||||||
|
FileSpec exec_filespec(path);
|
||||||
|
if (path[0] == '~')
|
||||||
|
FileSystem::Instance().Resolve(exec_filespec);
|
||||||
|
if (FileSystem::Instance().Exists(exec_filespec)) {
|
||||||
|
success = true;
|
||||||
|
return_module_spec.GetFileSpec() = exec_filespec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look next to the dSYM for the binary file.
|
||||||
|
if (!success) {
|
||||||
|
if (::CFURLGetFileSystemRepresentation(
|
||||||
|
dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
|
||||||
|
char *dsym_extension_pos = ::strstr(path, ".dSYM");
|
||||||
|
if (dsym_extension_pos) {
|
||||||
|
*dsym_extension_pos = '\0';
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"Looking for executable binary next to dSYM "
|
||||||
|
"bundle with name with name %s",
|
||||||
|
path);
|
||||||
|
FileSpec file_spec(path);
|
||||||
|
FileSystem::Instance().Resolve(file_spec);
|
||||||
|
ModuleSpecList module_specs;
|
||||||
|
ModuleSpec matched_module_spec;
|
||||||
|
using namespace llvm::sys::fs;
|
||||||
|
switch (get_file_type(file_spec.GetPath())) {
|
||||||
|
|
||||||
|
case file_type::directory_file: // Bundle directory?
|
||||||
|
{
|
||||||
|
CFCBundle bundle(path);
|
||||||
|
CFCReleaser<CFURLRef> bundle_exe_url(
|
||||||
|
bundle.CopyExecutableURL());
|
||||||
|
if (bundle_exe_url.get()) {
|
||||||
|
if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
|
||||||
|
true, (UInt8 *)path,
|
||||||
|
sizeof(path) - 1)) {
|
||||||
|
FileSpec bundle_exe_file_spec(path);
|
||||||
|
FileSystem::Instance().Resolve(bundle_exe_file_spec);
|
||||||
|
if (ObjectFile::GetModuleSpecifications(
|
||||||
|
bundle_exe_file_spec, 0, 0, module_specs) &&
|
||||||
|
module_specs.FindMatchingModuleSpec(
|
||||||
|
module_spec, matched_module_spec))
|
||||||
|
|
||||||
|
{
|
||||||
|
++items_found;
|
||||||
|
return_module_spec.GetFileSpec() = bundle_exe_file_spec;
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"Executable binary %s next to dSYM is "
|
||||||
|
"compatible; using",
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case file_type::fifo_file: // Forget pipes
|
||||||
|
case file_type::socket_file: // We can't process socket files
|
||||||
|
case file_type::file_not_found: // File doesn't exist...
|
||||||
|
case file_type::status_error:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case file_type::type_unknown:
|
||||||
|
case file_type::regular_file:
|
||||||
|
case file_type::symlink_file:
|
||||||
|
case file_type::block_file:
|
||||||
|
case file_type::character_file:
|
||||||
|
if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
|
||||||
|
module_specs) &&
|
||||||
|
module_specs.FindMatchingModuleSpec(module_spec,
|
||||||
|
matched_module_spec))
|
||||||
|
|
||||||
|
{
|
||||||
|
++items_found;
|
||||||
|
return_module_spec.GetFileSpec() = file_spec;
|
||||||
|
LLDB_LOGF(log,
|
||||||
|
"Executable binary %s next to dSYM is "
|
||||||
|
"compatible; using",
|
||||||
|
path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items_found)
|
||||||
|
return return_module_spec;
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
//===-- SymbolLocatorDebugSymbols.h -----------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
|
||||||
|
#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
|
||||||
|
|
||||||
|
#include "lldb/Symbol/SymbolLocator.h"
|
||||||
|
#include "lldb/lldb-private.h"
|
||||||
|
|
||||||
|
namespace lldb_private {
|
||||||
|
|
||||||
|
class SymbolLocatorDebugSymbols : public SymbolLocator {
|
||||||
|
public:
|
||||||
|
SymbolLocatorDebugSymbols();
|
||||||
|
|
||||||
|
static void Initialize();
|
||||||
|
static void Terminate();
|
||||||
|
|
||||||
|
static llvm::StringRef GetPluginNameStatic() { return "DebugSymbols"; }
|
||||||
|
static llvm::StringRef GetPluginDescriptionStatic();
|
||||||
|
|
||||||
|
static lldb_private::SymbolLocator *CreateInstance();
|
||||||
|
|
||||||
|
/// PluginInterface protocol.
|
||||||
|
/// \{
|
||||||
|
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
// Locate the executable file given a module specification.
|
||||||
|
//
|
||||||
|
// Locating the file should happen only on the local computer or using the
|
||||||
|
// current computers global settings.
|
||||||
|
static std::optional<ModuleSpec>
|
||||||
|
LocateExecutableObjectFile(const ModuleSpec &module_spec);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H
|
8
lldb/source/Plugins/SymbolLocator/Default/CMakeLists.txt
Normal file
8
lldb/source/Plugins/SymbolLocator/Default/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
add_lldb_library(lldbPluginSymbolLocatorDefault PLUGIN
|
||||||
|
SymbolLocatorDefault.cpp
|
||||||
|
|
||||||
|
LINK_LIBS
|
||||||
|
lldbCore
|
||||||
|
lldbHost
|
||||||
|
lldbSymbol
|
||||||
|
)
|
@ -0,0 +1,90 @@
|
|||||||
|
//===-- SymbolLocatorDefault.cpp ------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "SymbolLocatorDefault.h"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h"
|
||||||
|
#include "lldb/Core/Debugger.h"
|
||||||
|
#include "lldb/Core/Module.h"
|
||||||
|
#include "lldb/Core/ModuleList.h"
|
||||||
|
#include "lldb/Core/ModuleSpec.h"
|
||||||
|
#include "lldb/Core/PluginManager.h"
|
||||||
|
#include "lldb/Core/Progress.h"
|
||||||
|
#include "lldb/Core/Section.h"
|
||||||
|
#include "lldb/Host/FileSystem.h"
|
||||||
|
#include "lldb/Host/Host.h"
|
||||||
|
#include "lldb/Symbol/LocateSymbolFile.h"
|
||||||
|
#include "lldb/Symbol/ObjectFile.h"
|
||||||
|
#include "lldb/Target/Target.h"
|
||||||
|
#include "lldb/Utility/ArchSpec.h"
|
||||||
|
#include "lldb/Utility/DataBuffer.h"
|
||||||
|
#include "lldb/Utility/DataExtractor.h"
|
||||||
|
#include "lldb/Utility/LLDBLog.h"
|
||||||
|
#include "lldb/Utility/Log.h"
|
||||||
|
#include "lldb/Utility/StreamString.h"
|
||||||
|
#include "lldb/Utility/Timer.h"
|
||||||
|
#include "lldb/Utility/UUID.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/SmallSet.h"
|
||||||
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "llvm/Support/ThreadPool.h"
|
||||||
|
|
||||||
|
// From MacOSX system header "mach/machine.h"
|
||||||
|
typedef int cpu_type_t;
|
||||||
|
typedef int cpu_subtype_t;
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_private;
|
||||||
|
|
||||||
|
LLDB_PLUGIN_DEFINE(SymbolLocatorDefault)
|
||||||
|
|
||||||
|
SymbolLocatorDefault::SymbolLocatorDefault() : SymbolLocator() {}
|
||||||
|
|
||||||
|
void SymbolLocatorDefault::Initialize() {
|
||||||
|
PluginManager::RegisterPlugin(GetPluginNameStatic(),
|
||||||
|
GetPluginDescriptionStatic(), CreateInstance,
|
||||||
|
LocateExecutableObjectFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SymbolLocatorDefault::Terminate() {
|
||||||
|
PluginManager::UnregisterPlugin(CreateInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::StringRef SymbolLocatorDefault::GetPluginDescriptionStatic() {
|
||||||
|
return "Default symbol locator.";
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolLocator *SymbolLocatorDefault::CreateInstance() {
|
||||||
|
return new SymbolLocatorDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ModuleSpec> SymbolLocatorDefault::LocateExecutableObjectFile(
|
||||||
|
const ModuleSpec &module_spec) {
|
||||||
|
const FileSpec &exec_fspec = module_spec.GetFileSpec();
|
||||||
|
const ArchSpec *arch = module_spec.GetArchitecturePtr();
|
||||||
|
const UUID *uuid = module_spec.GetUUIDPtr();
|
||||||
|
LLDB_SCOPED_TIMERF(
|
||||||
|
"LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
|
||||||
|
exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>",
|
||||||
|
arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
|
||||||
|
|
||||||
|
ModuleSpecList module_specs;
|
||||||
|
ModuleSpec matched_module_spec;
|
||||||
|
if (exec_fspec &&
|
||||||
|
ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) &&
|
||||||
|
module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
|
||||||
|
ModuleSpec result;
|
||||||
|
result.GetFileSpec() = exec_fspec;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
//===-- SymbolLocatorDefault.h ----------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
|
||||||
|
#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
|
||||||
|
|
||||||
|
#include "lldb/Symbol/SymbolLocator.h"
|
||||||
|
#include "lldb/lldb-private.h"
|
||||||
|
|
||||||
|
namespace lldb_private {
|
||||||
|
|
||||||
|
class SymbolLocatorDefault : public SymbolLocator {
|
||||||
|
public:
|
||||||
|
SymbolLocatorDefault();
|
||||||
|
|
||||||
|
static void Initialize();
|
||||||
|
static void Terminate();
|
||||||
|
|
||||||
|
static llvm::StringRef GetPluginNameStatic() { return "Default"; }
|
||||||
|
static llvm::StringRef GetPluginDescriptionStatic();
|
||||||
|
|
||||||
|
static lldb_private::SymbolLocator *CreateInstance();
|
||||||
|
|
||||||
|
/// PluginInterface protocol.
|
||||||
|
/// \{
|
||||||
|
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
|
||||||
|
/// \}
|
||||||
|
|
||||||
|
// Locate the executable file given a module specification.
|
||||||
|
//
|
||||||
|
// Locating the file should happen only on the local computer or using the
|
||||||
|
// current computers global settings.
|
||||||
|
static std::optional<ModuleSpec>
|
||||||
|
LocateExecutableObjectFile(const ModuleSpec &module_spec);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H
|
@ -234,29 +234,6 @@ static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
|
|||||||
return dsym_module_spec.GetSymbolFileSpec();
|
return dsym_module_spec.GetSymbolFileSpec();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
|
|
||||||
ModuleSpec result;
|
|
||||||
const FileSpec &exec_fspec = module_spec.GetFileSpec();
|
|
||||||
const ArchSpec *arch = module_spec.GetArchitecturePtr();
|
|
||||||
const UUID *uuid = module_spec.GetUUIDPtr();
|
|
||||||
LLDB_SCOPED_TIMERF(
|
|
||||||
"LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
|
|
||||||
exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>",
|
|
||||||
arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
|
|
||||||
|
|
||||||
ModuleSpecList module_specs;
|
|
||||||
ModuleSpec matched_module_spec;
|
|
||||||
if (exec_fspec &&
|
|
||||||
ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) &&
|
|
||||||
module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
|
|
||||||
result.GetFileSpec() = exec_fspec;
|
|
||||||
} else {
|
|
||||||
LocateMacOSXFilesUsingDebugSymbols(module_spec, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep "symbols.enable-external-lookup" description in sync with this function.
|
// Keep "symbols.enable-external-lookup" description in sync with this function.
|
||||||
|
|
||||||
FileSpec
|
FileSpec
|
||||||
|
Loading…
Reference in New Issue
Block a user