[Lldb-commits] [lldb] r355032 - Move Host/Symbols.cpp to Symbols/LocateSymbolFile.cpp
Zachary Turner via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 27 13:42:10 PST 2019
Author: zturner
Date: Wed Feb 27 13:42:10 2019
New Revision: 355032
URL: http://llvm.org/viewvc/llvm-project?rev=355032&view=rev
Log:
Move Host/Symbols.cpp to Symbols/LocateSymbolFile.cpp
Given that we have a target named Symbols, one wonders why a
file named Symbols.cpp is not in this target. To be clear,
the functions exposed from this file are really focused on
*locating* a symbol file on a given host, which is where the
ambiguity comes in. However, it makes more sense conceptually
to be in the Symbols target. While some of the specific places
to search for symbol files might change depending on the Host,
this is not inherently true in the same way that, for example,
"accessing the file system" or "starting threads" is
fundamentally dependent on the Host.
PDBs, for example, recently became a reality on non-Windows platforms,
and it's theoretically possible that DSYMs could become a thing on non
MacOSX platforms (maybe in a remote debugging scenario). Other types of
symbol files, such as DWO, DWP, etc have never been tied to any Host
platform anyway.
After this patch, there is only one remaining dependency from
Host to Target.
Differential Revision: https://reviews.llvm.org/D58730
Added:
lldb/trunk/include/lldb/Symbol/LocateSymbolFile.h
lldb/trunk/source/Symbol/LocateSymbolFile.cpp
lldb/trunk/source/Symbol/LocateSymbolFileMacOSX.cpp
lldb/trunk/unittests/Symbol/LocateSymbolFileTest.cpp
Removed:
lldb/trunk/include/lldb/Host/Symbols.h
lldb/trunk/source/Host/common/Symbols.cpp
lldb/trunk/source/Host/macosx/Symbols.cpp
lldb/trunk/unittests/Host/SymbolsTest.cpp
Modified:
lldb/trunk/include/lldb/module.modulemap
lldb/trunk/source/Commands/CommandObjectTarget.cpp
lldb/trunk/source/Core/ModuleList.cpp
lldb/trunk/source/Host/CMakeLists.txt
lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
lldb/trunk/source/Symbol/CMakeLists.txt
lldb/trunk/unittests/Host/CMakeLists.txt
lldb/trunk/unittests/Symbol/CMakeLists.txt
Removed: lldb/trunk/include/lldb/Host/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Symbols.h?rev=355031&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/Symbols.h (original)
+++ lldb/trunk/include/lldb/Host/Symbols.h (removed)
@@ -1,61 +0,0 @@
-//===-- Symbols.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 liblldb_Symbols_h_
-#define liblldb_Symbols_h_
-
-#include <stdint.h>
-
-#include "lldb/Utility/FileSpec.h"
-
-namespace lldb_private {
-
-class ArchSpec;
-class ModuleSpec;
-class UUID;
-
-class Symbols {
-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.
- //
- // Locating the file should happen only on the local computer or using the
- // current computers global settings.
- //----------------------------------------------------------------------
- static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec);
-
- static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
- const lldb_private::UUID *uuid,
- const ArchSpec *arch);
-
- //----------------------------------------------------------------------
- // Locate the object and symbol file given a module specification.
- //
- // Locating the file can try to download the file from a corporate build
- // repository, or using any other means necessary to locate both the
- // unstripped object file and the debug symbols. The force_lookup argument
- // controls whether the external program is called unconditionally to find
- // the symbol file, or if the user's settings are checked to see if they've
- // enabled the external program before calling.
- //
- //----------------------------------------------------------------------
- static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
- bool force_lookup = true);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_Symbols_h_
Added: lldb/trunk/include/lldb/Symbol/LocateSymbolFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/LocateSymbolFile.h?rev=355032&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Symbol/LocateSymbolFile.h (added)
+++ lldb/trunk/include/lldb/Symbol/LocateSymbolFile.h Wed Feb 27 13:42:10 2019
@@ -0,0 +1,61 @@
+//===-- Symbols.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 liblldb_Symbols_h_
+#define liblldb_Symbols_h_
+
+#include <stdint.h>
+
+#include "lldb/Utility/FileSpec.h"
+
+namespace lldb_private {
+
+class ArchSpec;
+class ModuleSpec;
+class UUID;
+
+class Symbols {
+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.
+ //
+ // Locating the file should happen only on the local computer or using the
+ // current computers global settings.
+ //----------------------------------------------------------------------
+ static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec);
+
+ static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
+ const lldb_private::UUID *uuid,
+ const ArchSpec *arch);
+
+ //----------------------------------------------------------------------
+ // Locate the object and symbol file given a module specification.
+ //
+ // Locating the file can try to download the file from a corporate build
+ // repository, or using any other means necessary to locate both the
+ // unstripped object file and the debug symbols. The force_lookup argument
+ // controls whether the external program is called unconditionally to find
+ // the symbol file, or if the user's settings are checked to see if they've
+ // enabled the external program before calling.
+ //
+ //----------------------------------------------------------------------
+ static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ bool force_lookup = true);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symbols_h_
Modified: lldb/trunk/include/lldb/module.modulemap
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/module.modulemap?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/include/lldb/module.modulemap (original)
+++ lldb/trunk/include/lldb/module.modulemap Wed Feb 27 13:42:10 2019
@@ -48,7 +48,6 @@ module lldb_Host {
module SocketAddress { header "Host/SocketAddress.h" export * }
module Socket { header "Host/Socket.h" export * }
module StringConvert { textual header "Host/StringConvert.h" export * }
- module Symbols { header "Host/Symbols.h" export * }
module TaskPool { header "Host/TaskPool.h" export * }
module Terminal { header "Host/Terminal.h" export * }
module ThreadLauncher { header "Host/ThreadLauncher.h" export * }
Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Wed Feb 27 13:42:10 2019
@@ -17,7 +17,6 @@
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/OptionArgParser.h"
@@ -35,6 +34,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
Modified: lldb/trunk/source/Core/ModuleList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ModuleList.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Core/ModuleList.cpp (original)
+++ lldb/trunk/source/Core/ModuleList.cpp Wed Feb 27 13:42:10 2019
@@ -11,10 +11,10 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueFileSpec.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/VariableList.h"
Modified: lldb/trunk/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Host/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/CMakeLists.txt Wed Feb 27 13:42:10 2019
@@ -44,7 +44,6 @@ add_host_subdirectory(common
common/SocketAddress.cpp
common/Socket.cpp
common/StringConvert.cpp
- common/Symbols.cpp
common/TaskPool.cpp
common/TCPSocket.cpp
common/Terminal.cpp
@@ -95,7 +94,6 @@ else()
add_subdirectory(macosx/objcxx)
set(LLDBObjCLibs lldbHostMacOSXObjCXX)
add_host_subdirectory(macosx
- macosx/Symbols.cpp
macosx/cfcpp/CFCBundle.cpp
macosx/cfcpp/CFCData.cpp
macosx/cfcpp/CFCMutableArray.cpp
@@ -166,7 +164,6 @@ add_lldb_library(lldbHost
LINK_LIBS
lldbCore
- lldbSymbol
lldbTarget
lldbUtility
${EXTRA_LIBS}
Removed: lldb/trunk/source/Host/common/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Symbols.cpp?rev=355031&view=auto
==============================================================================
--- lldb/trunk/source/Host/common/Symbols.cpp (original)
+++ lldb/trunk/source/Host/common/Symbols.cpp (removed)
@@ -1,383 +0,0 @@
-//===-- Symbols.cpp ---------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/Symbols.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSystem.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/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-
-#include "llvm/Support/FileSystem.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;
-
-#if defined(__APPLE__)
-
-// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
- ModuleSpec &return_module_spec);
-
-#else
-
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
- ModuleSpec &return_module_spec) {
- // Cannot find MacOSX files using debug symbols on non MacOSX.
- return 0;
-}
-
-#endif
-
-static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
- const ArchSpec *arch,
- const lldb_private::UUID *uuid) {
- ModuleSpecList module_specs;
- if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
- ModuleSpec spec;
- for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
- UNUSED_IF_ASSERT_DISABLED(got_spec);
- assert(got_spec);
- if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
- (arch == NULL || (spec.GetArchitecturePtr() &&
- spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
- return true;
- }
- }
- }
- return false;
-}
-
-// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
-// return true if there is a matching dSYM bundle next to the exec_fspec,
-// and return that value in dsym_fspec.
-// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
-// call through Symbols::DownloadObjectAndSymbolFile to download the
-// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
-
-static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
- const FileSpec &exec_fspec,
- FileSpec &dsym_fspec) {
- ConstString filename = exec_fspec.GetFilename();
- FileSpec dsym_directory = exec_fspec;
- dsym_directory.RemoveLastPathComponent();
-
- std::string dsym_filename = filename.AsCString();
- dsym_filename += ".dSYM";
- dsym_directory.AppendPathComponent(dsym_filename);
- dsym_directory.AppendPathComponent("Contents");
- dsym_directory.AppendPathComponent("Resources");
- dsym_directory.AppendPathComponent("DWARF");
-
- if (FileSystem::Instance().Exists(dsym_directory)) {
-
- // See if the binary name exists in the dSYM DWARF
- // subdir.
- dsym_fspec = dsym_directory;
- dsym_fspec.AppendPathComponent(filename.AsCString());
- if (FileSystem::Instance().Exists(dsym_fspec) &&
- FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
- mod_spec.GetUUIDPtr())) {
- return true;
- }
-
- // See if we have "../CF.framework" - so we'll look for
- // CF.framework.dSYM/Contents/Resources/DWARF/CF
- // We need to drop the last suffix after '.' to match
- // 'CF' in the DWARF subdir.
- std::string binary_name (filename.AsCString());
- auto last_dot = binary_name.find_last_of('.');
- if (last_dot != std::string::npos) {
- binary_name.erase(last_dot);
- dsym_fspec = dsym_directory;
- dsym_fspec.AppendPathComponent(binary_name);
- if (FileSystem::Instance().Exists(dsym_fspec) &&
- FileAtPathContainsArchAndUUID(dsym_fspec,
- mod_spec.GetArchitecturePtr(),
- mod_spec.GetUUIDPtr())) {
- return true;
- }
- }
- }
-
- // See if we have a .dSYM.yaa next to this executable path.
- FileSpec dsym_yaa_fspec = exec_fspec;
- dsym_yaa_fspec.RemoveLastPathComponent();
- std::string dsym_yaa_filename = filename.AsCString();
- dsym_yaa_filename += ".dSYM.yaa";
- dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
-
- if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
- ModuleSpec mutable_mod_spec = mod_spec;
- if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) &&
- FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
- dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
- return true;
- }
- }
-
- return false;
-}
-
-// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
-// filled in, look for a .dSYM bundle next to that binary. Returns true
-// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
-// FileSpec.
-//
-// This routine looks a few directory layers above the given exec_path -
-// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
-// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
-//
-// If there is a .dSYM.yaa compressed archive found next to the binary,
-// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
-
-static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
- FileSpec &dsym_fspec) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- const FileSpec &exec_fspec = module_spec.GetFileSpec();
- if (exec_fspec) {
- if (::LookForDsymNextToExecutablePath (module_spec, exec_fspec, dsym_fspec)) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str());
- }
- return true;
- } else {
- FileSpec parent_dirs = exec_fspec;
-
- // Remove the binary name from the FileSpec
- parent_dirs.RemoveLastPathComponent();
-
- // Add a ".dSYM" name to each directory component of the path,
- // stripping off components. e.g. we may have a binary like
- // /S/L/F/Foundation.framework/Versions/A/Foundation and
- // /S/L/F/Foundation.framework.dSYM
- //
- // so we'll need to start with
- // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
- // "A", and if that doesn't exist, strip off the "A" and try it again
- // with "Versions", etc., until we find a dSYM bundle or we've
- // stripped off enough path components that there's no need to
- // continue.
-
- for (int i = 0; i < 4; i++) {
- // Does this part of the path have a "." character - could it be a
- // bundle's top level directory?
- const char *fn = parent_dirs.GetFilename().AsCString();
- if (fn == nullptr)
- break;
- if (::strchr(fn, '.') != nullptr) {
- if (::LookForDsymNextToExecutablePath (module_spec, parent_dirs, dsym_fspec)) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- dsym_fspec.GetPath().c_str());
- }
- return true;
- }
- }
- parent_dirs.RemoveLastPathComponent();
- }
- }
- }
- dsym_fspec.Clear();
- return false;
-}
-
-static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
- const UUID *uuid = module_spec.GetUUIDPtr();
-
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat,
- "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
- exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
- arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
-
- FileSpec symbol_fspec;
- ModuleSpec dsym_module_spec;
- // First try and find the dSYM in the same directory as the executable or in
- // an appropriate parent directory
- if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
- // We failed to easily find the dSYM above, so use DebugSymbols
- LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
- } else {
- dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
- }
- return dsym_module_spec.GetSymbolFileSpec();
-}
-
-ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
- ModuleSpec result;
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
- const UUID *uuid = module_spec.GetUUIDPtr();
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(
- func_cat, "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.
-
-FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
- FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
- if (symbol_file_spec.IsAbsolute() &&
- FileSystem::Instance().Exists(symbol_file_spec))
- return symbol_file_spec;
-
- const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
- if (symbol_filename && symbol_filename[0]) {
- FileSpecList debug_file_search_paths(
- Target::GetDefaultDebugFileSearchPaths());
-
- // Add module directory.
- FileSpec module_file_spec = module_spec.GetFileSpec();
- // We keep the unresolved pathname if it fails.
- FileSystem::Instance().ResolveSymbolicLink(module_file_spec, module_file_spec);
-
- const ConstString &file_dir = module_file_spec.GetDirectory();
- {
- FileSpec file_spec(file_dir.AsCString("."));
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
-
- if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
-
- // Add current working directory.
- {
- FileSpec file_spec(".");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
-
-#ifndef _WIN32
-#if defined(__NetBSD__)
- // Add /usr/libdata/debug directory.
- {
- FileSpec file_spec("/usr/libdata/debug");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
-#else
- // Add /usr/lib/debug directory.
- {
- FileSpec file_spec("/usr/lib/debug");
- FileSystem::Instance().Resolve(file_spec);
- debug_file_search_paths.AppendIfUnique(file_spec);
- }
-#endif
-#endif // _WIN32
- }
-
- std::string uuid_str;
- const UUID &module_uuid = module_spec.GetUUID();
- if (module_uuid.IsValid()) {
- // Some debug files are stored in the .build-id directory like this:
- // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
- uuid_str = module_uuid.GetAsString("");
- std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
- ::tolower);
- uuid_str.insert(2, 1, '/');
- uuid_str = uuid_str + ".debug";
- }
-
- size_t num_directories = debug_file_search_paths.GetSize();
- for (size_t idx = 0; idx < num_directories; ++idx) {
- FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
- FileSystem::Instance().Resolve(dirspec);
- if (!FileSystem::Instance().IsDirectory(dirspec))
- continue;
-
- std::vector<std::string> files;
- std::string dirname = dirspec.GetPath();
-
- files.push_back(dirname + "/" + symbol_filename);
- files.push_back(dirname + "/.debug/" + symbol_filename);
- files.push_back(dirname + "/.build-id/" + uuid_str);
-
- // Some debug files may stored in the module directory like this:
- // /usr/lib/debug/usr/lib/library.so.debug
- if (!file_dir.IsEmpty())
- files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);
-
- const uint32_t num_files = files.size();
- for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
- const std::string &filename = files[idx_file];
- FileSpec file_spec(filename);
- FileSystem::Instance().Resolve(file_spec);
-
- if (llvm::sys::fs::equivalent(file_spec.GetPath(),
- module_file_spec.GetPath()))
- continue;
-
- if (FileSystem::Instance().Exists(file_spec)) {
- lldb_private::ModuleSpecList specs;
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
- assert(num_specs <= 1 &&
- "Symbol Vendor supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec mspec;
- if (specs.GetModuleSpecAtIndex(0, mspec)) {
- // Skip the uuids check if module_uuid is invalid. For example,
- // this happens for *.dwp files since at the moment llvm-dwp
- // doesn't output build ids, nor does binutils dwp.
- if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
- return file_spec;
- }
- }
- }
- }
- }
- }
-
- return LocateExecutableSymbolFileDsym(module_spec);
-}
-
-#if !defined(__APPLE__)
-
-FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
- const lldb_private::UUID *uuid,
- const ArchSpec *arch) {
- // FIXME
- return FileSpec();
-}
-
-bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
- bool force_lookup) {
- // Fill in the module_spec.GetFileSpec() for the object file and/or the
- // module_spec.GetSymbolFileSpec() for the debug symbols file.
- return false;
-}
-
-#endif
Removed: lldb/trunk/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Symbols.cpp?rev=355031&view=auto
==============================================================================
--- lldb/trunk/source/Host/macosx/Symbols.cpp (original)
+++ lldb/trunk/source/Host/macosx/Symbols.cpp (removed)
@@ -1,654 +0,0 @@
-//===-- Symbols.cpp ---------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/Symbols.h"
-
-#include <dirent.h>
-#include <pwd.h>
-
-#include <CoreFoundation/CoreFoundation.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 "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/CleanUp.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-#include "mach/machine.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if !defined(__arm__) && !defined(__arm64__) && \
- !defined(__aarch64__) // No DebugSymbols on the iOS devices
-extern "C" {
-
-CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
-CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
-}
-#endif
-
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
- ModuleSpec &return_module_spec) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
- if (log)
- log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
- return 0;
- }
-
- return_module_spec = module_spec;
- return_module_spec.GetFileSpec().Clear();
- return_module_spec.GetSymbolFileSpec().Clear();
-
- int items_found = 0;
-
-#if !defined(__arm__) && !defined(__arm64__) && \
- !defined(__aarch64__) // No DebugSymbols on the iOS devices
-
- const UUID *uuid = module_spec.GetUUIDPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
-
- 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(
- ::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)) {
- if (log) {
- log->Printf("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)) {
- log->Printf("DebugSymbols framework returned dSYM path of %s for "
- "UUID %s -- looking for an exec file",
- path, uuid->GetAsString().c_str());
- }
- }
-
- CFCReleaser<CFDictionaryRef> dict(
- ::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()));
- }
- if (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))) {
- if (log) {
- log->Printf("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;
- }
- }
- }
-
- if (!success) {
- // No dictionary, check near the dSYM bundle for an executable that
- // matches...
- 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';
- if (log) {
- log->Printf("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;
- if (log) {
- log->Printf("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;
- if (log) {
- log->Printf("Executable binary %s next to dSYM is "
- "compatible; using",
- path);
- }
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
- // (__aarch64__)
-
- return items_found;
-}
-
-FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
- const lldb_private::UUID *uuid,
- const ArchSpec *arch) {
- char path[PATH_MAX];
- if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
- return {};
-
- ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
-
- DIR *dirp = opendir(path);
- if (!dirp)
- return {};
-
- // Make sure we close the directory before exiting this scope.
- CleanUp cleanup_dir(closedir, dirp);
-
- FileSpec dsym_fspec;
- dsym_fspec.GetDirectory().SetCString(path);
- struct dirent *dp;
- while ((dp = readdir(dirp)) != NULL) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- if (dp->d_namlen == 1 && dp->d_name[0] == '.')
- continue;
-
- if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
-
- if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
- dsym_fspec.GetFilename().SetCString(dp->d_name);
- ModuleSpecList module_specs;
- if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
- ModuleSpec spec;
- for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
- UNUSED_IF_ASSERT_DISABLED(got_spec);
- assert(got_spec);
- if ((uuid == NULL ||
- (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
- (arch == NULL ||
- (spec.GetArchitecturePtr() &&
- spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
- return dsym_fspec;
- }
- }
- }
- }
- }
-
- return {};
-}
-
-static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
- ModuleSpec &module_spec) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- bool success = false;
- if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
- std::string str;
- CFStringRef cf_str;
- CFDictionaryRef cf_dict;
-
- cf_str = (CFStringRef)CFDictionaryGetValue(
- (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- if (log) {
- log->Printf(
- "From dsymForUUID plist: Symbol rich executable is at '%s'",
- str.c_str());
- }
- }
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGDSYMPath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- success = true;
- if (log) {
- log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
- }
- }
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGArchitecture"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str))
- module_spec.GetArchitecture().SetTriple(str.c_str());
- }
-
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
- // If DBGVersion 2, strip last two components of path remappings from
- // entries to fix an issue with a specific set of
- // DBGSourcePathRemapping entries that lldb worked
- // with.
- // If DBGVersion 3, trust & use the source path remappings as-is.
- //
- cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
- if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
- // If we see DBGVersion with a value of 2 or higher, this is a new style
- // DBGSourcePathRemapping dictionary
- bool new_style_source_remapping_dictionary = false;
- bool do_truncate_remapping_names = false;
- std::string original_DBGSourcePath_value = DBGSourcePath;
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGVersion"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- std::string version;
- CFCString::FileSystemRepresentation(cf_str, version);
- if (!version.empty() && isdigit(version[0])) {
- int version_number = atoi(version.c_str());
- if (version_number > 1) {
- new_style_source_remapping_dictionary = true;
- }
- if (version_number == 2) {
- do_truncate_remapping_names = true;
- }
- }
- }
-
- CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
- if (kv_pair_count > 0) {
- CFStringRef *keys =
- (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
- CFStringRef *values =
- (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
- if (keys != nullptr && values != nullptr) {
- CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
- (const void **)keys,
- (const void **)values);
- }
- for (CFIndex i = 0; i < kv_pair_count; i++) {
- DBGBuildSourcePath.clear();
- DBGSourcePath.clear();
- if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
- }
- if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
- }
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- // In the "old style" DBGSourcePathRemapping dictionary, the
- // DBGSourcePath values (the "values" half of key-value path pairs)
- // were wrong. Ignore them and use the universal DBGSourcePath
- // string from earlier.
- if (new_style_source_remapping_dictionary &&
- !original_DBGSourcePath_value.empty()) {
- DBGSourcePath = original_DBGSourcePath_value;
- }
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- // With version 2 of DBGSourcePathRemapping, we can chop off the
- // last two filename parts from the source remapping and get a more
- // general source remapping that still works. Add this as another
- // option in addition to the full source path remap.
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- if (do_truncate_remapping_names) {
- FileSpec build_path(DBGBuildSourcePath.c_str());
- FileSpec source_path(DBGSourcePath.c_str());
- build_path.RemoveLastPathComponent();
- build_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- module_spec.GetSourceMappingList().Append(
- ConstString(build_path.GetPath().c_str()),
- ConstString(source_path.GetPath().c_str()), true);
- }
- }
- }
- if (keys)
- free(keys);
- if (values)
- free(values);
- }
- }
-
-
- // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
- // source remappings list.
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGBuildSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
- }
-
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- }
- }
- return success;
-}
-
-bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
- bool force_lookup) {
- bool success = false;
- const UUID *uuid_ptr = module_spec.GetUUIDPtr();
- const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
-
- // It's expensive to check for the DBGShellCommands defaults setting, only do
- // it once per lldb run and cache the result.
- static bool g_have_checked_for_dbgshell_command = false;
- static const char *g_dbgshell_command = NULL;
- if (!g_have_checked_for_dbgshell_command) {
- g_have_checked_for_dbgshell_command = true;
- CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
- CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
- if (defaults_setting &&
- CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
- char cstr_buf[PATH_MAX];
- if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf,
- sizeof(cstr_buf), kCFStringEncodingUTF8)) {
- g_dbgshell_command =
- strdup(cstr_buf); // this malloc'ed memory will never be freed
- }
- }
- if (defaults_setting) {
- CFRelease(defaults_setting);
- }
- }
-
- // When g_dbgshell_command is NULL, the user has not enabled the use of an
- // external program to find the symbols, don't run it for them.
- if (!force_lookup && g_dbgshell_command == NULL) {
- return false;
- }
-
- if (uuid_ptr ||
- (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
- static bool g_located_dsym_for_uuid_exe = false;
- static bool g_dsym_for_uuid_exe_exists = false;
- static char g_dsym_for_uuid_exe_path[PATH_MAX];
- if (!g_located_dsym_for_uuid_exe) {
- g_located_dsym_for_uuid_exe = true;
- const char *dsym_for_uuid_exe_path_cstr =
- getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
- FileSpec dsym_for_uuid_exe_spec;
- if (dsym_for_uuid_exe_path_cstr) {
- dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
-
- if (!g_dsym_for_uuid_exe_exists) {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
- FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- if (!g_dsym_for_uuid_exe_exists) {
- long bufsize;
- if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
- char buffer[bufsize];
- struct passwd pwd;
- struct passwd *tilde_rc = NULL;
- // we are a library so we need to use the reentrant version of
- // getpwnam()
- if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 &&
- tilde_rc && tilde_rc->pw_dir) {
- std::string dsymforuuid_path(tilde_rc->pw_dir);
- dsymforuuid_path += "/bin/dsymForUUID";
- dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
- FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
- }
- }
- }
- if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
-
- if (g_dsym_for_uuid_exe_exists)
- dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path,
- sizeof(g_dsym_for_uuid_exe_path));
- }
- if (g_dsym_for_uuid_exe_exists) {
- std::string uuid_str;
- char file_path[PATH_MAX];
- file_path[0] = '\0';
-
- if (uuid_ptr)
- uuid_str = uuid_ptr->GetAsString();
-
- if (file_spec_ptr)
- file_spec_ptr->GetPath(file_path, sizeof(file_path));
-
- StreamString command;
- if (!uuid_str.empty())
- command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
- g_dsym_for_uuid_exe_path, file_path);
-
- if (!command.GetString().empty()) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- int exit_status = -1;
- int signo = -1;
- std::string command_output;
- if (log) {
- if (!uuid_str.empty())
- log->Printf("Calling %s with UUID %s to find dSYM",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- log->Printf("Calling %s with file %s to find dSYM",
- g_dsym_for_uuid_exe_path, file_path);
- }
- Status error = Host::RunShellCommand(
- command.GetData(),
- NULL, // current working directory
- &exit_status, // Exit status
- &signo, // Signal int *
- &command_output, // Command output
- std::chrono::seconds(
- 30), // Large timeout to allow for long dsym download times
- false); // Don't run in a shell (we don't need shell expansion)
- if (error.Success() && exit_status == 0 && !command_output.empty()) {
- CFCData data(CFDataCreateWithBytesNoCopy(
- NULL, (const UInt8 *)command_output.data(), command_output.size(),
- kCFAllocatorNull));
-
- CFCReleaser<CFDictionaryRef> plist(
- (CFDictionaryRef)::CFPropertyListCreateFromXMLData(
- NULL, data.get(), kCFPropertyListImmutable, NULL));
-
- if (plist.get() &&
- CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) {
- if (!uuid_str.empty()) {
- CFCString uuid_cfstr(uuid_str.c_str());
- CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue(
- plist.get(), uuid_cfstr.get());
- success =
- GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec);
- } else {
- const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
- if (num_values > 0) {
- std::vector<CFStringRef> keys(num_values, NULL);
- std::vector<CFDictionaryRef> values(num_values, NULL);
- ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
- (const void **)&values[0]);
- if (num_values == 1) {
- return GetModuleSpecInfoFromUUIDDictionary(values[0],
- module_spec);
- } else {
- for (CFIndex i = 0; i < num_values; ++i) {
- ModuleSpec curr_module_spec;
- if (GetModuleSpecInfoFromUUIDDictionary(values[i],
- curr_module_spec)) {
- if (module_spec.GetArchitecture().IsCompatibleMatch(
- curr_module_spec.GetArchitecture())) {
- module_spec = curr_module_spec;
- return true;
- }
- }
- }
- }
- }
- }
- }
- } else {
- if (log) {
- if (!uuid_str.empty())
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, file_path);
- }
- }
- }
- }
- }
- return success;
-}
Modified: lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp Wed Feb 27 13:42:10 2019
@@ -15,8 +15,8 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/RegisterContext.h"
Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Wed Feb 27 13:42:10 2019
@@ -21,9 +21,9 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Wed Feb 27 13:42:10 2019
@@ -18,7 +18,6 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -28,6 +27,7 @@
#include "lldb/Interpreter/OptionGroupString.h"
#include "lldb/Interpreter/OptionGroupUInt64.h"
#include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Target.h"
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Feb 27 13:42:10 2019
@@ -41,7 +41,6 @@
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/StringConvert.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/XML.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -54,6 +53,7 @@
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/DynamicLoader.h"
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Feb 27 13:42:10 2019
@@ -29,7 +29,6 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/OptionValueFileSpecList.h"
#include "lldb/Interpreter/OptionValueProperties.h"
@@ -42,6 +41,7 @@
#include "lldb/Symbol/CompilerDeclContext.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/TypeMap.h"
Modified: lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp Wed Feb 27 13:42:10 2019
@@ -15,7 +15,7 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
Modified: lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Wed Feb 27 13:42:10 2019
@@ -15,8 +15,8 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
#include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
#include "lldb/Host/XML.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
Modified: lldb/trunk/source/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CMakeLists.txt?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CMakeLists.txt (original)
+++ lldb/trunk/source/Symbol/CMakeLists.txt Wed Feb 27 13:42:10 2019
@@ -1,3 +1,9 @@
+set(LLVM_OPTIONAL_SOURCES LocateSymbolFileMacOSX.cpp)
+
+if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ set(PLATFORM_SOURCES LocateSymbolFileMacOSX.cpp)
+endif()
+
add_lldb_library(lldbSymbol
ArmUnwindInfo.cpp
Block.cpp
@@ -18,6 +24,7 @@ add_lldb_library(lldbSymbol
FuncUnwinders.cpp
LineEntry.cpp
LineTable.cpp
+ LocateSymbolFile.cpp
ObjectFile.cpp
Symbol.cpp
SymbolContext.cpp
@@ -34,6 +41,8 @@ add_lldb_library(lldbSymbol
VariableList.cpp
VerifyDecl.cpp
+ ${PLATFORM_SOURCES}
+
LINK_LIBS
clangAST
clangBasic
Added: lldb/trunk/source/Symbol/LocateSymbolFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LocateSymbolFile.cpp?rev=355032&view=auto
==============================================================================
--- lldb/trunk/source/Symbol/LocateSymbolFile.cpp (added)
+++ lldb/trunk/source/Symbol/LocateSymbolFile.cpp Wed Feb 27 13:42:10 2019
@@ -0,0 +1,388 @@
+//===-- Symbols.cpp ---------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.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/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+
+#include "llvm/Support/FileSystem.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;
+
+#if defined(__APPLE__)
+
+// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+ ModuleSpec &return_module_spec);
+
+#else
+
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+ ModuleSpec &return_module_spec) {
+ // Cannot find MacOSX files using debug symbols on non MacOSX.
+ return 0;
+}
+
+#endif
+
+static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
+ const ArchSpec *arch,
+ const lldb_private::UUID *uuid) {
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
+ if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == NULL || (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
+// return true if there is a matching dSYM bundle next to the exec_fspec,
+// and return that value in dsym_fspec.
+// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
+// call through Symbols::DownloadObjectAndSymbolFile to download the
+// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
+
+static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
+ const FileSpec &exec_fspec,
+ FileSpec &dsym_fspec) {
+ ConstString filename = exec_fspec.GetFilename();
+ FileSpec dsym_directory = exec_fspec;
+ dsym_directory.RemoveLastPathComponent();
+
+ std::string dsym_filename = filename.AsCString();
+ dsym_filename += ".dSYM";
+ dsym_directory.AppendPathComponent(dsym_filename);
+ dsym_directory.AppendPathComponent("Contents");
+ dsym_directory.AppendPathComponent("Resources");
+ dsym_directory.AppendPathComponent("DWARF");
+
+ if (FileSystem::Instance().Exists(dsym_directory)) {
+
+ // See if the binary name exists in the dSYM DWARF
+ // subdir.
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(filename.AsCString());
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+
+ // See if we have "../CF.framework" - so we'll look for
+ // CF.framework.dSYM/Contents/Resources/DWARF/CF
+ // We need to drop the last suffix after '.' to match
+ // 'CF' in the DWARF subdir.
+ std::string binary_name(filename.AsCString());
+ auto last_dot = binary_name.find_last_of('.');
+ if (last_dot != std::string::npos) {
+ binary_name.erase(last_dot);
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(binary_name);
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec,
+ mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+ }
+ }
+
+ // See if we have a .dSYM.yaa next to this executable path.
+ FileSpec dsym_yaa_fspec = exec_fspec;
+ dsym_yaa_fspec.RemoveLastPathComponent();
+ std::string dsym_yaa_filename = filename.AsCString();
+ dsym_yaa_filename += ".dSYM.yaa";
+ dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
+
+ if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
+ ModuleSpec mutable_mod_spec = mod_spec;
+ if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) &&
+ FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
+ dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
+// filled in, look for a .dSYM bundle next to that binary. Returns true
+// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
+// FileSpec.
+//
+// This routine looks a few directory layers above the given exec_path -
+// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
+// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
+//
+// If there is a .dSYM.yaa compressed archive found next to the binary,
+// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
+
+static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
+ FileSpec &dsym_fspec) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ const FileSpec &exec_fspec = module_spec.GetFileSpec();
+ if (exec_fspec) {
+ if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec,
+ dsym_fspec)) {
+ if (log) {
+ log->Printf("dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
+ } else {
+ FileSpec parent_dirs = exec_fspec;
+
+ // Remove the binary name from the FileSpec
+ parent_dirs.RemoveLastPathComponent();
+
+ // Add a ".dSYM" name to each directory component of the path,
+ // stripping off components. e.g. we may have a binary like
+ // /S/L/F/Foundation.framework/Versions/A/Foundation and
+ // /S/L/F/Foundation.framework.dSYM
+ //
+ // so we'll need to start with
+ // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+ // "A", and if that doesn't exist, strip off the "A" and try it again
+ // with "Versions", etc., until we find a dSYM bundle or we've
+ // stripped off enough path components that there's no need to
+ // continue.
+
+ for (int i = 0; i < 4; i++) {
+ // Does this part of the path have a "." character - could it be a
+ // bundle's top level directory?
+ const char *fn = parent_dirs.GetFilename().AsCString();
+ if (fn == nullptr)
+ break;
+ if (::strchr(fn, '.') != nullptr) {
+ if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs,
+ dsym_fspec)) {
+ if (log) {
+ log->Printf("dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
+ }
+ return true;
+ }
+ }
+ parent_dirs.RemoveLastPathComponent();
+ }
+ }
+ }
+ dsym_fspec.Clear();
+ return false;
+}
+
+static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
+ const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+ const UUID *uuid = module_spec.GetUUIDPtr();
+
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(
+ func_cat,
+ "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
+ exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
+ arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
+
+ FileSpec symbol_fspec;
+ ModuleSpec dsym_module_spec;
+ // First try and find the dSYM in the same directory as the executable or in
+ // an appropriate parent directory
+ if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
+ // We failed to easily find the dSYM above, so use DebugSymbols
+ LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
+ } else {
+ dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
+ }
+ return dsym_module_spec.GetSymbolFileSpec();
+}
+
+ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
+ ModuleSpec result;
+ const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(
+ func_cat, "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.
+
+FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
+ FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
+ if (symbol_file_spec.IsAbsolute() &&
+ FileSystem::Instance().Exists(symbol_file_spec))
+ return symbol_file_spec;
+
+ const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
+ if (symbol_filename && symbol_filename[0]) {
+ FileSpecList debug_file_search_paths(
+ Target::GetDefaultDebugFileSearchPaths());
+
+ // Add module directory.
+ FileSpec module_file_spec = module_spec.GetFileSpec();
+ // We keep the unresolved pathname if it fails.
+ FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
+ module_file_spec);
+
+ const ConstString &file_dir = module_file_spec.GetDirectory();
+ {
+ FileSpec file_spec(file_dir.AsCString("."));
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+ if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+
+ // Add current working directory.
+ {
+ FileSpec file_spec(".");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+#ifndef _WIN32
+#if defined(__NetBSD__)
+ // Add /usr/libdata/debug directory.
+ {
+ FileSpec file_spec("/usr/libdata/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+#else
+ // Add /usr/lib/debug directory.
+ {
+ FileSpec file_spec("/usr/lib/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+#endif
+#endif // _WIN32
+ }
+
+ std::string uuid_str;
+ const UUID &module_uuid = module_spec.GetUUID();
+ if (module_uuid.IsValid()) {
+ // Some debug files are stored in the .build-id directory like this:
+ // /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
+ uuid_str = module_uuid.GetAsString("");
+ std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+ ::tolower);
+ uuid_str.insert(2, 1, '/');
+ uuid_str = uuid_str + ".debug";
+ }
+
+ size_t num_directories = debug_file_search_paths.GetSize();
+ for (size_t idx = 0; idx < num_directories; ++idx) {
+ FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
+ continue;
+
+ std::vector<std::string> files;
+ std::string dirname = dirspec.GetPath();
+
+ files.push_back(dirname + "/" + symbol_filename);
+ files.push_back(dirname + "/.debug/" + symbol_filename);
+ files.push_back(dirname + "/.build-id/" + uuid_str);
+
+ // Some debug files may stored in the module directory like this:
+ // /usr/lib/debug/usr/lib/library.so.debug
+ if (!file_dir.IsEmpty())
+ files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);
+
+ const uint32_t num_files = files.size();
+ for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
+ const std::string &filename = files[idx_file];
+ FileSpec file_spec(filename);
+ FileSystem::Instance().Resolve(file_spec);
+
+ if (llvm::sys::fs::equivalent(file_spec.GetPath(),
+ module_file_spec.GetPath()))
+ continue;
+
+ if (FileSystem::Instance().Exists(file_spec)) {
+ lldb_private::ModuleSpecList specs;
+ const size_t num_specs =
+ ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
+ assert(num_specs <= 1 &&
+ "Symbol Vendor supports only a single architecture");
+ if (num_specs == 1) {
+ ModuleSpec mspec;
+ if (specs.GetModuleSpecAtIndex(0, mspec)) {
+ // Skip the uuids check if module_uuid is invalid. For example,
+ // this happens for *.dwp files since at the moment llvm-dwp
+ // doesn't output build ids, nor does binutils dwp.
+ if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
+ return file_spec;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return LocateExecutableSymbolFileDsym(module_spec);
+}
+
+#if !defined(__APPLE__)
+
+FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
+ const lldb_private::UUID *uuid,
+ const ArchSpec *arch) {
+ // FIXME
+ return FileSpec();
+}
+
+bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ bool force_lookup) {
+ // Fill in the module_spec.GetFileSpec() for the object file and/or the
+ // module_spec.GetSymbolFileSpec() for the debug symbols file.
+ return false;
+}
+
+#endif
Added: lldb/trunk/source/Symbol/LocateSymbolFileMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LocateSymbolFileMacOSX.cpp?rev=355032&view=auto
==============================================================================
--- lldb/trunk/source/Symbol/LocateSymbolFileMacOSX.cpp (added)
+++ lldb/trunk/source/Symbol/LocateSymbolFileMacOSX.cpp Wed Feb 27 13:42:10 2019
@@ -0,0 +1,653 @@
+//===-- Symbols.cpp ---------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+#include <dirent.h>
+#include <pwd.h>
+
+#include <CoreFoundation/CoreFoundation.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 "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+#include "mach/machine.h"
+
+#include "llvm/Support/FileSystem.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#if !defined(__arm__) && !defined(__arm64__) && \
+ !defined(__aarch64__) // No DebugSymbols on the iOS devices
+extern "C" {
+
+CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
+CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
+}
+#endif
+
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+ ModuleSpec &return_module_spec) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+ if (log)
+ log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
+ return 0;
+ }
+
+ return_module_spec = module_spec;
+ return_module_spec.GetFileSpec().Clear();
+ return_module_spec.GetSymbolFileSpec().Clear();
+
+ int items_found = 0;
+
+#if !defined(__arm__) && !defined(__arm64__) && \
+ !defined(__aarch64__) // No DebugSymbols on the iOS devices
+
+ const UUID *uuid = module_spec.GetUUIDPtr();
+ const ArchSpec *arch = module_spec.GetArchitecturePtr();
+
+ 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(
+ ::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)) {
+ if (log) {
+ log->Printf("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)) {
+ log->Printf("DebugSymbols framework returned dSYM path of %s for "
+ "UUID %s -- looking for an exec file",
+ path, uuid->GetAsString().c_str());
+ }
+ }
+
+ CFCReleaser<CFDictionaryRef> dict(
+ ::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()));
+ }
+ if (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))) {
+ if (log) {
+ log->Printf("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;
+ }
+ }
+ }
+
+ if (!success) {
+ // No dictionary, check near the dSYM bundle for an executable that
+ // matches...
+ 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';
+ if (log) {
+ log->Printf("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;
+ if (log) {
+ log->Printf("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;
+ if (log) {
+ log->Printf("Executable binary %s next to dSYM is "
+ "compatible; using",
+ path);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
+ // (__aarch64__)
+
+ return items_found;
+}
+
+FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
+ const lldb_private::UUID *uuid,
+ const ArchSpec *arch) {
+ char path[PATH_MAX];
+ if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
+ return {};
+
+ ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
+
+ DIR *dirp = opendir(path);
+ if (!dirp)
+ return {};
+
+ // Make sure we close the directory before exiting this scope.
+ CleanUp cleanup_dir(closedir, dirp);
+
+ FileSpec dsym_fspec;
+ dsym_fspec.GetDirectory().SetCString(path);
+ struct dirent *dp;
+ while ((dp = readdir(dirp)) != NULL) {
+ // Only search directories
+ if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+ if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+ continue;
+
+ if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+ continue;
+ }
+
+ if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
+ dsym_fspec.GetFilename().SetCString(dp->d_name);
+ ModuleSpecList module_specs;
+ if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+ ModuleSpec spec;
+ for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
+ if ((uuid == NULL ||
+ (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == NULL ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return dsym_fspec;
+ }
+ }
+ }
+ }
+ }
+
+ return {};
+}
+
+static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
+ ModuleSpec &module_spec) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ bool success = false;
+ if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
+ std::string str;
+ CFStringRef cf_str;
+ CFDictionaryRef cf_dict;
+
+ cf_str = (CFStringRef)CFDictionaryGetValue(
+ (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str)) {
+ module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ if (log) {
+ log->Printf(
+ "From dsymForUUID plist: Symbol rich executable is at '%s'",
+ str.c_str());
+ }
+ }
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGDSYMPath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str)) {
+ module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
+ FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+ success = true;
+ if (log) {
+ log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
+ }
+ }
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGArchitecture"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ if (CFCString::FileSystemRepresentation(cf_str, str))
+ module_spec.GetArchitecture().SetTriple(str.c_str());
+ }
+
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
+
+ // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+ // If DBGVersion 2, strip last two components of path remappings from
+ // entries to fix an issue with a specific set of
+ // DBGSourcePathRemapping entries that lldb worked
+ // with.
+ // If DBGVersion 3, trust & use the source path remappings as-is.
+ //
+ cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
+ (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
+ if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
+ // If we see DBGVersion with a value of 2 or higher, this is a new style
+ // DBGSourcePathRemapping dictionary
+ bool new_style_source_remapping_dictionary = false;
+ bool do_truncate_remapping_names = false;
+ std::string original_DBGSourcePath_value = DBGSourcePath;
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGVersion"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ std::string version;
+ CFCString::FileSystemRepresentation(cf_str, version);
+ if (!version.empty() && isdigit(version[0])) {
+ int version_number = atoi(version.c_str());
+ if (version_number > 1) {
+ new_style_source_remapping_dictionary = true;
+ }
+ if (version_number == 2) {
+ do_truncate_remapping_names = true;
+ }
+ }
+ }
+
+ CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
+ if (kv_pair_count > 0) {
+ CFStringRef *keys =
+ (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+ CFStringRef *values =
+ (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+ if (keys != nullptr && values != nullptr) {
+ CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
+ (const void **)keys,
+ (const void **)values);
+ }
+ for (CFIndex i = 0; i < kv_pair_count; i++) {
+ DBGBuildSourcePath.clear();
+ DBGSourcePath.clear();
+ if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
+ }
+ if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
+ }
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ // In the "old style" DBGSourcePathRemapping dictionary, the
+ // DBGSourcePath values (the "values" half of key-value path pairs)
+ // were wrong. Ignore them and use the universal DBGSourcePath
+ // string from earlier.
+ if (new_style_source_remapping_dictionary &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ // With version 2 of DBGSourcePathRemapping, we can chop off the
+ // last two filename parts from the source remapping and get a more
+ // general source remapping that still works. Add this as another
+ // option in addition to the full source path remap.
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ if (do_truncate_remapping_names) {
+ FileSpec build_path(DBGBuildSourcePath.c_str());
+ FileSpec source_path(DBGSourcePath.c_str());
+ build_path.RemoveLastPathComponent();
+ build_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ source_path.RemoveLastPathComponent();
+ module_spec.GetSourceMappingList().Append(
+ ConstString(build_path.GetPath().c_str()),
+ ConstString(source_path.GetPath().c_str()), true);
+ }
+ }
+ }
+ if (keys)
+ free(keys);
+ if (values)
+ free(values);
+ }
+ }
+
+ // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
+ // source remappings list.
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGBuildSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+ }
+
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+ }
+
+ if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ }
+ }
+ return success;
+}
+
+bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+ bool force_lookup) {
+ bool success = false;
+ const UUID *uuid_ptr = module_spec.GetUUIDPtr();
+ const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+
+ // It's expensive to check for the DBGShellCommands defaults setting, only do
+ // it once per lldb run and cache the result.
+ static bool g_have_checked_for_dbgshell_command = false;
+ static const char *g_dbgshell_command = NULL;
+ if (!g_have_checked_for_dbgshell_command) {
+ g_have_checked_for_dbgshell_command = true;
+ CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
+ CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
+ if (defaults_setting &&
+ CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
+ char cstr_buf[PATH_MAX];
+ if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf,
+ sizeof(cstr_buf), kCFStringEncodingUTF8)) {
+ g_dbgshell_command =
+ strdup(cstr_buf); // this malloc'ed memory will never be freed
+ }
+ }
+ if (defaults_setting) {
+ CFRelease(defaults_setting);
+ }
+ }
+
+ // When g_dbgshell_command is NULL, the user has not enabled the use of an
+ // external program to find the symbols, don't run it for them.
+ if (!force_lookup && g_dbgshell_command == NULL) {
+ return false;
+ }
+
+ if (uuid_ptr ||
+ (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
+ static bool g_located_dsym_for_uuid_exe = false;
+ static bool g_dsym_for_uuid_exe_exists = false;
+ static char g_dsym_for_uuid_exe_path[PATH_MAX];
+ if (!g_located_dsym_for_uuid_exe) {
+ g_located_dsym_for_uuid_exe = true;
+ const char *dsym_for_uuid_exe_path_cstr =
+ getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
+ FileSpec dsym_for_uuid_exe_spec;
+ if (dsym_for_uuid_exe_path_cstr) {
+ dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
+ FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+ }
+
+ if (!g_dsym_for_uuid_exe_exists) {
+ dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
+ FileSpec::Style::native);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+ if (!g_dsym_for_uuid_exe_exists) {
+ long bufsize;
+ if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
+ char buffer[bufsize];
+ struct passwd pwd;
+ struct passwd *tilde_rc = NULL;
+ // we are a library so we need to use the reentrant version of
+ // getpwnam()
+ if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 &&
+ tilde_rc && tilde_rc->pw_dir) {
+ std::string dsymforuuid_path(tilde_rc->pw_dir);
+ dsymforuuid_path += "/bin/dsymForUUID";
+ dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
+ FileSpec::Style::native);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+ }
+ }
+ }
+ }
+ if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
+ dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
+ FileSpec::Style::native);
+ FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+ }
+
+ if (g_dsym_for_uuid_exe_exists)
+ dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path,
+ sizeof(g_dsym_for_uuid_exe_path));
+ }
+ if (g_dsym_for_uuid_exe_exists) {
+ std::string uuid_str;
+ char file_path[PATH_MAX];
+ file_path[0] = '\0';
+
+ if (uuid_ptr)
+ uuid_str = uuid_ptr->GetAsString();
+
+ if (file_spec_ptr)
+ file_spec_ptr->GetPath(file_path, sizeof(file_path));
+
+ StreamString command;
+ if (!uuid_str.empty())
+ command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
+ g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ else if (file_path[0] != '\0')
+ command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
+ g_dsym_for_uuid_exe_path, file_path);
+
+ if (!command.GetString().empty()) {
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ int exit_status = -1;
+ int signo = -1;
+ std::string command_output;
+ if (log) {
+ if (!uuid_str.empty())
+ log->Printf("Calling %s with UUID %s to find dSYM",
+ g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ else if (file_path[0] != '\0')
+ log->Printf("Calling %s with file %s to find dSYM",
+ g_dsym_for_uuid_exe_path, file_path);
+ }
+ Status error = Host::RunShellCommand(
+ command.GetData(),
+ NULL, // current working directory
+ &exit_status, // Exit status
+ &signo, // Signal int *
+ &command_output, // Command output
+ std::chrono::seconds(
+ 30), // Large timeout to allow for long dsym download times
+ false); // Don't run in a shell (we don't need shell expansion)
+ if (error.Success() && exit_status == 0 && !command_output.empty()) {
+ CFCData data(CFDataCreateWithBytesNoCopy(
+ NULL, (const UInt8 *)command_output.data(), command_output.size(),
+ kCFAllocatorNull));
+
+ CFCReleaser<CFDictionaryRef> plist(
+ (CFDictionaryRef)::CFPropertyListCreateFromXMLData(
+ NULL, data.get(), kCFPropertyListImmutable, NULL));
+
+ if (plist.get() &&
+ CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) {
+ if (!uuid_str.empty()) {
+ CFCString uuid_cfstr(uuid_str.c_str());
+ CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue(
+ plist.get(), uuid_cfstr.get());
+ success =
+ GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec);
+ } else {
+ const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
+ if (num_values > 0) {
+ std::vector<CFStringRef> keys(num_values, NULL);
+ std::vector<CFDictionaryRef> values(num_values, NULL);
+ ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
+ (const void **)&values[0]);
+ if (num_values == 1) {
+ return GetModuleSpecInfoFromUUIDDictionary(values[0],
+ module_spec);
+ } else {
+ for (CFIndex i = 0; i < num_values; ++i) {
+ ModuleSpec curr_module_spec;
+ if (GetModuleSpecInfoFromUUIDDictionary(values[i],
+ curr_module_spec)) {
+ if (module_spec.GetArchitecture().IsCompatibleMatch(
+ curr_module_spec.GetArchitecture())) {
+ module_spec = curr_module_spec;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ if (log) {
+ if (!uuid_str.empty())
+ log->Printf("Called %s on %s, no matches",
+ g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ else if (file_path[0] != '\0')
+ log->Printf("Called %s on %s, no matches",
+ g_dsym_for_uuid_exe_path, file_path);
+ }
+ }
+ }
+ }
+ }
+ return success;
+}
Modified: lldb/trunk/unittests/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/CMakeLists.txt?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/unittests/Host/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Host/CMakeLists.txt Wed Feb 27 13:42:10 2019
@@ -9,7 +9,6 @@ set (FILES
ProcessLaunchInfoTest.cpp
SocketAddressTest.cpp
SocketTest.cpp
- SymbolsTest.cpp
TaskPoolTest.cpp
)
Removed: lldb/trunk/unittests/Host/SymbolsTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Host/SymbolsTest.cpp?rev=355031&view=auto
==============================================================================
--- lldb/trunk/unittests/Host/SymbolsTest.cpp (original)
+++ lldb/trunk/unittests/Host/SymbolsTest.cpp (removed)
@@ -1,48 +0,0 @@
-//===-- SymbolsTest.cpp -----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Symbols.h"
-
-using namespace lldb_private;
-
-namespace {
-class SymbolsTest : public ::testing::Test {
-public:
- void SetUp() override {
- FileSystem::Initialize();
- HostInfo::Initialize();
- }
- void TearDown() override {
- HostInfo::Terminate();
- FileSystem::Terminate();
- }
-};
-} // namespace
-
-TEST_F(
- SymbolsTest,
- TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
- ModuleSpec module_spec;
- FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
- EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
-}
-
-TEST_F(SymbolsTest,
- LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
- ModuleSpec module_spec;
- // using a GUID here because the symbol file shouldn't actually exist on disk
- module_spec.GetSymbolFileSpec().SetFile(
- "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
- FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
- EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
-}
Modified: lldb/trunk/unittests/Symbol/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/CMakeLists.txt?rev=355032&r1=355031&r2=355032&view=diff
==============================================================================
--- lldb/trunk/unittests/Symbol/CMakeLists.txt (original)
+++ lldb/trunk/unittests/Symbol/CMakeLists.txt Wed Feb 27 13:42:10 2019
@@ -1,4 +1,5 @@
add_lldb_unittest(SymbolTests
+ LocateSymbolFileTest.cpp
TestClangASTContext.cpp
TestDWARFCallFrameInfo.cpp
TestType.cpp
Added: lldb/trunk/unittests/Symbol/LocateSymbolFileTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Symbol/LocateSymbolFileTest.cpp?rev=355032&view=auto
==============================================================================
--- lldb/trunk/unittests/Symbol/LocateSymbolFileTest.cpp (added)
+++ lldb/trunk/unittests/Symbol/LocateSymbolFileTest.cpp Wed Feb 27 13:42:10 2019
@@ -0,0 +1,48 @@
+//===-- SymbolsTest.cpp -----------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+using namespace lldb_private;
+
+namespace {
+class SymbolsTest : public ::testing::Test {
+public:
+ void SetUp() override {
+ FileSystem::Initialize();
+ HostInfo::Initialize();
+ }
+ void TearDown() override {
+ HostInfo::Terminate();
+ FileSystem::Terminate();
+ }
+};
+} // namespace
+
+TEST_F(
+ SymbolsTest,
+ TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
+ ModuleSpec module_spec;
+ FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
+ EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
+}
+
+TEST_F(SymbolsTest,
+ LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
+ ModuleSpec module_spec;
+ // using a GUID here because the symbol file shouldn't actually exist on disk
+ module_spec.GetSymbolFileSpec().SetFile(
+ "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
+ FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
+ EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
+}
More information about the lldb-commits
mailing list