LLDB  mainline
SymbolVendorELF.cpp
Go to the documentation of this file.
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 "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
16 #include "lldb/Core/Section.h"
17 #include "lldb/Host/Host.h"
19 #include "lldb/Symbol/ObjectFile.h"
20 #include "lldb/Target/Target.h"
22 #include "lldb/Utility/Timer.h"
23 
24 using namespace lldb;
25 using namespace lldb_private;
26 
27 // SymbolVendorELF constructor
28 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp)
29  : SymbolVendor(module_sp) {}
30 
31 // Destructor
33 
35  PluginManager::RegisterPlugin(GetPluginNameStatic(),
37 }
38 
40  PluginManager::UnregisterPlugin(CreateInstance);
41 }
42 
44  static ConstString g_name("ELF");
45  return g_name;
46 }
47 
49  return "Symbol vendor for ELF that looks for dSYM files that match "
50  "executables.";
51 }
52 
53 // CreateInstance
54 //
55 // Platforms can register a callback to use when creating symbol vendors to
56 // allow for complex debug information file setups, and to also allow for
57 // finding separate debug information files.
59 SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp,
60  lldb_private::Stream *feedback_strm) {
61  if (!module_sp)
62  return NULL;
63 
64  ObjectFile *obj_file = module_sp->GetObjectFile();
65  if (!obj_file)
66  return NULL;
67 
68  static ConstString obj_file_elf("elf");
69  ConstString obj_name = obj_file->GetPluginName();
70  if (obj_name != obj_file_elf)
71  return NULL;
72 
73  lldb_private::UUID uuid = obj_file->GetUUID();
74  if (!uuid)
75  return NULL;
76 
77  // Get the .gnu_debuglink file (if specified).
78  FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
79 
80  // If the module specified a filespec, use it first.
81  FileSpec debug_symbol_fspec(module_sp->GetSymbolFileFileSpec());
82  if (debug_symbol_fspec)
83  file_spec_list.Insert(0, debug_symbol_fspec);
84 
85  // If we have no debug symbol files, then nothing to do.
86  if (file_spec_list.IsEmpty())
87  return NULL;
88 
89  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
90  Timer scoped_timer(func_cat, "SymbolVendorELF::CreateInstance (module = %s)",
91  module_sp->GetFileSpec().GetPath().c_str());
92 
93  for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx) {
94  ModuleSpec module_spec;
95  const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx);
96 
97  module_spec.GetFileSpec() = obj_file->GetFileSpec();
98  FileSystem::Instance().Resolve(module_spec.GetFileSpec());
99  module_spec.GetSymbolFileSpec() = fspec;
100  module_spec.GetUUID() = uuid;
101  FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths();
102  FileSpec dsym_fspec =
103  Symbols::LocateExecutableSymbolFile(module_spec, search_paths);
104  if (dsym_fspec) {
105  DataBufferSP dsym_file_data_sp;
106  lldb::offset_t dsym_file_data_offset = 0;
107  ObjectFileSP dsym_objfile_sp =
108  ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0,
109  FileSystem::Instance().GetByteSize(dsym_fspec),
110  dsym_file_data_sp, dsym_file_data_offset);
111  if (dsym_objfile_sp) {
112  // This objfile is for debugging purposes. Sadly, ObjectFileELF won't
113  // be able to figure this out consistently as the symbol file may not
114  // have stripped the code sections, etc.
115  dsym_objfile_sp->SetType(ObjectFile::eTypeDebugInfo);
116 
117  SymbolVendorELF *symbol_vendor = new SymbolVendorELF(module_sp);
118  if (symbol_vendor) {
119  // Get the module unified section list and add our debug sections to
120  // that.
121  SectionList *module_section_list = module_sp->GetSectionList();
122  SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
123 
124  static const SectionType g_sections[] = {
133  };
134  for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]);
135  ++idx) {
136  SectionType section_type = g_sections[idx];
137  SectionSP section_sp(
138  objfile_section_list->FindSectionByType(section_type, true));
139  if (section_sp) {
140  SectionSP module_section_sp(
141  module_section_list->FindSectionByType(section_type, true));
142  if (module_section_sp)
143  module_section_list->ReplaceSection(module_section_sp->GetID(),
144  section_sp);
145  else
146  module_section_list->AddSection(section_sp);
147  }
148  }
149 
150  symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
151  return symbol_vendor;
152  }
153  }
154  }
155  }
156  return NULL;
157 }
158 
159 // PluginInterface protocol
161 
bool ReplaceSection(lldb::user_id_t sect_id, const lldb::SectionSP &section_sp, uint32_t depth=UINT32_MAX)
Definition: Section.cpp:468
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
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:269
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:55
A timer class that simplifies common timing metrics.
Definition: Timer.h:23
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:545
SymbolVendorELF(const lldb::ModuleSP &module_sp)
static const char * GetPluginDescriptionStatic()
void AddSymbolFileRepresentation(const lldb::ObjectFileSP &objfile_sp)
uint64_t offset_t
Definition: lldb-types.h:87
static void Initialize()
virtual lldb_private::FileSpecList GetDebugSymbolFilePaths()
Gets the symbol file spec list for this object file.
Definition: ObjectFile.h:376
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:38
FileSpec & GetSymbolFileSpec()
Definition: ModuleSpec.h:99
virtual UUID GetUUID()=0
Gets the UUID for this object file.
Definition: SBAddress.h:15
size_t AddSection(const lldb::SectionSP &section_sp)
Definition: Section.cpp:428
virtual ConstString GetPluginName()=0