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 <cstring> |
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/ObjectFile.h" |
20 | #include "lldb/Target/Target.h" |
21 | #include "lldb/Utility/StreamString.h" |
22 | #include "lldb/Utility/Timer.h" |
23 | |
24 | using namespace lldb; |
25 | using namespace lldb_private; |
26 | |
27 | LLDB_PLUGIN_DEFINE(SymbolVendorELF) |
28 | |
29 | // SymbolVendorELF constructor |
30 | SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) |
31 | : SymbolVendor(module_sp) {} |
32 | |
33 | void SymbolVendorELF::Initialize() { |
34 | PluginManager::RegisterPlugin(name: GetPluginNameStatic(), |
35 | description: GetPluginDescriptionStatic(), create_callback: CreateInstance); |
36 | } |
37 | |
38 | void SymbolVendorELF::Terminate() { |
39 | PluginManager::UnregisterPlugin(create_callback: CreateInstance); |
40 | } |
41 | |
42 | llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() { |
43 | return "Symbol vendor for ELF that looks for dSYM files that match " |
44 | "executables." ; |
45 | } |
46 | |
47 | // CreateInstance |
48 | // |
49 | // Platforms can register a callback to use when creating symbol vendors to |
50 | // allow for complex debug information file setups, and to also allow for |
51 | // finding separate debug information files. |
52 | SymbolVendor * |
53 | SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, |
54 | lldb_private::Stream *feedback_strm) { |
55 | if (!module_sp) |
56 | return nullptr; |
57 | |
58 | ObjectFileELF *obj_file = |
59 | llvm::dyn_cast_or_null<ObjectFileELF>(Val: module_sp->GetObjectFile()); |
60 | if (!obj_file) |
61 | return nullptr; |
62 | |
63 | lldb_private::UUID uuid = obj_file->GetUUID(); |
64 | if (!uuid) |
65 | return nullptr; |
66 | |
67 | // If the main object file already contains debug info, then we are done. |
68 | if (obj_file->GetSectionList()->FindSectionByType( |
69 | sect_type: lldb::eSectionTypeDWARFDebugInfo, check_children: true)) |
70 | return nullptr; |
71 | |
72 | // If the module specified a filespec, use that. |
73 | FileSpec fspec = module_sp->GetSymbolFileFileSpec(); |
74 | // Otherwise, try gnu_debuglink, if one exists. |
75 | if (!fspec) |
76 | fspec = obj_file->GetDebugLink().value_or(u: FileSpec()); |
77 | |
78 | LLDB_SCOPED_TIMERF("SymbolVendorELF::CreateInstance (module = %s)" , |
79 | module_sp->GetFileSpec().GetPath().c_str()); |
80 | |
81 | ModuleSpec module_spec; |
82 | |
83 | module_spec.GetFileSpec() = obj_file->GetFileSpec(); |
84 | FileSystem::Instance().Resolve(file_spec&: module_spec.GetFileSpec()); |
85 | module_spec.GetSymbolFileSpec() = fspec; |
86 | module_spec.GetUUID() = uuid; |
87 | FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); |
88 | FileSpec dsym_fspec = |
89 | PluginManager::LocateExecutableSymbolFile(module_spec, default_search_paths: search_paths); |
90 | if (!dsym_fspec) |
91 | return nullptr; |
92 | |
93 | DataBufferSP dsym_file_data_sp; |
94 | lldb::offset_t dsym_file_data_offset = 0; |
95 | ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin( |
96 | module_sp, file_spec: &dsym_fspec, file_offset: 0, file_size: FileSystem::Instance().GetByteSize(file_spec: dsym_fspec), |
97 | data_sp&: dsym_file_data_sp, data_offset&: dsym_file_data_offset); |
98 | if (!dsym_objfile_sp) |
99 | return nullptr; |
100 | |
101 | // This objfile is for debugging purposes. Sadly, ObjectFileELF won't |
102 | // be able to figure this out consistently as the symbol file may not |
103 | // have stripped the code sections, etc. |
104 | dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo); |
105 | |
106 | SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp); |
107 | |
108 | // Get the module unified section list and add our debug sections to |
109 | // that. |
110 | SectionList *module_section_list = module_sp->GetSectionList(); |
111 | SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); |
112 | |
113 | if (!module_section_list || !objfile_section_list) |
114 | return nullptr; |
115 | |
116 | static const SectionType g_sections[] = { |
117 | eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, |
118 | eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, |
119 | eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, |
120 | eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr, |
121 | eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists, |
122 | eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro, |
123 | eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames, |
124 | eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, |
125 | eSectionTypeDWARFDebugRngLists, eSectionTypeDWARFDebugStr, |
126 | eSectionTypeDWARFDebugStrOffsets, eSectionTypeDWARFDebugTypes, |
127 | eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink, |
128 | }; |
129 | for (SectionType section_type : g_sections) { |
130 | if (SectionSP section_sp = |
131 | objfile_section_list->FindSectionByType(sect_type: section_type, check_children: true)) { |
132 | if (SectionSP module_section_sp = |
133 | module_section_list->FindSectionByType(sect_type: section_type, check_children: true)) |
134 | module_section_list->ReplaceSection(sect_id: module_section_sp->GetID(), |
135 | section_sp); |
136 | else |
137 | module_section_list->AddSection(section_sp); |
138 | } |
139 | } |
140 | |
141 | symbol_vendor->AddSymbolFileRepresentation(objfile_sp: dsym_objfile_sp); |
142 | return symbol_vendor; |
143 | } |
144 | |