SymbolVendorELF.cpp revision 269024
1//===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "SymbolVendorELF.h" 11 12#include <string.h> 13 14#include "lldb/Core/Module.h" 15#include "lldb/Core/ModuleSpec.h" 16#include "lldb/Core/PluginManager.h" 17#include "lldb/Core/Section.h" 18#include "lldb/Core/StreamString.h" 19#include "lldb/Core/Timer.h" 20#include "lldb/Host/Host.h" 21#include "lldb/Host/Symbols.h" 22#include "lldb/Symbol/ObjectFile.h" 23 24using namespace lldb; 25using namespace lldb_private; 26 27//---------------------------------------------------------------------- 28// SymbolVendorELF constructor 29//---------------------------------------------------------------------- 30SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) : 31 SymbolVendor (module_sp) 32{ 33} 34 35//---------------------------------------------------------------------- 36// Destructor 37//---------------------------------------------------------------------- 38SymbolVendorELF::~SymbolVendorELF() 39{ 40} 41 42void 43SymbolVendorELF::Initialize() 44{ 45 PluginManager::RegisterPlugin (GetPluginNameStatic(), 46 GetPluginDescriptionStatic(), 47 CreateInstance); 48} 49 50void 51SymbolVendorELF::Terminate() 52{ 53 PluginManager::UnregisterPlugin (CreateInstance); 54} 55 56 57lldb_private::ConstString 58SymbolVendorELF::GetPluginNameStatic() 59{ 60 static ConstString g_name("ELF"); 61 return g_name; 62} 63 64const char * 65SymbolVendorELF::GetPluginDescriptionStatic() 66{ 67 return "Symbol vendor for ELF that looks for dSYM files that match executables."; 68} 69 70 71 72//---------------------------------------------------------------------- 73// CreateInstance 74// 75// Platforms can register a callback to use when creating symbol 76// vendors to allow for complex debug information file setups, and to 77// also allow for finding separate debug information files. 78//---------------------------------------------------------------------- 79SymbolVendor* 80SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm) 81{ 82 if (!module_sp) 83 return NULL; 84 85 ObjectFile *obj_file = module_sp->GetObjectFile(); 86 if (!obj_file) 87 return NULL; 88 89 static ConstString obj_file_elf("elf"); 90 ConstString obj_name = obj_file->GetPluginName(); 91 if (obj_name != obj_file_elf) 92 return NULL; 93 94 lldb_private::UUID uuid; 95 if (!obj_file->GetUUID (&uuid)) 96 return NULL; 97 98 // Get the .gnu_debuglink file (if specified). 99 FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths(); 100 101 // If the module specified a filespec, use it first. 102 FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec()); 103 if (debug_symbol_fspec) 104 file_spec_list.Insert (0, debug_symbol_fspec); 105 106 // If we have no debug symbol files, then nothing to do. 107 if (file_spec_list.IsEmpty()) 108 return NULL; 109 110 Timer scoped_timer (__PRETTY_FUNCTION__, 111 "SymbolVendorELF::CreateInstance (module = %s)", 112 module_sp->GetFileSpec().GetPath().c_str()); 113 114 for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) 115 { 116 ModuleSpec module_spec; 117 const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx); 118 119 module_spec.GetFileSpec() = obj_file->GetFileSpec(); 120 module_spec.GetFileSpec().ResolvePath(); 121 module_spec.GetSymbolFileSpec() = fspec; 122 module_spec.GetUUID() = uuid; 123 FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec); 124 if (dsym_fspec) 125 { 126 DataBufferSP dsym_file_data_sp; 127 lldb::offset_t dsym_file_data_offset = 0; 128 ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset); 129 if (dsym_objfile_sp) 130 { 131 // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able 132 // to figure this out consistently as the symbol file may not have stripped the 133 // code sections, etc. 134 dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo); 135 136 SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp); 137 if (symbol_vendor) 138 { 139 // Get the module unified section list and add our debug sections to that. 140 SectionList *module_section_list = module_sp->GetSectionList(); 141 SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); 142 143 static const SectionType g_sections[] = 144 { 145 eSectionTypeDWARFDebugAranges, 146 eSectionTypeDWARFDebugInfo, 147 eSectionTypeDWARFDebugAbbrev, 148 eSectionTypeDWARFDebugFrame, 149 eSectionTypeDWARFDebugLine, 150 eSectionTypeDWARFDebugStr, 151 eSectionTypeDWARFDebugLoc, 152 eSectionTypeDWARFDebugMacInfo, 153 eSectionTypeDWARFDebugPubNames, 154 eSectionTypeDWARFDebugPubTypes, 155 eSectionTypeDWARFDebugRanges, 156 eSectionTypeELFSymbolTable, 157 }; 158 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx) 159 { 160 SectionType section_type = g_sections[idx]; 161 SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true)); 162 if (section_sp) 163 { 164 SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true)); 165 if (module_section_sp) 166 module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp); 167 else 168 module_section_list->AddSection (section_sp); 169 } 170 } 171 172 symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp); 173 return symbol_vendor; 174 } 175 } 176 } 177 } 178 return NULL; 179} 180 181//------------------------------------------------------------------ 182// PluginInterface protocol 183//------------------------------------------------------------------ 184ConstString 185SymbolVendorELF::GetPluginName() 186{ 187 return GetPluginNameStatic(); 188} 189 190uint32_t 191SymbolVendorELF::GetPluginVersion() 192{ 193 return 1; 194} 195 196