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