1f325ba9dSStephen Wilson //===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #ifndef liblldb_ObjectFileELF_h_
1130fdc8d8SChris Lattner #define liblldb_ObjectFileELF_h_
1230fdc8d8SChris Lattner 
1330fdc8d8SChris Lattner #include <stdint.h>
1430fdc8d8SChris Lattner #include <vector>
1530fdc8d8SChris Lattner 
1630fdc8d8SChris Lattner #include "lldb/lldb-private.h"
1753239f00SGreg Clayton #include "lldb/Host/FileSpec.h"
1830fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
19c836ae7dSMichael Sartain #include "lldb/Core/UUID.h"
2030fdc8d8SChris Lattner 
21f325ba9dSStephen Wilson #include "ELFHeader.h"
2230fdc8d8SChris Lattner 
23c113ff8cSEd Maste struct ELFNote
24c113ff8cSEd Maste {
25c113ff8cSEd Maste     elf::elf_word n_namesz;
26c113ff8cSEd Maste     elf::elf_word n_descsz;
27c113ff8cSEd Maste     elf::elf_word n_type;
28c113ff8cSEd Maste 
29c113ff8cSEd Maste     std::string n_name;
30c113ff8cSEd Maste 
31c113ff8cSEd Maste     ELFNote() : n_namesz(0), n_descsz(0), n_type(0)
32c113ff8cSEd Maste     {
33c113ff8cSEd Maste     }
34c113ff8cSEd Maste 
35c113ff8cSEd Maste     /// Parse an ELFNote entry from the given DataExtractor starting at position
36c113ff8cSEd Maste     /// \p offset.
37c113ff8cSEd Maste     ///
38c113ff8cSEd Maste     /// @param[in] data
39c113ff8cSEd Maste     ///    The DataExtractor to read from.
40c113ff8cSEd Maste     ///
41c113ff8cSEd Maste     /// @param[in,out] offset
42c113ff8cSEd Maste     ///    Pointer to an offset in the data.  On return the offset will be
43c113ff8cSEd Maste     ///    advanced by the number of bytes read.
44c113ff8cSEd Maste     ///
45c113ff8cSEd Maste     /// @return
46c113ff8cSEd Maste     ///    True if the ELFRel entry was successfully read and false otherwise.
47c113ff8cSEd Maste     bool
48c113ff8cSEd Maste     Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
49c113ff8cSEd Maste };
50c113ff8cSEd Maste 
51f325ba9dSStephen Wilson //------------------------------------------------------------------------------
52f325ba9dSStephen Wilson /// @class ObjectFileELF
53f325ba9dSStephen Wilson /// @brief Generic ELF object file reader.
54f325ba9dSStephen Wilson ///
55f325ba9dSStephen Wilson /// This class provides a generic ELF (32/64 bit) reader plugin implementing the
56f325ba9dSStephen Wilson /// ObjectFile protocol.
5730fdc8d8SChris Lattner class ObjectFileELF :
5830fdc8d8SChris Lattner     public lldb_private::ObjectFile
5930fdc8d8SChris Lattner {
6030fdc8d8SChris Lattner public:
6130fdc8d8SChris Lattner     //------------------------------------------------------------------
6230fdc8d8SChris Lattner     // Static Functions
6330fdc8d8SChris Lattner     //------------------------------------------------------------------
6430fdc8d8SChris Lattner     static void
6530fdc8d8SChris Lattner     Initialize();
6630fdc8d8SChris Lattner 
6730fdc8d8SChris Lattner     static void
6830fdc8d8SChris Lattner     Terminate();
6930fdc8d8SChris Lattner 
7057abc5d6SGreg Clayton     static lldb_private::ConstString
7130fdc8d8SChris Lattner     GetPluginNameStatic();
7230fdc8d8SChris Lattner 
7330fdc8d8SChris Lattner     static const char *
7430fdc8d8SChris Lattner     GetPluginDescriptionStatic();
7530fdc8d8SChris Lattner 
7630fdc8d8SChris Lattner     static lldb_private::ObjectFile *
77e72dfb32SGreg Clayton     CreateInstance(const lldb::ModuleSP &module_sp,
785ce9c565SGreg Clayton                    lldb::DataBufferSP& data_sp,
795ce9c565SGreg Clayton                    lldb::offset_t data_offset,
8030fdc8d8SChris Lattner                    const lldb_private::FileSpec* file,
815ce9c565SGreg Clayton                    lldb::offset_t file_offset,
825ce9c565SGreg Clayton                    lldb::offset_t length);
8330fdc8d8SChris Lattner 
84c9660546SGreg Clayton     static lldb_private::ObjectFile *
85e72dfb32SGreg Clayton     CreateMemoryInstance (const lldb::ModuleSP &module_sp,
86c9660546SGreg Clayton                           lldb::DataBufferSP& data_sp,
87c9660546SGreg Clayton                           const lldb::ProcessSP &process_sp,
88c9660546SGreg Clayton                           lldb::addr_t header_addr);
89c9660546SGreg Clayton 
90f4d6de6aSGreg Clayton     static size_t
91f4d6de6aSGreg Clayton     GetModuleSpecifications (const lldb_private::FileSpec& file,
92f4d6de6aSGreg Clayton                              lldb::DataBufferSP& data_sp,
93f4d6de6aSGreg Clayton                              lldb::offset_t data_offset,
94f4d6de6aSGreg Clayton                              lldb::offset_t file_offset,
95f4d6de6aSGreg Clayton                              lldb::offset_t length,
96f4d6de6aSGreg Clayton                              lldb_private::ModuleSpecList &specs);
979f0013d8SMichael Sartain 
989f0013d8SMichael Sartain     static bool
999f0013d8SMichael Sartain     MagicBytesMatch (lldb::DataBufferSP& data_sp,
1009f0013d8SMichael Sartain                      lldb::addr_t offset,
1019f0013d8SMichael Sartain                      lldb::addr_t length);
1029f0013d8SMichael Sartain 
10330fdc8d8SChris Lattner     //------------------------------------------------------------------
104f325ba9dSStephen Wilson     // PluginInterface protocol
10530fdc8d8SChris Lattner     //------------------------------------------------------------------
10657abc5d6SGreg Clayton     virtual lldb_private::ConstString
107f325ba9dSStephen Wilson     GetPluginName();
10830fdc8d8SChris Lattner 
109f325ba9dSStephen Wilson     virtual uint32_t
110f325ba9dSStephen Wilson     GetPluginVersion();
111f325ba9dSStephen Wilson 
112f325ba9dSStephen Wilson     //------------------------------------------------------------------
113f325ba9dSStephen Wilson     // ObjectFile Protocol.
114f325ba9dSStephen Wilson     //------------------------------------------------------------------
11530fdc8d8SChris Lattner     virtual
11630fdc8d8SChris Lattner     ~ObjectFileELF();
11730fdc8d8SChris Lattner 
11830fdc8d8SChris Lattner     virtual bool
11930fdc8d8SChris Lattner     ParseHeader();
12030fdc8d8SChris Lattner 
1219e02dacdSSteve Pucci     virtual bool
122*751caf65SGreg Clayton     SetLoadAddress (lldb_private::Target &target,
123*751caf65SGreg Clayton                     lldb::addr_t value,
124*751caf65SGreg Clayton                     bool value_is_offset);
1259e02dacdSSteve Pucci 
12630fdc8d8SChris Lattner     virtual lldb::ByteOrder
12730fdc8d8SChris Lattner     GetByteOrder() const;
12830fdc8d8SChris Lattner 
1295aee162fSJim Ingham     virtual bool
1305aee162fSJim Ingham     IsExecutable () const;
1315aee162fSJim Ingham 
132c7bece56SGreg Clayton     virtual uint32_t
13330fdc8d8SChris Lattner     GetAddressByteSize() const;
13430fdc8d8SChris Lattner 
13530fdc8d8SChris Lattner     virtual lldb_private::Symtab *
1363046e668SGreg Clayton     GetSymtab();
13730fdc8d8SChris Lattner 
13835729bb1SAshok Thirumurthi     virtual lldb_private::Symbol *
13935729bb1SAshok Thirumurthi     ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique);
14035729bb1SAshok Thirumurthi 
1413046e668SGreg Clayton     virtual bool
1423046e668SGreg Clayton     IsStripped ();
1433046e668SGreg Clayton 
1443046e668SGreg Clayton     virtual void
1453046e668SGreg Clayton     CreateSections (lldb_private::SectionList &unified_section_list);
14630fdc8d8SChris Lattner 
14730fdc8d8SChris Lattner     virtual void
14830fdc8d8SChris Lattner     Dump(lldb_private::Stream *s);
14930fdc8d8SChris Lattner 
15030fdc8d8SChris Lattner     virtual bool
151514487e8SGreg Clayton     GetArchitecture (lldb_private::ArchSpec &arch);
15230fdc8d8SChris Lattner 
15330fdc8d8SChris Lattner     virtual bool
15430fdc8d8SChris Lattner     GetUUID(lldb_private::UUID* uuid);
15530fdc8d8SChris Lattner 
156a7499c98SMichael Sartain     virtual lldb_private::FileSpecList
157a7499c98SMichael Sartain     GetDebugSymbolFilePaths();
158a7499c98SMichael Sartain 
15930fdc8d8SChris Lattner     virtual uint32_t
16030fdc8d8SChris Lattner     GetDependentModules(lldb_private::FileSpecList& files);
16130fdc8d8SChris Lattner 
1622ab0a585SStephen Wilson     virtual lldb_private::Address
1635480365bSEd Maste     GetImageInfoAddress(lldb_private::Target *target);
1642ab0a585SStephen Wilson 
165672e6f59SJim Ingham     virtual lldb_private::Address
166672e6f59SJim Ingham     GetEntryPointAddress ();
1679e00b6a6SGreg Clayton 
1689e00b6a6SGreg Clayton     virtual ObjectFile::Type
1699e00b6a6SGreg Clayton     CalculateType();
1709e00b6a6SGreg Clayton 
1719e00b6a6SGreg Clayton     virtual ObjectFile::Strata
1729e00b6a6SGreg Clayton     CalculateStrata();
173672e6f59SJim Ingham 
1744822d926SAshok Thirumurthi     // Returns number of program headers found in the ELF file.
1754822d926SAshok Thirumurthi     size_t
1764822d926SAshok Thirumurthi     GetProgramHeaderCount();
1774822d926SAshok Thirumurthi 
1784822d926SAshok Thirumurthi     // Returns the program header with the given index.
1794822d926SAshok Thirumurthi     const elf::ELFProgramHeader *
1804822d926SAshok Thirumurthi     GetProgramHeaderByIndex(lldb::user_id_t id);
1814822d926SAshok Thirumurthi 
1824822d926SAshok Thirumurthi     // Returns segment data for the given index.
1834822d926SAshok Thirumurthi     lldb_private::DataExtractor
1844822d926SAshok Thirumurthi     GetSegmentDataByIndex(lldb::user_id_t id);
1854822d926SAshok Thirumurthi 
186f325ba9dSStephen Wilson private:
187e72dfb32SGreg Clayton     ObjectFileELF(const lldb::ModuleSP &module_sp,
1885ce9c565SGreg Clayton                   lldb::DataBufferSP& data_sp,
1895ce9c565SGreg Clayton                   lldb::offset_t data_offset,
190f325ba9dSStephen Wilson                   const lldb_private::FileSpec* file,
1915ce9c565SGreg Clayton                   lldb::offset_t offset,
1925ce9c565SGreg Clayton                   lldb::offset_t length);
19330fdc8d8SChris Lattner 
194f325ba9dSStephen Wilson     typedef std::vector<elf::ELFProgramHeader>  ProgramHeaderColl;
19530fdc8d8SChris Lattner     typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
19630fdc8d8SChris Lattner     typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
19730fdc8d8SChris Lattner 
198a7499c98SMichael Sartain     struct ELFSectionHeaderInfo : public elf::ELFSectionHeader
199a7499c98SMichael Sartain     {
200a7499c98SMichael Sartain         lldb_private::ConstString section_name;
201a7499c98SMichael Sartain     };
202a7499c98SMichael Sartain     typedef std::vector<ELFSectionHeaderInfo>   SectionHeaderColl;
20330fdc8d8SChris Lattner     typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
20430fdc8d8SChris Lattner     typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
20530fdc8d8SChris Lattner 
206499b40e8SStephen Wilson     typedef std::vector<elf::ELFDynamic>        DynamicSymbolColl;
207499b40e8SStephen Wilson     typedef DynamicSymbolColl::iterator         DynamicSymbolCollIter;
208499b40e8SStephen Wilson     typedef DynamicSymbolColl::const_iterator   DynamicSymbolCollConstIter;
209499b40e8SStephen Wilson 
210f325ba9dSStephen Wilson     /// Version of this reader common to all plugins based on this class.
211f325ba9dSStephen Wilson     static const uint32_t m_plugin_version = 1;
212f325ba9dSStephen Wilson 
213f325ba9dSStephen Wilson     /// ELF file header.
214f325ba9dSStephen Wilson     elf::ELFHeader m_header;
215f325ba9dSStephen Wilson 
216a7499c98SMichael Sartain     /// ELF build ID.
217c836ae7dSMichael Sartain     lldb_private::UUID m_uuid;
218c836ae7dSMichael Sartain 
219a7499c98SMichael Sartain     /// ELF .gnu_debuglink file and crc data if available.
220a7499c98SMichael Sartain     std::string m_gnu_debuglink_file;
221a7499c98SMichael Sartain     uint32_t m_gnu_debuglink_crc;
222a7499c98SMichael Sartain 
223f325ba9dSStephen Wilson     /// Collection of program headers.
22430fdc8d8SChris Lattner     ProgramHeaderColl m_program_headers;
225f325ba9dSStephen Wilson 
226f325ba9dSStephen Wilson     /// Collection of section headers.
22730fdc8d8SChris Lattner     SectionHeaderColl m_section_headers;
228f325ba9dSStephen Wilson 
229499b40e8SStephen Wilson     /// Collection of symbols from the dynamic table.
230499b40e8SStephen Wilson     DynamicSymbolColl m_dynamic_symbols;
231499b40e8SStephen Wilson 
232f325ba9dSStephen Wilson     /// List of file specifications corresponding to the modules (shared
233f325ba9dSStephen Wilson     /// libraries) on which this object file depends.
2347b0992d9SGreg Clayton     mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
235f325ba9dSStephen Wilson 
236672e6f59SJim Ingham     /// Cached value of the entry point for this module.
237672e6f59SJim Ingham     lldb_private::Address  m_entry_point_address;
238672e6f59SJim Ingham 
239f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
240c7bece56SGreg Clayton     size_t
241f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollIter &I);
242f325ba9dSStephen Wilson 
243f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
244c7bece56SGreg Clayton     size_t
245f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollConstIter &I) const;
246f325ba9dSStephen Wilson 
247f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
248f325ba9dSStephen Wilson     /// m_program_headers.  This method will compute the header list only once.
249f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
25030fdc8d8SChris Lattner     size_t
251f325ba9dSStephen Wilson     ParseProgramHeaders();
25230fdc8d8SChris Lattner 
253f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
254f325ba9dSStephen Wilson     /// m_section_headers.  This method will compute the header list only once.
255f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
25630fdc8d8SChris Lattner     size_t
257f325ba9dSStephen Wilson     ParseSectionHeaders();
25830fdc8d8SChris Lattner 
259a7499c98SMichael Sartain     /// Parses the elf section headers and returns the uuid, debug link name, crc.
260a7499c98SMichael Sartain     static size_t
261a7499c98SMichael Sartain     GetSectionHeaderInfo(SectionHeaderColl &section_headers,
262a7499c98SMichael Sartain                          lldb_private::DataExtractor &data,
263a7499c98SMichael Sartain                          const elf::ELFHeader &header,
264a7499c98SMichael Sartain                          lldb_private::UUID &uuid,
265a7499c98SMichael Sartain                          std::string &gnu_debuglink_file,
266a7499c98SMichael Sartain                          uint32_t &gnu_debuglink_crc);
267a7499c98SMichael Sartain 
268f325ba9dSStephen Wilson     /// Scans the dynamic section and locates all dependent modules (shared
269710dd5aeSGreg Clayton     /// libraries) populating m_filespec_ap.  This method will compute the
270f325ba9dSStephen Wilson     /// dependent module list only once.  Returns the number of dependent
271f325ba9dSStephen Wilson     /// modules parsed.
272f325ba9dSStephen Wilson     size_t
273f325ba9dSStephen Wilson     ParseDependentModules();
27430fdc8d8SChris Lattner 
275499b40e8SStephen Wilson     /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The
276499b40e8SStephen Wilson     /// vector retains the order as found in the object file.  Returns the
277499b40e8SStephen Wilson     /// number of dynamic symbols parsed.
278499b40e8SStephen Wilson     size_t
279499b40e8SStephen Wilson     ParseDynamicSymbols();
280499b40e8SStephen Wilson 
281f325ba9dSStephen Wilson     /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method
282f325ba9dSStephen Wilson     /// will parse the symbols only once.  Returns the number of symbols parsed.
283499b40e8SStephen Wilson     unsigned
284f325ba9dSStephen Wilson     ParseSymbolTable(lldb_private::Symtab *symbol_table,
285499b40e8SStephen Wilson                      lldb::user_id_t start_id,
2863046e668SGreg Clayton                      lldb_private::Section *symtab);
287f325ba9dSStephen Wilson 
288a7499c98SMichael Sartain     /// Helper routine for ParseSymbolTable().
289a7499c98SMichael Sartain     unsigned
290a7499c98SMichael Sartain     ParseSymbols(lldb_private::Symtab *symbol_table,
291a7499c98SMichael Sartain                  lldb::user_id_t start_id,
292a7499c98SMichael Sartain                  lldb_private::SectionList *section_list,
2933046e668SGreg Clayton                  const size_t num_symbols,
294a7499c98SMichael Sartain                  const lldb_private::DataExtractor &symtab_data,
295a7499c98SMichael Sartain                  const lldb_private::DataExtractor &strtab_data);
296a7499c98SMichael Sartain 
297499b40e8SStephen Wilson     /// Scans the relocation entries and adds a set of artificial symbols to the
298499b40e8SStephen Wilson     /// given symbol table for each PLT slot.  Returns the number of symbols
299499b40e8SStephen Wilson     /// added.
300499b40e8SStephen Wilson     unsigned
301499b40e8SStephen Wilson     ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
302499b40e8SStephen Wilson                            lldb::user_id_t start_id,
303a7499c98SMichael Sartain                            const ELFSectionHeaderInfo *rela_hdr,
304499b40e8SStephen Wilson                            lldb::user_id_t section_id);
305499b40e8SStephen Wilson 
306499b40e8SStephen Wilson     /// Returns the section header with the given id or NULL.
307a7499c98SMichael Sartain     const ELFSectionHeaderInfo *
308499b40e8SStephen Wilson     GetSectionHeaderByIndex(lldb::user_id_t id);
309499b40e8SStephen Wilson 
310f325ba9dSStephen Wilson     /// @name  ELF header dump routines
311f325ba9dSStephen Wilson     //@{
31230fdc8d8SChris Lattner     static void
313f325ba9dSStephen Wilson     DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
31430fdc8d8SChris Lattner 
31530fdc8d8SChris Lattner     static void
31630fdc8d8SChris Lattner     DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
317f325ba9dSStephen Wilson                                   unsigned char ei_data);
31830fdc8d8SChris Lattner 
319f325ba9dSStephen Wilson     static void
320f325ba9dSStephen Wilson     DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
321f325ba9dSStephen Wilson     //@}
322f325ba9dSStephen Wilson 
323f325ba9dSStephen Wilson     /// @name ELF program header dump routines
324f325ba9dSStephen Wilson     //@{
32530fdc8d8SChris Lattner     void
32630fdc8d8SChris Lattner     DumpELFProgramHeaders(lldb_private::Stream *s);
32730fdc8d8SChris Lattner 
32830fdc8d8SChris Lattner     static void
32930fdc8d8SChris Lattner     DumpELFProgramHeader(lldb_private::Stream *s,
330f325ba9dSStephen Wilson                          const elf::ELFProgramHeader &ph);
33130fdc8d8SChris Lattner 
33230fdc8d8SChris Lattner     static void
333f325ba9dSStephen Wilson     DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
33430fdc8d8SChris Lattner 
33530fdc8d8SChris Lattner     static void
33630fdc8d8SChris Lattner     DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
337f325ba9dSStephen Wilson                                  elf::elf_word p_flags);
338f325ba9dSStephen Wilson     //@}
33930fdc8d8SChris Lattner 
340f325ba9dSStephen Wilson     /// @name ELF section header dump routines
341f325ba9dSStephen Wilson     //@{
34230fdc8d8SChris Lattner     void
34330fdc8d8SChris Lattner     DumpELFSectionHeaders(lldb_private::Stream *s);
34430fdc8d8SChris Lattner 
34530fdc8d8SChris Lattner     static void
34630fdc8d8SChris Lattner     DumpELFSectionHeader(lldb_private::Stream *s,
347a7499c98SMichael Sartain                          const ELFSectionHeaderInfo& sh);
34830fdc8d8SChris Lattner 
34930fdc8d8SChris Lattner     static void
35030fdc8d8SChris Lattner     DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
351f325ba9dSStephen Wilson                                  elf::elf_word sh_type);
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner     static void
35430fdc8d8SChris Lattner     DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
355c7bece56SGreg Clayton                                   elf::elf_xword sh_flags);
356f325ba9dSStephen Wilson     //@}
35730fdc8d8SChris Lattner 
358f325ba9dSStephen Wilson     /// ELF dependent module dump routine.
359f325ba9dSStephen Wilson     void
360f325ba9dSStephen Wilson     DumpDependentModules(lldb_private::Stream *s);
36130fdc8d8SChris Lattner 
362499b40e8SStephen Wilson     const elf::ELFDynamic *
363499b40e8SStephen Wilson     FindDynamicSymbol(unsigned tag);
364499b40e8SStephen Wilson 
365499b40e8SStephen Wilson     unsigned
366499b40e8SStephen Wilson     PLTRelocationType();
36730fdc8d8SChris Lattner };
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner #endif // #ifndef liblldb_ObjectFileELF_h_
370