]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / Plugins / SymbolVendor / ELF / SymbolVendorELF.cpp
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 //----------------------------------------------------------------------
30 SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
31     SymbolVendor (module_sp)
32 {
33 }
34
35 //----------------------------------------------------------------------
36 // Destructor
37 //----------------------------------------------------------------------
38 SymbolVendorELF::~SymbolVendorELF()
39 {
40 }
41
42 void
43 SymbolVendorELF::Initialize()
44 {
45     PluginManager::RegisterPlugin (GetPluginNameStatic(),
46                                    GetPluginDescriptionStatic(),
47                                    CreateInstance);
48 }
49
50 void
51 SymbolVendorELF::Terminate()
52 {
53     PluginManager::UnregisterPlugin (CreateInstance);
54 }
55
56
57 lldb_private::ConstString
58 SymbolVendorELF::GetPluginNameStatic()
59 {
60     static ConstString g_name("ELF");
61     return g_name;
62 }
63
64 const char *
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*
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
185 SymbolVendorELF::GetPluginName()
186 {
187     return GetPluginNameStatic();
188 }
189
190 uint32_t
191 SymbolVendorELF::GetPluginVersion()
192 {
193     return 1;
194 }
195