LLDB  mainline
SymbolVendorELF.cpp
Go to the documentation of this file.
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 
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Host/Host.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Target/Target.h"
23 #include "lldb/Utility/Timer.h"
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
29 
30 // SymbolVendorELF constructor
31 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
32  : SymbolVendor(module_sp) {}
33 
34 // Destructor
36 
38  PluginManager::RegisterPlugin(GetPluginNameStatic(),
39  GetPluginDescriptionStatic(), CreateInstance);
40 }
41 
43  PluginManager::UnregisterPlugin(CreateInstance);
44 }
45 
47  static ConstString g_name("ELF");
48  return g_name;
49 }
50 
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.
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(
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[] = {
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 
bool ReplaceSection(lldb::user_id_t sect_id, const lldb::SectionSP &section_sp, uint32_t depth=UINT32_MAX)
Definition: Section.cpp:447
A class that represents a running process on the host machine.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
virtual FileSpec & GetFileSpec()
Get accessor to the object file specification.
Definition: ObjectFile.h:279
static void Terminate()
static lldb_private::SymbolVendor * CreateInstance(const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
A file utility class.
Definition: FileSpec.h:56
A timer class that simplifies common timing metrics.
Definition: Timer.h:23
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:524
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
static const char * GetPluginDescriptionStatic()
void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp)
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
DWARF .debug_types section.
uint64_t offset_t
Definition: lldb-types.h:87
Generic ELF object file reader.
Definition: ObjectFileELF.h:57
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:607
llvm::Optional< lldb_private::FileSpec > GetDebugLink()
Return the contents of the .gnu_debuglink section, if the object file contains it.
static void Initialize()
lldb_private::ConstString GetPluginName() override
uint32_t GetPluginVersion() override
FileSpec & GetFileSpec()
Definition: ModuleSpec.h:75
~SymbolVendorELF() override
static lldb_private::ConstString GetPluginNameStatic()
A uniqued constant string class.
Definition: ConstString.h:40
Definition: SBAddress.h:15
size_t AddSection(const lldb::SectionSP &section_sp)
Definition: Section.cpp:407