xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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