1//===-- ObjectFileELF.h --------------------------------------- -*- 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#ifndef liblldb_ObjectFileELF_h_
11#define liblldb_ObjectFileELF_h_
12
13#include <stdint.h>
14#include <vector>
15
16#include "lldb/lldb-private.h"
17#include "lldb/Host/FileSpec.h"
18#include "lldb/Symbol/ObjectFile.h"
19#include "lldb/Core/UUID.h"
20
21#include "ELFHeader.h"
22
23//------------------------------------------------------------------------------
24/// @class ObjectFileELF
25/// @brief Generic ELF object file reader.
26///
27/// This class provides a generic ELF (32/64 bit) reader plugin implementing the
28/// ObjectFile protocol.
29class ObjectFileELF :
30    public lldb_private::ObjectFile
31{
32public:
33    //------------------------------------------------------------------
34    // Static Functions
35    //------------------------------------------------------------------
36    static void
37    Initialize();
38
39    static void
40    Terminate();
41
42    static lldb_private::ConstString
43    GetPluginNameStatic();
44
45    static const char *
46    GetPluginDescriptionStatic();
47
48    static lldb_private::ObjectFile *
49    CreateInstance(const lldb::ModuleSP &module_sp,
50                   lldb::DataBufferSP& data_sp,
51                   lldb::offset_t data_offset,
52                   const lldb_private::FileSpec* file,
53                   lldb::offset_t file_offset,
54                   lldb::offset_t length);
55
56    static lldb_private::ObjectFile *
57    CreateMemoryInstance (const lldb::ModuleSP &module_sp,
58                          lldb::DataBufferSP& data_sp,
59                          const lldb::ProcessSP &process_sp,
60                          lldb::addr_t header_addr);
61
62    static size_t
63    GetModuleSpecifications (const lldb_private::FileSpec& file,
64                             lldb::DataBufferSP& data_sp,
65                             lldb::offset_t data_offset,
66                             lldb::offset_t file_offset,
67                             lldb::offset_t length,
68                             lldb_private::ModuleSpecList &specs);
69
70    static bool
71    MagicBytesMatch (lldb::DataBufferSP& data_sp,
72                     lldb::addr_t offset,
73                     lldb::addr_t length);
74
75    //------------------------------------------------------------------
76    // PluginInterface protocol
77    //------------------------------------------------------------------
78    virtual lldb_private::ConstString
79    GetPluginName();
80
81    virtual uint32_t
82    GetPluginVersion();
83
84    //------------------------------------------------------------------
85    // ObjectFile Protocol.
86    //------------------------------------------------------------------
87    virtual
88    ~ObjectFileELF();
89
90    virtual bool
91    ParseHeader();
92
93    virtual lldb::ByteOrder
94    GetByteOrder() const;
95
96    virtual bool
97    IsExecutable () const;
98
99    virtual uint32_t
100    GetAddressByteSize() const;
101
102    virtual lldb_private::Symtab *
103    GetSymtab();
104
105    virtual bool
106    IsStripped ();
107
108    virtual void
109    CreateSections (lldb_private::SectionList &unified_section_list);
110
111    virtual void
112    Dump(lldb_private::Stream *s);
113
114    virtual bool
115    GetArchitecture (lldb_private::ArchSpec &arch);
116
117    virtual bool
118    GetUUID(lldb_private::UUID* uuid);
119
120    virtual lldb_private::FileSpecList
121    GetDebugSymbolFilePaths();
122
123    virtual uint32_t
124    GetDependentModules(lldb_private::FileSpecList& files);
125
126    virtual lldb_private::Address
127    GetImageInfoAddress();
128
129    virtual lldb_private::Address
130    GetEntryPointAddress ();
131
132    virtual ObjectFile::Type
133    CalculateType();
134
135    virtual ObjectFile::Strata
136    CalculateStrata();
137
138    // Returns number of program headers found in the ELF file.
139    size_t
140    GetProgramHeaderCount();
141
142    // Returns the program header with the given index.
143    const elf::ELFProgramHeader *
144    GetProgramHeaderByIndex(lldb::user_id_t id);
145
146    // Returns segment data for the given index.
147    lldb_private::DataExtractor
148    GetSegmentDataByIndex(lldb::user_id_t id);
149
150private:
151    ObjectFileELF(const lldb::ModuleSP &module_sp,
152                  lldb::DataBufferSP& data_sp,
153                  lldb::offset_t data_offset,
154                  const lldb_private::FileSpec* file,
155                  lldb::offset_t offset,
156                  lldb::offset_t length);
157
158    typedef std::vector<elf::ELFProgramHeader>  ProgramHeaderColl;
159    typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
160    typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
161
162    struct ELFSectionHeaderInfo : public elf::ELFSectionHeader
163    {
164        lldb_private::ConstString section_name;
165    };
166    typedef std::vector<ELFSectionHeaderInfo>   SectionHeaderColl;
167    typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
168    typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
169
170    typedef std::vector<elf::ELFDynamic>        DynamicSymbolColl;
171    typedef DynamicSymbolColl::iterator         DynamicSymbolCollIter;
172    typedef DynamicSymbolColl::const_iterator   DynamicSymbolCollConstIter;
173
174    /// Version of this reader common to all plugins based on this class.
175    static const uint32_t m_plugin_version = 1;
176
177    /// ELF file header.
178    elf::ELFHeader m_header;
179
180    /// ELF build ID.
181    lldb_private::UUID m_uuid;
182
183    /// ELF .gnu_debuglink file and crc data if available.
184    std::string m_gnu_debuglink_file;
185    uint32_t m_gnu_debuglink_crc;
186
187    /// Collection of program headers.
188    ProgramHeaderColl m_program_headers;
189
190    /// Collection of section headers.
191    SectionHeaderColl m_section_headers;
192
193    /// Collection of symbols from the dynamic table.
194    DynamicSymbolColl m_dynamic_symbols;
195
196    /// List of file specifications corresponding to the modules (shared
197    /// libraries) on which this object file depends.
198    mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
199
200    /// Cached value of the entry point for this module.
201    lldb_private::Address  m_entry_point_address;
202
203    /// Returns a 1 based index of the given section header.
204    size_t
205    SectionIndex(const SectionHeaderCollIter &I);
206
207    /// Returns a 1 based index of the given section header.
208    size_t
209    SectionIndex(const SectionHeaderCollConstIter &I) const;
210
211    /// Parses all section headers present in this object file and populates
212    /// m_program_headers.  This method will compute the header list only once.
213    /// Returns the number of headers parsed.
214    size_t
215    ParseProgramHeaders();
216
217    /// Parses all section headers present in this object file and populates
218    /// m_section_headers.  This method will compute the header list only once.
219    /// Returns the number of headers parsed.
220    size_t
221    ParseSectionHeaders();
222
223    /// Parses the elf section headers and returns the uuid, debug link name, crc.
224    static size_t
225    GetSectionHeaderInfo(SectionHeaderColl &section_headers,
226                         lldb_private::DataExtractor &data,
227                         const elf::ELFHeader &header,
228                         lldb_private::UUID &uuid,
229                         std::string &gnu_debuglink_file,
230                         uint32_t &gnu_debuglink_crc);
231
232    /// Scans the dynamic section and locates all dependent modules (shared
233    /// libraries) populating m_filespec_ap.  This method will compute the
234    /// dependent module list only once.  Returns the number of dependent
235    /// modules parsed.
236    size_t
237    ParseDependentModules();
238
239    /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The
240    /// vector retains the order as found in the object file.  Returns the
241    /// number of dynamic symbols parsed.
242    size_t
243    ParseDynamicSymbols();
244
245    /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method
246    /// will parse the symbols only once.  Returns the number of symbols parsed.
247    unsigned
248    ParseSymbolTable(lldb_private::Symtab *symbol_table,
249                     lldb::user_id_t start_id,
250                     lldb_private::Section *symtab);
251
252    /// Helper routine for ParseSymbolTable().
253    unsigned
254    ParseSymbols(lldb_private::Symtab *symbol_table,
255                 lldb::user_id_t start_id,
256                 lldb_private::SectionList *section_list,
257                 const size_t num_symbols,
258                 const lldb_private::DataExtractor &symtab_data,
259                 const lldb_private::DataExtractor &strtab_data);
260
261    /// Scans the relocation entries and adds a set of artificial symbols to the
262    /// given symbol table for each PLT slot.  Returns the number of symbols
263    /// added.
264    unsigned
265    ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
266                           lldb::user_id_t start_id,
267                           const ELFSectionHeaderInfo *rela_hdr,
268                           lldb::user_id_t section_id);
269
270    /// Returns the section header with the given id or NULL.
271    const ELFSectionHeaderInfo *
272    GetSectionHeaderByIndex(lldb::user_id_t id);
273
274    /// @name  ELF header dump routines
275    //@{
276    static void
277    DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
278
279    static void
280    DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
281                                  unsigned char ei_data);
282
283    static void
284    DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
285    //@}
286
287    /// @name ELF program header dump routines
288    //@{
289    void
290    DumpELFProgramHeaders(lldb_private::Stream *s);
291
292    static void
293    DumpELFProgramHeader(lldb_private::Stream *s,
294                         const elf::ELFProgramHeader &ph);
295
296    static void
297    DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
298
299    static void
300    DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
301                                 elf::elf_word p_flags);
302    //@}
303
304    /// @name ELF section header dump routines
305    //@{
306    void
307    DumpELFSectionHeaders(lldb_private::Stream *s);
308
309    static void
310    DumpELFSectionHeader(lldb_private::Stream *s,
311                         const ELFSectionHeaderInfo& sh);
312
313    static void
314    DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
315                                 elf::elf_word sh_type);
316
317    static void
318    DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
319                                  elf::elf_xword sh_flags);
320    //@}
321
322    /// ELF dependent module dump routine.
323    void
324    DumpDependentModules(lldb_private::Stream *s);
325
326    const elf::ELFDynamic *
327    FindDynamicSymbol(unsigned tag);
328
329    unsigned
330    PLTRelocationType();
331};
332
333#endif // #ifndef liblldb_ObjectFileELF_h_
334