diff options
Diffstat (limited to 'source/Plugins/SymbolVendor/MacOSX')
-rw-r--r-- | source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt | 5 | ||||
-rw-r--r-- | source/Plugins/SymbolVendor/MacOSX/Makefile | 14 | ||||
-rw-r--r-- | source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp | 251 | ||||
-rw-r--r-- | source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h | 58 |
4 files changed, 328 insertions, 0 deletions
diff --git a/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt b/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt new file mode 100644 index 000000000000..093766ac07d5 --- /dev/null +++ b/source/Plugins/SymbolVendor/MacOSX/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${LIBXML2_INCLUDE_DIR}) + +add_lldb_library(lldbPluginSymbolVendorMacOSX + SymbolVendorMacOSX.cpp + ) diff --git a/source/Plugins/SymbolVendor/MacOSX/Makefile b/source/Plugins/SymbolVendor/MacOSX/Makefile new file mode 100644 index 000000000000..9f71ad669aa0 --- /dev/null +++ b/source/Plugins/SymbolVendor/MacOSX/Makefile @@ -0,0 +1,14 @@ +##===- source/Plugins/SymbolVendor/MacOSX/Makefile ---------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LLDB_LEVEL := ../../../.. +LIBRARYNAME := lldbPluginSymbolVendorMacOSX +BUILD_ARCHIVE = 1 + +include $(LLDB_LEVEL)/Makefile diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp new file mode 100644 index 000000000000..7d21fbc0ede4 --- /dev/null +++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp @@ -0,0 +1,251 @@ +//===-- SymbolVendorMacOSX.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolVendorMacOSX.h" + +#include <string.h> + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Core/Timer.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/Symbols.h" +#include "lldb/Host/XML.h" +#include "lldb/Symbol/ObjectFile.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// SymbolVendorMacOSX constructor +//---------------------------------------------------------------------- +SymbolVendorMacOSX::SymbolVendorMacOSX(const lldb::ModuleSP &module_sp) : + SymbolVendor (module_sp) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SymbolVendorMacOSX::~SymbolVendorMacOSX() +{ +} + + +static bool +UUIDsMatch(Module *module, ObjectFile *ofile, lldb_private::Stream *feedback_strm) +{ + if (module && ofile) + { + // Make sure the UUIDs match + lldb_private::UUID dsym_uuid; + + if (!ofile->GetUUID(&dsym_uuid)) + { + if (feedback_strm) + { + feedback_strm->PutCString("warning: failed to get the uuid for object file: '"); + ofile->GetFileSpec().Dump(feedback_strm); + feedback_strm->PutCString("\n"); + } + return false; + } + + if (dsym_uuid == module->GetUUID()) + return true; + + // Emit some warning messages since the UUIDs do not match! + if (feedback_strm) + { + feedback_strm->PutCString("warning: UUID mismatch detected between modules:\n "); + module->GetUUID().Dump(feedback_strm); + feedback_strm->PutChar(' '); + module->GetFileSpec().Dump(feedback_strm); + feedback_strm->PutCString("\n "); + dsym_uuid.Dump(feedback_strm); + feedback_strm->PutChar(' '); + ofile->GetFileSpec().Dump(feedback_strm); + feedback_strm->EOL(); + } + } + return false; +} + +void +SymbolVendorMacOSX::Initialize() +{ + PluginManager::RegisterPlugin (GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void +SymbolVendorMacOSX::Terminate() +{ + PluginManager::UnregisterPlugin (CreateInstance); +} + + +lldb_private::ConstString +SymbolVendorMacOSX::GetPluginNameStatic() +{ + static ConstString g_name("macosx"); + return g_name; +} + +const char * +SymbolVendorMacOSX::GetPluginDescriptionStatic() +{ + return "Symbol vendor for MacOSX that looks for dSYM files that match executables."; +} + + + +//---------------------------------------------------------------------- +// CreateInstance +// +// Platforms can register a callback to use when creating symbol +// vendors to allow for complex debug information file setups, and to +// also allow for finding separate debug information files. +//---------------------------------------------------------------------- +SymbolVendor* +SymbolVendorMacOSX::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm) +{ + if (!module_sp) + return NULL; + + ObjectFile * obj_file = module_sp->GetObjectFile(); + if (!obj_file) + return NULL; + + static ConstString obj_file_macho("mach-o"); + ConstString obj_name = obj_file->GetPluginName(); + if (obj_name != obj_file_macho) + return NULL; + + Timer scoped_timer (__PRETTY_FUNCTION__, + "SymbolVendorMacOSX::CreateInstance (module = %s)", + module_sp->GetFileSpec().GetPath().c_str()); + SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module_sp); + if (symbol_vendor) + { + char path[PATH_MAX]; + path[0] = '\0'; + + // Try and locate the dSYM file on Mac OS X + Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM", + "SymbolVendorMacOSX::CreateInstance (module = %s) locate dSYM", + module_sp->GetFileSpec().GetPath().c_str()); + + // First check to see if the module has a symbol file in mind already. + // If it does, then we MUST use that. + FileSpec dsym_fspec (module_sp->GetSymbolFileFileSpec()); + + ObjectFileSP dsym_objfile_sp; + if (!dsym_fspec) + { + // No symbol file was specified in the module, lets try and find + // one ourselves. + FileSpec file_spec = obj_file->GetFileSpec(); + if (!file_spec) + file_spec = module_sp->GetFileSpec(); + + ModuleSpec module_spec(file_spec, module_sp->GetArchitecture()); + module_spec.GetUUID() = module_sp->GetUUID(); + dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec); + if (module_spec.GetSourceMappingList().GetSize()) + module_sp->GetSourceMappingList().Append (module_spec.GetSourceMappingList (), true); + } + + if (dsym_fspec) + { + DataBufferSP dsym_file_data_sp; + lldb::offset_t dsym_file_data_offset = 0; + dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset); + if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm)) + { + // We need a XML parser if we hope to parse a plist... + if (XMLDocument::XMLEnabled()) + { + char dsym_path[PATH_MAX]; + if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path))) + { + lldb_private::UUID dsym_uuid; + if (dsym_objfile_sp->GetUUID(&dsym_uuid)) + { + std::string uuid_str = dsym_uuid.GetAsString (); + if (!uuid_str.empty()) + { + char *resources = strstr (dsym_path, "/Contents/Resources/"); + if (resources) + { + char dsym_uuid_plist_path[PATH_MAX]; + resources[strlen("/Contents/Resources/")] = '\0'; + snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str()); + FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false); + if (dsym_uuid_plist_spec.Exists()) + { + ApplePropertyList plist(dsym_uuid_plist_path); + if (plist) + { + std::string DBGBuildSourcePath; + std::string DBGSourcePath; + + plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath); + plist.GetValueAsString("DBGSourcePath", DBGSourcePath); + if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) + { + if (DBGSourcePath[0] == '~') + { + FileSpec resolved_source_path(DBGSourcePath.c_str(), true); + DBGSourcePath = resolved_source_path.GetPath(); + } + module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true); + } + } + } + } + } + } + } + } + + symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp); + return symbol_vendor; + } + } + + // Just create our symbol vendor using the current objfile as this is either + // an executable with no dSYM (that we could locate), an executable with + // a dSYM that has a UUID that doesn't match. + symbol_vendor->AddSymbolFileRepresentation(obj_file->shared_from_this()); + } + return symbol_vendor; +} + + + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +ConstString +SymbolVendorMacOSX::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +SymbolVendorMacOSX::GetPluginVersion() +{ + return 1; +} + diff --git a/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h new file mode 100644 index 000000000000..31a842ade86f --- /dev/null +++ b/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h @@ -0,0 +1,58 @@ +//===-- SymbolVendorMacOSX.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_SymbolVendorMacOSX_h_ +#define liblldb_SymbolVendorMacOSX_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Symbol/SymbolVendor.h" + +class SymbolVendorMacOSX : public lldb_private::SymbolVendor +{ +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void + Initialize(); + + static void + Terminate(); + + static lldb_private::ConstString + GetPluginNameStatic(); + + static const char * + GetPluginDescriptionStatic(); + + static lldb_private::SymbolVendor* + CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolVendorMacOSX (const lldb::ModuleSP &module_sp); + + virtual + ~SymbolVendorMacOSX(); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + virtual lldb_private::ConstString + GetPluginName(); + + virtual uint32_t + GetPluginVersion(); + +private: + DISALLOW_COPY_AND_ASSIGN (SymbolVendorMacOSX); +}; + +#endif // liblldb_SymbolVendorMacOSX_h_ |