1 //===-- SymbolVendorELF.cpp -----------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "SymbolVendorELF.h" 10 11 #include <string.h> 12 13 #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" 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/Host/Host.h" 19 #include "lldb/Symbol/LocateSymbolFile.h" 20 #include "lldb/Symbol/ObjectFile.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Utility/StreamString.h" 23 #include "lldb/Utility/Timer.h" 24 25 using namespace lldb; 26 using namespace lldb_private; 27 28 LLDB_PLUGIN_DEFINE(SymbolVendorELF) 29 30 // SymbolVendorELF constructor 31 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) 32 : SymbolVendor(module_sp) {} 33 34 // Destructor 35 SymbolVendorELF::~SymbolVendorELF() {} 36 37 void SymbolVendorELF::Initialize() { 38 PluginManager::RegisterPlugin(GetPluginNameStatic(), 39 GetPluginDescriptionStatic(), CreateInstance); 40 } 41 42 void SymbolVendorELF::Terminate() { 43 PluginManager::UnregisterPlugin(CreateInstance); 44 } 45 46 lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() { 47 static ConstString g_name("ELF"); 48 return g_name; 49 } 50 51 const char *SymbolVendorELF::GetPluginDescriptionStatic() { 52 return "Symbol vendor for ELF that looks for dSYM files that match " 53 "executables."; 54 } 55 56 // CreateInstance 57 // 58 // Platforms can register a callback to use when creating symbol vendors to 59 // allow for complex debug information file setups, and to also allow for 60 // finding separate debug information files. 61 SymbolVendor * 62 SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, 63 lldb_private::Stream *feedback_strm) { 64 if (!module_sp) 65 return nullptr; 66 67 ObjectFileELF *obj_file = 68 llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile()); 69 if (!obj_file) 70 return nullptr; 71 72 lldb_private::UUID uuid = obj_file->GetUUID(); 73 if (!uuid) 74 return nullptr; 75 76 // If the main object file already contains debug info, then we are done. 77 if (obj_file->GetSectionList()->FindSectionByType( 78 lldb::eSectionTypeDWARFDebugInfo, true)) 79 return nullptr; 80 81 // If the module specified a filespec, use that. 82 FileSpec fspec = module_sp->GetSymbolFileFileSpec(); 83 // Otherwise, try gnu_debuglink, if one exists. 84 if (!fspec) 85 fspec = obj_file->GetDebugLink().getValueOr(FileSpec()); 86 87 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); 88 Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)", 89 module_sp->GetFileSpec().GetPath().c_str()); 90 91 ModuleSpec module_spec; 92 93 module_spec.GetFileSpec() = obj_file->GetFileSpec(); 94 FileSystem::Instance().Resolve(module_spec.GetFileSpec()); 95 module_spec.GetSymbolFileSpec() = fspec; 96 module_spec.GetUUID() = uuid; 97 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); 98 FileSpec dsym_fspec = 99 Symbols::LocateExecutableSymbolFile(module_spec, search_paths); 100 if (!dsym_fspec) 101 return nullptr; 102 103 DataBufferSP dsym_file_data_sp; 104 lldb::offset_t dsym_file_data_offset = 0; 105 ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin( 106 module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec), 107 dsym_file_data_sp, dsym_file_data_offset); 108 if (!dsym_objfile_sp) 109 return nullptr; 110 111 // This objfile is for debugging purposes. Sadly, ObjectFileELF won't 112 // be able to figure this out consistently as the symbol file may not 113 // have stripped the code sections, etc. 114 dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo); 115 116 SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp); 117 118 // Get the module unified section list and add our debug sections to 119 // that. 120 SectionList *module_section_list = module_sp->GetSectionList(); 121 SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); 122 123 static const SectionType g_sections[] = { 124 eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, 125 eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, 126 eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, 127 eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr, 128 eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists, 129 eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro, 130 eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames, 131 eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, 132 eSectionTypeDWARFDebugRngLists, eSectionTypeDWARFDebugStr, 133 eSectionTypeDWARFDebugStrOffsets, eSectionTypeDWARFDebugTypes, 134 eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink, 135 }; 136 for (SectionType section_type : g_sections) { 137 if (SectionSP section_sp = 138 objfile_section_list->FindSectionByType(section_type, true)) { 139 if (SectionSP module_section_sp = 140 module_section_list->FindSectionByType(section_type, true)) 141 module_section_list->ReplaceSection(module_section_sp->GetID(), 142 section_sp); 143 else 144 module_section_list->AddSection(section_sp); 145 } 146 } 147 148 symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp); 149 return symbol_vendor; 150 } 151 152 // PluginInterface protocol 153 ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); } 154 155 uint32_t SymbolVendorELF::GetPluginVersion() { return 1; } 156