1 //===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "SymbolVendorELF.h"
11
12 #include <string.h>
13
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/Core/StreamString.h"
19 #include "lldb/Core/Timer.h"
20 #include "lldb/Host/Host.h"
21 #include "lldb/Host/Symbols.h"
22 #include "lldb/Symbol/ObjectFile.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 //----------------------------------------------------------------------
28 // SymbolVendorELF constructor
29 //----------------------------------------------------------------------
SymbolVendorELF(const lldb::ModuleSP & module_sp)30 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
31 SymbolVendor (module_sp)
32 {
33 }
34
35 //----------------------------------------------------------------------
36 // Destructor
37 //----------------------------------------------------------------------
~SymbolVendorELF()38 SymbolVendorELF::~SymbolVendorELF()
39 {
40 }
41
42 void
Initialize()43 SymbolVendorELF::Initialize()
44 {
45 PluginManager::RegisterPlugin (GetPluginNameStatic(),
46 GetPluginDescriptionStatic(),
47 CreateInstance);
48 }
49
50 void
Terminate()51 SymbolVendorELF::Terminate()
52 {
53 PluginManager::UnregisterPlugin (CreateInstance);
54 }
55
56
57 lldb_private::ConstString
GetPluginNameStatic()58 SymbolVendorELF::GetPluginNameStatic()
59 {
60 static ConstString g_name("ELF");
61 return g_name;
62 }
63
64 const char *
GetPluginDescriptionStatic()65 SymbolVendorELF::GetPluginDescriptionStatic()
66 {
67 return "Symbol vendor for ELF that looks for dSYM files that match executables.";
68 }
69
70
71
72 //----------------------------------------------------------------------
73 // CreateInstance
74 //
75 // Platforms can register a callback to use when creating symbol
76 // vendors to allow for complex debug information file setups, and to
77 // also allow for finding separate debug information files.
78 //----------------------------------------------------------------------
79 SymbolVendor*
CreateInstance(const lldb::ModuleSP & module_sp,lldb_private::Stream * feedback_strm)80 SymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
81 {
82 if (!module_sp)
83 return NULL;
84
85 ObjectFile *obj_file = module_sp->GetObjectFile();
86 if (!obj_file)
87 return NULL;
88
89 static ConstString obj_file_elf("elf");
90 ConstString obj_name = obj_file->GetPluginName();
91 if (obj_name != obj_file_elf)
92 return NULL;
93
94 lldb_private::UUID uuid;
95 if (!obj_file->GetUUID (&uuid))
96 return NULL;
97
98 // Get the .gnu_debuglink file (if specified).
99 FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
100
101 // If the module specified a filespec, use it first.
102 FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec());
103 if (debug_symbol_fspec)
104 file_spec_list.Insert (0, debug_symbol_fspec);
105
106 // If we have no debug symbol files, then nothing to do.
107 if (file_spec_list.IsEmpty())
108 return NULL;
109
110 Timer scoped_timer (__PRETTY_FUNCTION__,
111 "SymbolVendorELF::CreateInstance (module = %s)",
112 module_sp->GetFileSpec().GetPath().c_str());
113
114 for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx)
115 {
116 ModuleSpec module_spec;
117 const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx);
118
119 module_spec.GetFileSpec() = obj_file->GetFileSpec();
120 module_spec.GetFileSpec().ResolvePath();
121 module_spec.GetSymbolFileSpec() = fspec;
122 module_spec.GetUUID() = uuid;
123 FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
124 if (dsym_fspec)
125 {
126 DataBufferSP dsym_file_data_sp;
127 lldb::offset_t dsym_file_data_offset = 0;
128 ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
129 if (dsym_objfile_sp)
130 {
131 // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able
132 // to figure this out consistently as the symbol file may not have stripped the
133 // code sections, etc.
134 dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo);
135
136 SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp);
137 if (symbol_vendor)
138 {
139 // Get the module unified section list and add our debug sections to that.
140 SectionList *module_section_list = module_sp->GetSectionList();
141 SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
142
143 static const SectionType g_sections[] =
144 {
145 eSectionTypeDWARFDebugAranges,
146 eSectionTypeDWARFDebugInfo,
147 eSectionTypeDWARFDebugAbbrev,
148 eSectionTypeDWARFDebugFrame,
149 eSectionTypeDWARFDebugLine,
150 eSectionTypeDWARFDebugStr,
151 eSectionTypeDWARFDebugLoc,
152 eSectionTypeDWARFDebugMacInfo,
153 eSectionTypeDWARFDebugPubNames,
154 eSectionTypeDWARFDebugPubTypes,
155 eSectionTypeDWARFDebugRanges,
156 eSectionTypeELFSymbolTable,
157 };
158 for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
159 {
160 SectionType section_type = g_sections[idx];
161 SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true));
162 if (section_sp)
163 {
164 SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true));
165 if (module_section_sp)
166 module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp);
167 else
168 module_section_list->AddSection (section_sp);
169 }
170 }
171
172 symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
173 return symbol_vendor;
174 }
175 }
176 }
177 }
178 return NULL;
179 }
180
181 //------------------------------------------------------------------
182 // PluginInterface protocol
183 //------------------------------------------------------------------
184 ConstString
GetPluginName()185 SymbolVendorELF::GetPluginName()
186 {
187 return GetPluginNameStatic();
188 }
189
190 uint32_t
GetPluginVersion()191 SymbolVendorELF::GetPluginVersion()
192 {
193 return 1;
194 }
195
196