summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp')
-rw-r--r--lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
new file mode 100644
index 00000000000..270d7ed0f5d
--- /dev/null
+++ b/lldb/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -0,0 +1,339 @@
+//===-- 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 <mach/machine.h> // DebugSymbols needs this on Leopard...
+
+#include <AvailabilityMacros.h>
+
+#include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Timer.h"
+#include "lldb/Host/Symbols.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// SymbolVendorMacOSX constructor
+//----------------------------------------------------------------------
+SymbolVendorMacOSX::SymbolVendorMacOSX(Module *module) :
+ SymbolVendor(module)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+SymbolVendorMacOSX::~SymbolVendorMacOSX()
+{
+}
+
+
+static bool
+UUIDsMatch(Module *module, ObjectFile *ofile)
+{
+ if (module && ofile)
+ {
+ // Make sure the UUIDs match
+ UUID dsym_uuid;
+ if (ofile->GetUUID(&dsym_uuid))
+ return dsym_uuid == module->GetUUID();
+ }
+ return false;
+}
+
+
+//ObjectFile *
+//LocateDSYMMachFileInDSYMBundle (Module* module, FileSpec& dsym_fspec)
+//{
+// ObjectFile *dsym_objfile = NULL;
+//
+// char path[PATH_MAX];
+//
+// if (dsym_fspec.GetPath(path, sizeof(path)))
+// {
+// size_t path_len = strlen(path);
+// const char *bundle_subpath = "/Contents/Resources/DWARF/";
+// if (path_len > 0)
+// {
+// if (path[path_len-1] == '/')
+// ::strncat (path, bundle_subpath + 1, sizeof(path));
+// else
+// ::strncat (path, bundle_subpath, sizeof(path));
+// ::strncat (path, dsym_fspec.GetFilename().AsCString(), sizeof(path));
+//
+// path_len = strlen(path);
+//
+// if (::strcasecmp (&path[path_len - strlen(".dSYM")], ".dSYM") == 0)
+// {
+// path[path_len - ::strlen(".dSYM")] = '\0';
+// dsym_fspec.SetFile(path);
+// dsym_objfile = ObjectFile::FindPlugin(module, &dsym_fspec, 0);
+// }
+// }
+// }
+// return dsym_objfile;
+//}
+//
+//CFURLRef DBGCopyFullDSYMURLForUUID (CFUUIDRef uuid, CFURLRef exec_url) __attribute__((weak_import));
+
+
+//ObjectFile *
+//FindDSYMUsingDebugSymbols (Module* module, FileSpec& dsym_fspec)
+//{
+// Timer scoped_locate("FindDSYMUsingDebugSymbols");
+// dsym_fspec.Clear();
+// ObjectFile *dsym_objfile = NULL;
+// if (module->GetUUID().IsValid())
+// {
+// // Try and locate the dSYM file using DebugSymbols first
+// const UInt8 *module_uuid = (const UInt8 *)module->GetUUID().GetBytes();
+// if (module_uuid != NULL)
+// {
+// CFUUIDRef module_uuid_ref;
+// 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)
+// {
+// CFURLRef dsym_url = NULL;
+// CFURLRef exec_url = NULL;
+//
+// // if (DBGCopyFullDSYMURLForUUID)
+// {
+// char exec_path[PATH_MAX];
+// if (module->GetFileSpec().GetPath(exec_path, sizeof(exec_path)))
+// {
+// exec_url = CFURLCreateFromFileSystemRepresentation ( NULL,
+// (const UInt8 *)exec_path,
+// strlen(exec_path),
+// FALSE);
+// }
+//
+// dsym_url = DBGCopyFullDSYMURLForUUID(module_uuid_ref, exec_url);
+// }
+// // else
+// // {
+// // dsym_url = DBGCopyDSYMURLForUUID(module_uuid_ref);
+// // }
+//
+// if (exec_url)
+// {
+// ::CFRelease (exec_url);
+// exec_url = NULL;
+// }
+//
+// ::CFRelease(module_uuid_ref);
+// module_uuid_ref = NULL;
+//
+// if (dsym_url)
+// {
+// char dsym_path[PATH_MAX];
+// Boolean success = CFURLGetFileSystemRepresentation (dsym_url, true, (UInt8*)dsym_path, sizeof(dsym_path)-1);
+//
+// ::CFRelease(dsym_url), dsym_url = NULL;
+//
+// if (success)
+// {
+// dsym_fspec.SetFile(dsym_path);
+//
+// // Some newer versions of DebugSymbols will return a full path into a dSYM bundle
+// // that points to the correct mach file within the dSYM bundle (MH_DSYM mach file
+// // type).
+// dsym_objfile = ObjectFile::FindPlugin(module, &dsym_fspec, 0);
+//
+// // Olders versions of DebugSymbols will return a path to a dSYM bundle.
+// if (dsym_objfile == NULL)
+// dsym_objfile = LocateDSYMMachFileInDSYMBundle (module, dsym_fspec);
+// }
+// }
+// }
+// }
+// }
+// return dsym_objfile;
+//}
+
+static void
+ReplaceDSYMSectionsWithExecutableSections (ObjectFile *exec_objfile, ObjectFile *dsym_objfile)
+{
+ // We need both the executable and the dSYM to live off of the
+ // same section lists. So we take all of the sections from the
+ // executable, and replace them in the dSYM. This allows section
+ // offset addresses that come from the dSYM to automatically
+ // get updated as images (shared libraries) get loaded and
+ // unloaded.
+ SectionList *exec_section_list = exec_objfile->GetSectionList();
+ SectionList *dsym_section_list = dsym_objfile->GetSectionList();
+ if (exec_section_list && dsym_section_list)
+ {
+ const uint32_t num_exec_sections = dsym_section_list->GetSize();
+ uint32_t exec_sect_idx;
+ for (exec_sect_idx = 0; exec_sect_idx < num_exec_sections; ++exec_sect_idx)
+ {
+ SectionSP exec_sect_sp(exec_section_list->GetSectionAtIndex(exec_sect_idx));
+ if (exec_sect_sp.get())
+ {
+ // Try and replace any sections that exist in both the executable
+ // and in the dSYM with those from the executable. If we fail to
+ // replace the one in the dSYM, then add the executable section to
+ // the dSYM.
+ if (dsym_section_list->ReplaceSection(exec_sect_sp->GetID(), exec_sect_sp, 0) == false)
+ dsym_section_list->AddSection(exec_sect_sp);
+ }
+ }
+ }
+}
+
+void
+SymbolVendorMacOSX::Initialize()
+{
+ PluginManager::RegisterPlugin (GetPluginNameStatic(),
+ GetPluginDescriptionStatic(),
+ CreateInstance);
+}
+
+void
+SymbolVendorMacOSX::Terminate()
+{
+ PluginManager::UnregisterPlugin (CreateInstance);
+}
+
+
+const char *
+SymbolVendorMacOSX::GetPluginNameStatic()
+{
+ return "symbol-vendor.macosx";
+}
+
+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(Module* module)
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__,
+ "SymbolVendorMacOSX::CreateInstance (module = %s/%s)",
+ module->GetFileSpec().GetDirectory().AsCString(),
+ module->GetFileSpec().GetFilename().AsCString());
+ SymbolVendorMacOSX* symbol_vendor = new SymbolVendorMacOSX(module);
+ if (symbol_vendor)
+ {
+ char path[PATH_MAX];
+ path[0] = '\0';
+
+ // Try and locate the dSYM file on Mac OS X
+ ObjectFile * obj_file = module->GetObjectFile();
+ if (obj_file)
+ {
+ Timer scoped_timer2 ("SymbolVendorMacOSX::CreateInstance () locate dSYM",
+ "SymbolVendorMacOSX::CreateInstance (module = %s/%s) locate dSYM",
+ module->GetFileSpec().GetDirectory().AsCString(),
+ module->GetFileSpec().GetFilename().AsCString());
+
+ FileSpec dsym_fspec;
+ std::auto_ptr<ObjectFile> dsym_objfile_ap;
+ const FileSpec &file_spec = obj_file->GetFileSpec();
+ if (file_spec)
+ {
+ dsym_fspec = Symbols::LocateExecutableSymbolFile (&file_spec, &module->GetArchitecture(), &module->GetUUID());
+
+ if (dsym_fspec)
+ {
+ dsym_objfile_ap.reset(ObjectFile::FindPlugin(module, &dsym_fspec, 0, dsym_fspec.GetByteSize()));
+ if (UUIDsMatch(module, dsym_objfile_ap.get()))
+ {
+ ReplaceDSYMSectionsWithExecutableSections (obj_file, dsym_objfile_ap.get());
+ symbol_vendor->AddSymbolFileRepresendation(dsym_objfile_ap.release());
+ 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), and executable with
+ // a dSYM that has a UUID that doesn't match, or it is a dSYM file itself.
+ symbol_vendor->AddSymbolFileRepresendation(obj_file);
+ }
+ }
+ return symbol_vendor;
+}
+
+
+
+//------------------------------------------------------------------
+// PluginInterface protocol
+//------------------------------------------------------------------
+const char *
+SymbolVendorMacOSX::GetPluginName()
+{
+ return "SymbolVendorMacOSX";
+}
+
+const char *
+SymbolVendorMacOSX::GetShortPluginName()
+{
+ return GetPluginNameStatic();
+}
+
+uint32_t
+SymbolVendorMacOSX::GetPluginVersion()
+{
+ return 1;
+}
+
+void
+SymbolVendorMacOSX::GetPluginCommandHelp (const char *command, Stream *strm)
+{
+}
+
+Error
+SymbolVendorMacOSX::ExecutePluginCommand (Args &command, Stream *strm)
+{
+ Error error;
+ error.SetErrorString("No plug-in command are currently supported.");
+ return error;
+}
+
+Log *
+SymbolVendorMacOSX::EnablePluginLogging (Stream *strm, Args &command)
+{
+ return NULL;
+}
+
OpenPOWER on IntegriCloud