diff options
Diffstat (limited to 'source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp')
-rw-r--r-- | source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp new file mode 100644 index 0000000..6500aab --- /dev/null +++ b/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -0,0 +1,199 @@ +//===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolVendorELF.h" + +//#include <libxml/parser.h> +// #include <libxml/tree.h> +#include <string.h> + +// #include <AvailabilityMacros.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/Symbol/ObjectFile.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// SymbolVendorELF constructor +//---------------------------------------------------------------------- +SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) : + SymbolVendor (module_sp) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SymbolVendorELF::~SymbolVendorELF() +{ +} + +void +SymbolVendorELF::Initialize() +{ + PluginManager::RegisterPlugin (GetPluginNameStatic(), + GetPluginDescriptionStatic(), + CreateInstance); +} + +void +SymbolVendorELF::Terminate() +{ + PluginManager::UnregisterPlugin (CreateInstance); +} + + +lldb_private::ConstString +SymbolVendorELF::GetPluginNameStatic() +{ + static ConstString g_name("ELF"); + return g_name; +} + +const char * +SymbolVendorELF::GetPluginDescriptionStatic() +{ + return "Symbol vendor for ELF 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* +SymbolVendorELF::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_elf("elf"); + ConstString obj_name = obj_file->GetPluginName(); + if (obj_name != obj_file_elf) + return NULL; + + lldb_private::UUID uuid; + if (!obj_file->GetUUID (&uuid)) + return NULL; + + // Get the .gnu_debuglink file (if specified). + FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths(); + + // If the module specified a filespec, use it first. + FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec()); + if (debug_symbol_fspec) + file_spec_list.Insert (0, debug_symbol_fspec); + + // If we have no debug symbol files, then nothing to do. + if (file_spec_list.IsEmpty()) + return NULL; + + Timer scoped_timer (__PRETTY_FUNCTION__, + "SymbolVendorELF::CreateInstance (module = %s)", + module_sp->GetFileSpec().GetPath().c_str()); + + for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) + { + ModuleSpec module_spec; + const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx); + + module_spec.GetFileSpec() = obj_file->GetFileSpec(); + module_spec.GetFileSpec().ResolvePath(); + module_spec.GetSymbolFileSpec() = fspec; + module_spec.GetUUID() = uuid; + FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec); + if (dsym_fspec) + { + DataBufferSP dsym_file_data_sp; + lldb::offset_t dsym_file_data_offset = 0; + ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset); + if (dsym_objfile_sp) + { + // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able + // to figure this out consistently as the symbol file may not have stripped the + // code sections, etc. + dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo); + + SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp); + if (symbol_vendor) + { + // Get the module unified section list and add our debug sections to that. + SectionList *module_section_list = module_sp->GetSectionList(); + SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); + + static const SectionType g_sections[] = + { + eSectionTypeDWARFDebugAranges, + eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugAbbrev, + eSectionTypeDWARFDebugFrame, + eSectionTypeDWARFDebugLine, + eSectionTypeDWARFDebugStr, + eSectionTypeDWARFDebugLoc, + eSectionTypeDWARFDebugMacInfo, + eSectionTypeDWARFDebugPubNames, + eSectionTypeDWARFDebugPubTypes, + eSectionTypeDWARFDebugRanges, + eSectionTypeELFSymbolTable, + }; + for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx) + { + SectionType section_type = g_sections[idx]; + SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true)); + if (section_sp) + { + SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true)); + if (module_section_sp) + module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp); + else + module_section_list->AddSection (section_sp); + } + } + + symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp); + return symbol_vendor; + } + } + } + } + return NULL; +} + +//------------------------------------------------------------------ +// PluginInterface protocol +//------------------------------------------------------------------ +ConstString +SymbolVendorELF::GetPluginName() +{ + return GetPluginNameStatic(); +} + +uint32_t +SymbolVendorELF::GetPluginVersion() +{ + return 1; +} + |