1dda28197Spatrick //===-- SymbolVendorELF.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "SymbolVendorELF.h"
10061da546Spatrick
11be691f3bSpatrick #include <cstring>
12061da546Spatrick
13061da546Spatrick #include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
14061da546Spatrick #include "lldb/Core/Module.h"
15061da546Spatrick #include "lldb/Core/ModuleSpec.h"
16061da546Spatrick #include "lldb/Core/PluginManager.h"
17061da546Spatrick #include "lldb/Core/Section.h"
18061da546Spatrick #include "lldb/Host/Host.h"
19061da546Spatrick #include "lldb/Symbol/LocateSymbolFile.h"
20061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
21061da546Spatrick #include "lldb/Target/Target.h"
22061da546Spatrick #include "lldb/Utility/StreamString.h"
23061da546Spatrick #include "lldb/Utility/Timer.h"
24061da546Spatrick
25061da546Spatrick using namespace lldb;
26061da546Spatrick using namespace lldb_private;
27061da546Spatrick
LLDB_PLUGIN_DEFINE(SymbolVendorELF)28dda28197Spatrick LLDB_PLUGIN_DEFINE(SymbolVendorELF)
29dda28197Spatrick
30061da546Spatrick // SymbolVendorELF constructor
31061da546Spatrick SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
32061da546Spatrick : SymbolVendor(module_sp) {}
33061da546Spatrick
Initialize()34061da546Spatrick void SymbolVendorELF::Initialize() {
35061da546Spatrick PluginManager::RegisterPlugin(GetPluginNameStatic(),
36061da546Spatrick GetPluginDescriptionStatic(), CreateInstance);
37061da546Spatrick }
38061da546Spatrick
Terminate()39061da546Spatrick void SymbolVendorELF::Terminate() {
40061da546Spatrick PluginManager::UnregisterPlugin(CreateInstance);
41061da546Spatrick }
42061da546Spatrick
GetPluginDescriptionStatic()43*f6aab3d8Srobert llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() {
44061da546Spatrick return "Symbol vendor for ELF that looks for dSYM files that match "
45061da546Spatrick "executables.";
46061da546Spatrick }
47061da546Spatrick
48061da546Spatrick // CreateInstance
49061da546Spatrick //
50061da546Spatrick // Platforms can register a callback to use when creating symbol vendors to
51061da546Spatrick // allow for complex debug information file setups, and to also allow for
52061da546Spatrick // finding separate debug information files.
53061da546Spatrick SymbolVendor *
CreateInstance(const lldb::ModuleSP & module_sp,lldb_private::Stream * feedback_strm)54061da546Spatrick SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
55061da546Spatrick lldb_private::Stream *feedback_strm) {
56061da546Spatrick if (!module_sp)
57061da546Spatrick return nullptr;
58061da546Spatrick
59061da546Spatrick ObjectFileELF *obj_file =
60061da546Spatrick llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile());
61061da546Spatrick if (!obj_file)
62061da546Spatrick return nullptr;
63061da546Spatrick
64061da546Spatrick lldb_private::UUID uuid = obj_file->GetUUID();
65061da546Spatrick if (!uuid)
66061da546Spatrick return nullptr;
67061da546Spatrick
68061da546Spatrick // If the main object file already contains debug info, then we are done.
69061da546Spatrick if (obj_file->GetSectionList()->FindSectionByType(
70061da546Spatrick lldb::eSectionTypeDWARFDebugInfo, true))
71061da546Spatrick return nullptr;
72061da546Spatrick
73061da546Spatrick // If the module specified a filespec, use that.
74061da546Spatrick FileSpec fspec = module_sp->GetSymbolFileFileSpec();
75061da546Spatrick // Otherwise, try gnu_debuglink, if one exists.
76061da546Spatrick if (!fspec)
77*f6aab3d8Srobert fspec = obj_file->GetDebugLink().value_or(FileSpec());
78061da546Spatrick
79be691f3bSpatrick LLDB_SCOPED_TIMERF("SymbolVendorELF::CreateInstance (module = %s)",
80061da546Spatrick module_sp->GetFileSpec().GetPath().c_str());
81061da546Spatrick
82061da546Spatrick ModuleSpec module_spec;
83061da546Spatrick
84061da546Spatrick module_spec.GetFileSpec() = obj_file->GetFileSpec();
85061da546Spatrick FileSystem::Instance().Resolve(module_spec.GetFileSpec());
86061da546Spatrick module_spec.GetSymbolFileSpec() = fspec;
87061da546Spatrick module_spec.GetUUID() = uuid;
88061da546Spatrick FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
89061da546Spatrick FileSpec dsym_fspec =
90061da546Spatrick Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
91061da546Spatrick if (!dsym_fspec)
92061da546Spatrick return nullptr;
93061da546Spatrick
94061da546Spatrick DataBufferSP dsym_file_data_sp;
95061da546Spatrick lldb::offset_t dsym_file_data_offset = 0;
96061da546Spatrick ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
97061da546Spatrick module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
98061da546Spatrick dsym_file_data_sp, dsym_file_data_offset);
99061da546Spatrick if (!dsym_objfile_sp)
100061da546Spatrick return nullptr;
101061da546Spatrick
102061da546Spatrick // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
103061da546Spatrick // be able to figure this out consistently as the symbol file may not
104061da546Spatrick // have stripped the code sections, etc.
105061da546Spatrick dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
106061da546Spatrick
107061da546Spatrick SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
108061da546Spatrick
109061da546Spatrick // Get the module unified section list and add our debug sections to
110061da546Spatrick // that.
111061da546Spatrick SectionList *module_section_list = module_sp->GetSectionList();
112061da546Spatrick SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
113061da546Spatrick
114061da546Spatrick static const SectionType g_sections[] = {
115061da546Spatrick eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr,
116061da546Spatrick eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex,
117061da546Spatrick eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo,
118061da546Spatrick eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLineStr,
119061da546Spatrick eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugLocLists,
120061da546Spatrick eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugMacro,
121061da546Spatrick eSectionTypeDWARFDebugNames, eSectionTypeDWARFDebugPubNames,
122061da546Spatrick eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges,
123061da546Spatrick eSectionTypeDWARFDebugRngLists, eSectionTypeDWARFDebugStr,
124061da546Spatrick eSectionTypeDWARFDebugStrOffsets, eSectionTypeDWARFDebugTypes,
125061da546Spatrick eSectionTypeELFSymbolTable, eSectionTypeDWARFGNUDebugAltLink,
126061da546Spatrick };
127061da546Spatrick for (SectionType section_type : g_sections) {
128061da546Spatrick if (SectionSP section_sp =
129061da546Spatrick objfile_section_list->FindSectionByType(section_type, true)) {
130061da546Spatrick if (SectionSP module_section_sp =
131061da546Spatrick module_section_list->FindSectionByType(section_type, true))
132061da546Spatrick module_section_list->ReplaceSection(module_section_sp->GetID(),
133061da546Spatrick section_sp);
134061da546Spatrick else
135061da546Spatrick module_section_list->AddSection(section_sp);
136061da546Spatrick }
137061da546Spatrick }
138061da546Spatrick
139061da546Spatrick symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
140061da546Spatrick return symbol_vendor;
141061da546Spatrick }
142