1 //===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "SymbolVendorELF.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Host/Host.h"
18 #include "lldb/Symbol/LocateSymbolFile.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Utility/StreamString.h"
22 #include "lldb/Utility/Timer.h"
25 using namespace lldb_private;
27 // SymbolVendorELF constructor
28 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
29 : SymbolVendor(module_sp) {}
32 SymbolVendorELF::~SymbolVendorELF() {}
34 void SymbolVendorELF::Initialize() {
35 PluginManager::RegisterPlugin(GetPluginNameStatic(),
36 GetPluginDescriptionStatic(), CreateInstance);
39 void SymbolVendorELF::Terminate() {
40 PluginManager::UnregisterPlugin(CreateInstance);
43 lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() {
44 static ConstString g_name("ELF");
48 const char *SymbolVendorELF::GetPluginDescriptionStatic() {
49 return "Symbol vendor for ELF that looks for dSYM files that match "
55 // Platforms can register a callback to use when creating symbol vendors to
56 // allow for complex debug information file setups, and to also allow for
57 // finding separate debug information files.
59 SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
60 lldb_private::Stream *feedback_strm) {
64 ObjectFile *obj_file = module_sp->GetObjectFile();
68 static ConstString obj_file_elf("elf");
69 ConstString obj_name = obj_file->GetPluginName();
70 if (obj_name != obj_file_elf)
73 lldb_private::UUID uuid = obj_file->GetUUID();
77 // Get the .gnu_debuglink file (if specified).
78 FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
80 // If the module specified a filespec, use it first.
81 FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
82 if (debug_symbol_fspec)
83 file_spec_list.Insert(0, debug_symbol_fspec);
85 // If we have no debug symbol files, then nothing to do.
86 if (file_spec_list.IsEmpty())
89 static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
90 Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
91 module_sp->GetFileSpec().GetPath().c_str());
93 for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
94 ModuleSpec module_spec;
95 const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
97 module_spec.GetFileSpec() = obj_file->GetFileSpec();
98 FileSystem::Instance().Resolve(module_spec.GetFileSpec());
99 module_spec.GetSymbolFileSpec() = fspec;
100 module_spec.GetUUID() = uuid;
101 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
102 FileSpec dsym_fspec =
103 Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
105 DataBufferSP dsym_file_data_sp;
106 lldb::offset_t dsym_file_data_offset = 0;
107 ObjectFileSP dsym_objfile_sp =
108 ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
109 FileSystem::Instance().GetByteSize(dsym_fspec),
110 dsym_file_data_sp, dsym_file_data_offset);
111 if (dsym_objfile_sp) {
112 // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
113 // be able to figure this out consistently as the symbol file may not
114 // have stripped the code sections, etc.
115 dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
117 SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
119 // Get the module unified section list and add our debug sections to
121 SectionList *module_section_list = module_sp->GetSectionList();
122 SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
124 static const SectionType g_sections[] = {
125 eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
126 eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
127 eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
128 eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc,
129 eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames,
130 eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
131 eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets,
132 eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
134 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
136 SectionType section_type = g_sections[idx];
137 SectionSP section_sp(
138 objfile_section_list->FindSectionByType(section_type, true));
140 SectionSP module_section_sp(
141 module_section_list->FindSectionByType(section_type, true));
142 if (module_section_sp)
143 module_section_list->ReplaceSection(module_section_sp->GetID(),
146 module_section_list->AddSection(section_sp);
150 symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
151 return symbol_vendor;
159 // PluginInterface protocol
160 ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); }
162 uint32_t SymbolVendorELF::GetPluginVersion() { return 1; }