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