]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / SymbolVendor / ELF / SymbolVendorELF.cpp
1 //===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===//
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 // SymbolVendorELF constructor
29 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
30     : SymbolVendor(module_sp) {}
31
32 // Destructor
33 SymbolVendorELF::~SymbolVendorELF() {}
34
35 void SymbolVendorELF::Initialize() {
36   PluginManager::RegisterPlugin(GetPluginNameStatic(),
37                                 GetPluginDescriptionStatic(), CreateInstance);
38 }
39
40 void SymbolVendorELF::Terminate() {
41   PluginManager::UnregisterPlugin(CreateInstance);
42 }
43
44 lldb_private::ConstString SymbolVendorELF::GetPluginNameStatic() {
45   static ConstString g_name("ELF");
46   return g_name;
47 }
48
49 const char *SymbolVendorELF::GetPluginDescriptionStatic() {
50   return "Symbol vendor for ELF that looks for dSYM files that match "
51          "executables.";
52 }
53
54 // CreateInstance
55 //
56 // Platforms can register a callback to use when creating symbol vendors to
57 // allow for complex debug information file setups, and to also allow for
58 // finding separate debug information files.
59 SymbolVendor *
60 SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
61                                 lldb_private::Stream *feedback_strm) {
62   if (!module_sp)
63     return nullptr;
64
65   ObjectFileELF *obj_file =
66       llvm::dyn_cast_or_null<ObjectFileELF>(module_sp->GetObjectFile());
67   if (!obj_file)
68     return nullptr;
69
70   lldb_private::UUID uuid = obj_file->GetUUID();
71   if (!uuid)
72     return nullptr;
73
74   // If the main object file already contains debug info, then we are done.
75   if (obj_file->GetSectionList()->FindSectionByType(
76           lldb::eSectionTypeDWARFDebugInfo, true))
77     return nullptr;
78
79   // If the module specified a filespec, use that.
80   FileSpec fspec = module_sp->GetSymbolFileFileSpec();
81   // Otherwise, try gnu_debuglink, if one exists.
82   if (!fspec)
83     fspec = obj_file->GetDebugLink().getValueOr(FileSpec());
84
85   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
86   Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
87                      module_sp->GetFileSpec().GetPath().c_str());
88
89   ModuleSpec module_spec;
90
91   module_spec.GetFileSpec() = obj_file->GetFileSpec();
92   FileSystem::Instance().Resolve(module_spec.GetFileSpec());
93   module_spec.GetSymbolFileSpec() = fspec;
94   module_spec.GetUUID() = uuid;
95   FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
96   FileSpec dsym_fspec =
97       Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
98   if (!dsym_fspec)
99     return nullptr;
100
101   DataBufferSP dsym_file_data_sp;
102   lldb::offset_t dsym_file_data_offset = 0;
103   ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(
104       module_sp, &dsym_fspec, 0, FileSystem::Instance().GetByteSize(dsym_fspec),
105       dsym_file_data_sp, dsym_file_data_offset);
106   if (!dsym_objfile_sp)
107     return nullptr;
108
109   // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
110   // be able to figure this out consistently as the symbol file may not
111   // have stripped the code sections, etc.
112   dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
113
114   SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
115
116   // Get the module unified section list and add our debug sections to
117   // that.
118   SectionList *module_section_list = module_sp->GetSectionList();
119   SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
120
121   static const SectionType g_sections[] = {
122       eSectionTypeDWARFDebugAbbrev,     eSectionTypeDWARFDebugAddr,
123       eSectionTypeDWARFDebugAranges,    eSectionTypeDWARFDebugCuIndex,
124       eSectionTypeDWARFDebugFrame,      eSectionTypeDWARFDebugInfo,
125       eSectionTypeDWARFDebugLine,       eSectionTypeDWARFDebugLineStr,
126       eSectionTypeDWARFDebugLoc,        eSectionTypeDWARFDebugLocLists,
127       eSectionTypeDWARFDebugMacInfo,    eSectionTypeDWARFDebugMacro,
128       eSectionTypeDWARFDebugNames,      eSectionTypeDWARFDebugPubNames,
129       eSectionTypeDWARFDebugPubTypes,   eSectionTypeDWARFDebugRanges,
130       eSectionTypeDWARFDebugRngLists,   eSectionTypeDWARFDebugStr,
131       eSectionTypeDWARFDebugStrOffsets, eSectionTypeDWARFDebugTypes,
132       eSectionTypeELFSymbolTable,       eSectionTypeDWARFGNUDebugAltLink,
133   };
134   for (SectionType section_type : g_sections) {
135     if (SectionSP section_sp =
136             objfile_section_list->FindSectionByType(section_type, true)) {
137       if (SectionSP module_section_sp =
138               module_section_list->FindSectionByType(section_type, true))
139         module_section_list->ReplaceSection(module_section_sp->GetID(),
140                                             section_sp);
141       else
142         module_section_list->AddSection(section_sp);
143     }
144   }
145
146   symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
147   return symbol_vendor;
148 }
149
150 // PluginInterface protocol
151 ConstString SymbolVendorELF::GetPluginName() { return GetPluginNameStatic(); }
152
153 uint32_t SymbolVendorELF::GetPluginVersion() { return 1; }