1254721Semaste//===-- SymbolVendorELF.cpp ----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "SymbolVendorELF.h"
11254721Semaste
12254721Semaste#include <string.h>
13254721Semaste
14254721Semaste#include "lldb/Core/Module.h"
15254721Semaste#include "lldb/Core/ModuleSpec.h"
16254721Semaste#include "lldb/Core/PluginManager.h"
17254721Semaste#include "lldb/Core/Section.h"
18254721Semaste#include "lldb/Core/StreamString.h"
19254721Semaste#include "lldb/Core/Timer.h"
20254721Semaste#include "lldb/Host/Host.h"
21254721Semaste#include "lldb/Host/Symbols.h"
22254721Semaste#include "lldb/Symbol/ObjectFile.h"
23254721Semaste
24254721Semasteusing namespace lldb;
25254721Semasteusing namespace lldb_private;
26254721Semaste
27254721Semaste//----------------------------------------------------------------------
28254721Semaste// SymbolVendorELF constructor
29254721Semaste//----------------------------------------------------------------------
30254721SemasteSymbolVendorELF::SymbolVendorELF(const lldb::ModuleSP &module_sp) :
31254721Semaste    SymbolVendor (module_sp)
32254721Semaste{
33254721Semaste}
34254721Semaste
35254721Semaste//----------------------------------------------------------------------
36254721Semaste// Destructor
37254721Semaste//----------------------------------------------------------------------
38254721SemasteSymbolVendorELF::~SymbolVendorELF()
39254721Semaste{
40254721Semaste}
41254721Semaste
42254721Semastevoid
43254721SemasteSymbolVendorELF::Initialize()
44254721Semaste{
45254721Semaste    PluginManager::RegisterPlugin (GetPluginNameStatic(),
46254721Semaste                                   GetPluginDescriptionStatic(),
47254721Semaste                                   CreateInstance);
48254721Semaste}
49254721Semaste
50254721Semastevoid
51254721SemasteSymbolVendorELF::Terminate()
52254721Semaste{
53254721Semaste    PluginManager::UnregisterPlugin (CreateInstance);
54254721Semaste}
55254721Semaste
56254721Semaste
57254721Semastelldb_private::ConstString
58254721SemasteSymbolVendorELF::GetPluginNameStatic()
59254721Semaste{
60254721Semaste    static ConstString g_name("ELF");
61254721Semaste    return g_name;
62254721Semaste}
63254721Semaste
64254721Semasteconst char *
65254721SemasteSymbolVendorELF::GetPluginDescriptionStatic()
66254721Semaste{
67254721Semaste    return "Symbol vendor for ELF that looks for dSYM files that match executables.";
68254721Semaste}
69254721Semaste
70254721Semaste
71254721Semaste
72254721Semaste//----------------------------------------------------------------------
73254721Semaste// CreateInstance
74254721Semaste//
75254721Semaste// Platforms can register a callback to use when creating symbol
76254721Semaste// vendors to allow for complex debug information file setups, and to
77254721Semaste// also allow for finding separate debug information files.
78254721Semaste//----------------------------------------------------------------------
79254721SemasteSymbolVendor*
80254721SemasteSymbolVendorELF::CreateInstance (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm)
81254721Semaste{
82254721Semaste    if (!module_sp)
83254721Semaste        return NULL;
84254721Semaste
85254721Semaste    ObjectFile *obj_file = module_sp->GetObjectFile();
86254721Semaste    if (!obj_file)
87254721Semaste        return NULL;
88254721Semaste
89254721Semaste    static ConstString obj_file_elf("elf");
90254721Semaste    ConstString obj_name = obj_file->GetPluginName();
91254721Semaste    if (obj_name != obj_file_elf)
92254721Semaste        return NULL;
93254721Semaste
94254721Semaste    lldb_private::UUID uuid;
95254721Semaste    if (!obj_file->GetUUID (&uuid))
96254721Semaste        return NULL;
97254721Semaste
98254721Semaste    // Get the .gnu_debuglink file (if specified).
99254721Semaste    FileSpecList file_spec_list = obj_file->GetDebugSymbolFilePaths();
100254721Semaste
101254721Semaste    // If the module specified a filespec, use it first.
102254721Semaste    FileSpec debug_symbol_fspec (module_sp->GetSymbolFileFileSpec());
103254721Semaste    if (debug_symbol_fspec)
104254721Semaste        file_spec_list.Insert (0, debug_symbol_fspec);
105254721Semaste
106254721Semaste    // If we have no debug symbol files, then nothing to do.
107254721Semaste    if (file_spec_list.IsEmpty())
108254721Semaste        return NULL;
109254721Semaste
110254721Semaste    Timer scoped_timer (__PRETTY_FUNCTION__,
111254721Semaste                        "SymbolVendorELF::CreateInstance (module = %s)",
112254721Semaste                        module_sp->GetFileSpec().GetPath().c_str());
113254721Semaste
114254721Semaste    for (size_t idx = 0; idx < file_spec_list.GetSize(); ++idx)
115254721Semaste    {
116254721Semaste        ModuleSpec module_spec;
117254721Semaste        const FileSpec fspec = file_spec_list.GetFileSpecAtIndex (idx);
118254721Semaste
119254721Semaste        module_spec.GetFileSpec() = obj_file->GetFileSpec();
120254721Semaste        module_spec.GetFileSpec().ResolvePath();
121254721Semaste        module_spec.GetSymbolFileSpec() = fspec;
122254721Semaste        module_spec.GetUUID() = uuid;
123254721Semaste        FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile (module_spec);
124254721Semaste        if (dsym_fspec)
125254721Semaste        {
126254721Semaste            DataBufferSP dsym_file_data_sp;
127254721Semaste            lldb::offset_t dsym_file_data_offset = 0;
128254721Semaste            ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
129254721Semaste            if (dsym_objfile_sp)
130254721Semaste            {
131254721Semaste                // This objfile is for debugging purposes. Sadly, ObjectFileELF won't be able
132254721Semaste                // to figure this out consistently as the symbol file may not have stripped the
133254721Semaste                // code sections, etc.
134254721Semaste                dsym_objfile_sp->SetType (ObjectFile::eTypeDebugInfo);
135254721Semaste
136254721Semaste                SymbolVendorELF* symbol_vendor = new SymbolVendorELF(module_sp);
137254721Semaste                if (symbol_vendor)
138254721Semaste                {
139254721Semaste                    // Get the module unified section list and add our debug sections to that.
140254721Semaste                    SectionList *module_section_list = module_sp->GetSectionList();
141254721Semaste                    SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList();
142254721Semaste
143254721Semaste                    static const SectionType g_sections[] =
144254721Semaste                    {
145254721Semaste                        eSectionTypeDWARFDebugAranges,
146254721Semaste                        eSectionTypeDWARFDebugInfo,
147254721Semaste                        eSectionTypeDWARFDebugAbbrev,
148254721Semaste                        eSectionTypeDWARFDebugFrame,
149254721Semaste                        eSectionTypeDWARFDebugLine,
150254721Semaste                        eSectionTypeDWARFDebugStr,
151254721Semaste                        eSectionTypeDWARFDebugLoc,
152254721Semaste                        eSectionTypeDWARFDebugMacInfo,
153254721Semaste                        eSectionTypeDWARFDebugPubNames,
154254721Semaste                        eSectionTypeDWARFDebugPubTypes,
155254721Semaste                        eSectionTypeDWARFDebugRanges,
156254721Semaste                        eSectionTypeELFSymbolTable,
157254721Semaste                    };
158254721Semaste                    for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx)
159254721Semaste                    {
160254721Semaste                        SectionType section_type = g_sections[idx];
161254721Semaste                        SectionSP section_sp (objfile_section_list->FindSectionByType (section_type, true));
162254721Semaste                        if (section_sp)
163254721Semaste                        {
164254721Semaste                            SectionSP module_section_sp (module_section_list->FindSectionByType (section_type, true));
165254721Semaste                            if (module_section_sp)
166254721Semaste                                module_section_list->ReplaceSection (module_section_sp->GetID(), section_sp);
167254721Semaste                            else
168254721Semaste                                module_section_list->AddSection (section_sp);
169254721Semaste                        }
170254721Semaste                    }
171254721Semaste
172254721Semaste                    symbol_vendor->AddSymbolFileRepresentation (dsym_objfile_sp);
173254721Semaste                    return symbol_vendor;
174254721Semaste                }
175254721Semaste            }
176254721Semaste        }
177254721Semaste    }
178254721Semaste    return NULL;
179254721Semaste}
180254721Semaste
181254721Semaste//------------------------------------------------------------------
182254721Semaste// PluginInterface protocol
183254721Semaste//------------------------------------------------------------------
184254721SemasteConstString
185254721SemasteSymbolVendorELF::GetPluginName()
186254721Semaste{
187254721Semaste    return GetPluginNameStatic();
188254721Semaste}
189254721Semaste
190254721Semasteuint32_t
191254721SemasteSymbolVendorELF::GetPluginVersion()
192254721Semaste{
193254721Semaste    return 1;
194254721Semaste}
195254721Semaste
196