//===-- 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; }