SymbolVendorELF.cpp revision 269024
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
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// SymbolVendorELF constructor
29//----------------------------------------------------------------------
30SymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
31    SymbolVendor (module_sp)
32{
33}
34
35//----------------------------------------------------------------------
36// Destructor
37//----------------------------------------------------------------------
38SymbolVendorELF::~SymbolVendorELF()
39{
40}
41
42void
43SymbolVendorELF::Initialize()
44{
45    PluginManager::RegisterPlugin (GetPluginNameStatic(),
46                                   GetPluginDescriptionStatic(),
47                                   CreateInstance);
48}
49
50void
51SymbolVendorELF::Terminate()
52{
53    PluginManager::UnregisterPlugin (CreateInstance);
54}
55
56
57lldb_private::ConstString
58SymbolVendorELF::GetPluginNameStatic()
59{
60    static ConstString g_name("ELF");
61    return g_name;
62}
63
64const char *
65SymbolVendorELF::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//----------------------------------------------------------------------
79SymbolVendor*
80SymbolVendorELF::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//------------------------------------------------------------------
184ConstString
185SymbolVendorELF::GetPluginName()
186{
187    return GetPluginNameStatic();
188}
189
190uint32_t
191SymbolVendorELF::GetPluginVersion()
192{
193    return 1;
194}
195
196