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 
23f325ba9dSStephen Wilson //------------------------------------------------------------------------------
24f325ba9dSStephen Wilson /// @class ObjectFileELF
25f325ba9dSStephen Wilson /// @brief Generic ELF object file reader.
26f325ba9dSStephen Wilson ///
27f325ba9dSStephen Wilson /// This class provides a generic ELF (32/64 bit) reader plugin implementing the
28f325ba9dSStephen Wilson /// ObjectFile protocol.
2930fdc8d8SChris Lattner class ObjectFileELF :
3030fdc8d8SChris Lattner     public lldb_private::ObjectFile
3130fdc8d8SChris Lattner {
3230fdc8d8SChris Lattner public:
3330fdc8d8SChris Lattner     //------------------------------------------------------------------
3430fdc8d8SChris Lattner     // Static Functions
3530fdc8d8SChris Lattner     //------------------------------------------------------------------
3630fdc8d8SChris Lattner     static void
3730fdc8d8SChris Lattner     Initialize();
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner     static void
4030fdc8d8SChris Lattner     Terminate();
4130fdc8d8SChris Lattner 
4257abc5d6SGreg Clayton     static lldb_private::ConstString
4330fdc8d8SChris Lattner     GetPluginNameStatic();
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner     static const char *
4630fdc8d8SChris Lattner     GetPluginDescriptionStatic();
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner     static lldb_private::ObjectFile *
49e72dfb32SGreg Clayton     CreateInstance(const lldb::ModuleSP &module_sp,
505ce9c565SGreg Clayton                    lldb::DataBufferSP& data_sp,
515ce9c565SGreg Clayton                    lldb::offset_t data_offset,
5230fdc8d8SChris Lattner                    const lldb_private::FileSpec* file,
535ce9c565SGreg Clayton                    lldb::offset_t file_offset,
545ce9c565SGreg Clayton                    lldb::offset_t length);
5530fdc8d8SChris Lattner 
56c9660546SGreg Clayton     static lldb_private::ObjectFile *
57e72dfb32SGreg Clayton     CreateMemoryInstance (const lldb::ModuleSP &module_sp,
58c9660546SGreg Clayton                           lldb::DataBufferSP& data_sp,
59c9660546SGreg Clayton                           const lldb::ProcessSP &process_sp,
60c9660546SGreg Clayton                           lldb::addr_t header_addr);
61c9660546SGreg Clayton 
62f4d6de6aSGreg Clayton     static size_t
63f4d6de6aSGreg Clayton     GetModuleSpecifications (const lldb_private::FileSpec& file,
64f4d6de6aSGreg Clayton                              lldb::DataBufferSP& data_sp,
65f4d6de6aSGreg Clayton                              lldb::offset_t data_offset,
66f4d6de6aSGreg Clayton                              lldb::offset_t file_offset,
67f4d6de6aSGreg Clayton                              lldb::offset_t length,
68f4d6de6aSGreg Clayton                              lldb_private::ModuleSpecList &specs);
699f0013d8SMichael Sartain 
709f0013d8SMichael Sartain     static bool
719f0013d8SMichael Sartain     MagicBytesMatch (lldb::DataBufferSP& data_sp,
729f0013d8SMichael Sartain                      lldb::addr_t offset,
739f0013d8SMichael Sartain                      lldb::addr_t length);
749f0013d8SMichael Sartain 
7530fdc8d8SChris Lattner     //------------------------------------------------------------------
76f325ba9dSStephen Wilson     // PluginInterface protocol
7730fdc8d8SChris Lattner     //------------------------------------------------------------------
7857abc5d6SGreg Clayton     virtual lldb_private::ConstString
79f325ba9dSStephen Wilson     GetPluginName();
8030fdc8d8SChris Lattner 
81f325ba9dSStephen Wilson     virtual uint32_t
82f325ba9dSStephen Wilson     GetPluginVersion();
83f325ba9dSStephen Wilson 
84f325ba9dSStephen Wilson     //------------------------------------------------------------------
85f325ba9dSStephen Wilson     // ObjectFile Protocol.
86f325ba9dSStephen Wilson     //------------------------------------------------------------------
8730fdc8d8SChris Lattner     virtual
8830fdc8d8SChris Lattner     ~ObjectFileELF();
8930fdc8d8SChris Lattner 
9030fdc8d8SChris Lattner     virtual bool
9130fdc8d8SChris Lattner     ParseHeader();
9230fdc8d8SChris Lattner 
9330fdc8d8SChris Lattner     virtual lldb::ByteOrder
9430fdc8d8SChris Lattner     GetByteOrder() const;
9530fdc8d8SChris Lattner 
965aee162fSJim Ingham     virtual bool
975aee162fSJim Ingham     IsExecutable () const;
985aee162fSJim Ingham 
99c7bece56SGreg Clayton     virtual uint32_t
10030fdc8d8SChris Lattner     GetAddressByteSize() const;
10130fdc8d8SChris Lattner 
10230fdc8d8SChris Lattner     virtual lldb_private::Symtab *
1033046e668SGreg Clayton     GetSymtab();
10430fdc8d8SChris Lattner 
105*35729bb1SAshok Thirumurthi     virtual lldb_private::Symbol *
106*35729bb1SAshok Thirumurthi     ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique);
107*35729bb1SAshok Thirumurthi 
1083046e668SGreg Clayton     virtual bool
1093046e668SGreg Clayton     IsStripped ();
1103046e668SGreg Clayton 
1113046e668SGreg Clayton     virtual void
1123046e668SGreg Clayton     CreateSections (lldb_private::SectionList &unified_section_list);
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner     virtual void
11530fdc8d8SChris Lattner     Dump(lldb_private::Stream *s);
11630fdc8d8SChris Lattner 
11730fdc8d8SChris Lattner     virtual bool
118514487e8SGreg Clayton     GetArchitecture (lldb_private::ArchSpec &arch);
11930fdc8d8SChris Lattner 
12030fdc8d8SChris Lattner     virtual bool
12130fdc8d8SChris Lattner     GetUUID(lldb_private::UUID* uuid);
12230fdc8d8SChris Lattner 
123a7499c98SMichael Sartain     virtual lldb_private::FileSpecList
124a7499c98SMichael Sartain     GetDebugSymbolFilePaths();
125a7499c98SMichael Sartain 
12630fdc8d8SChris Lattner     virtual uint32_t
12730fdc8d8SChris Lattner     GetDependentModules(lldb_private::FileSpecList& files);
12830fdc8d8SChris Lattner 
1292ab0a585SStephen Wilson     virtual lldb_private::Address
1302ab0a585SStephen Wilson     GetImageInfoAddress();
1312ab0a585SStephen Wilson 
132672e6f59SJim Ingham     virtual lldb_private::Address
133672e6f59SJim Ingham     GetEntryPointAddress ();
1349e00b6a6SGreg Clayton 
1359e00b6a6SGreg Clayton     virtual ObjectFile::Type
1369e00b6a6SGreg Clayton     CalculateType();
1379e00b6a6SGreg Clayton 
1389e00b6a6SGreg Clayton     virtual ObjectFile::Strata
1399e00b6a6SGreg Clayton     CalculateStrata();
140672e6f59SJim Ingham 
1414822d926SAshok Thirumurthi     // Returns number of program headers found in the ELF file.
1424822d926SAshok Thirumurthi     size_t
1434822d926SAshok Thirumurthi     GetProgramHeaderCount();
1444822d926SAshok Thirumurthi 
1454822d926SAshok Thirumurthi     // Returns the program header with the given index.
1464822d926SAshok Thirumurthi     const elf::ELFProgramHeader *
1474822d926SAshok Thirumurthi     GetProgramHeaderByIndex(lldb::user_id_t id);
1484822d926SAshok Thirumurthi 
1494822d926SAshok Thirumurthi     // Returns segment data for the given index.
1504822d926SAshok Thirumurthi     lldb_private::DataExtractor
1514822d926SAshok Thirumurthi     GetSegmentDataByIndex(lldb::user_id_t id);
1524822d926SAshok Thirumurthi 
153f325ba9dSStephen Wilson private:
154e72dfb32SGreg Clayton     ObjectFileELF(const lldb::ModuleSP &module_sp,
1555ce9c565SGreg Clayton                   lldb::DataBufferSP& data_sp,
1565ce9c565SGreg Clayton                   lldb::offset_t data_offset,
157f325ba9dSStephen Wilson                   const lldb_private::FileSpec* file,
1585ce9c565SGreg Clayton                   lldb::offset_t offset,
1595ce9c565SGreg Clayton                   lldb::offset_t length);
16030fdc8d8SChris Lattner 
161f325ba9dSStephen Wilson     typedef std::vector<elf::ELFProgramHeader>  ProgramHeaderColl;
16230fdc8d8SChris Lattner     typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
16330fdc8d8SChris Lattner     typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
16430fdc8d8SChris Lattner 
165a7499c98SMichael Sartain     struct ELFSectionHeaderInfo : public elf::ELFSectionHeader
166a7499c98SMichael Sartain     {
167a7499c98SMichael Sartain         lldb_private::ConstString section_name;
168a7499c98SMichael Sartain     };
169a7499c98SMichael Sartain     typedef std::vector<ELFSectionHeaderInfo>   SectionHeaderColl;
17030fdc8d8SChris Lattner     typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
17130fdc8d8SChris Lattner     typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
17230fdc8d8SChris Lattner 
173499b40e8SStephen Wilson     typedef std::vector<elf::ELFDynamic>        DynamicSymbolColl;
174499b40e8SStephen Wilson     typedef DynamicSymbolColl::iterator         DynamicSymbolCollIter;
175499b40e8SStephen Wilson     typedef DynamicSymbolColl::const_iterator   DynamicSymbolCollConstIter;
176499b40e8SStephen Wilson 
177f325ba9dSStephen Wilson     /// Version of this reader common to all plugins based on this class.
178f325ba9dSStephen Wilson     static const uint32_t m_plugin_version = 1;
179f325ba9dSStephen Wilson 
180f325ba9dSStephen Wilson     /// ELF file header.
181f325ba9dSStephen Wilson     elf::ELFHeader m_header;
182f325ba9dSStephen Wilson 
183a7499c98SMichael Sartain     /// ELF build ID.
184c836ae7dSMichael Sartain     lldb_private::UUID m_uuid;
185c836ae7dSMichael Sartain 
186a7499c98SMichael Sartain     /// ELF .gnu_debuglink file and crc data if available.
187a7499c98SMichael Sartain     std::string m_gnu_debuglink_file;
188a7499c98SMichael Sartain     uint32_t m_gnu_debuglink_crc;
189a7499c98SMichael Sartain 
190f325ba9dSStephen Wilson     /// Collection of program headers.
19130fdc8d8SChris Lattner     ProgramHeaderColl m_program_headers;
192f325ba9dSStephen Wilson 
193f325ba9dSStephen Wilson     /// Collection of section headers.
19430fdc8d8SChris Lattner     SectionHeaderColl m_section_headers;
195f325ba9dSStephen Wilson 
196499b40e8SStephen Wilson     /// Collection of symbols from the dynamic table.
197499b40e8SStephen Wilson     DynamicSymbolColl m_dynamic_symbols;
198499b40e8SStephen Wilson 
199f325ba9dSStephen Wilson     /// List of file specifications corresponding to the modules (shared
200f325ba9dSStephen Wilson     /// libraries) on which this object file depends.
2017b0992d9SGreg Clayton     mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
202f325ba9dSStephen Wilson 
203672e6f59SJim Ingham     /// Cached value of the entry point for this module.
204672e6f59SJim Ingham     lldb_private::Address  m_entry_point_address;
205672e6f59SJim Ingham 
206f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
207c7bece56SGreg Clayton     size_t
208f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollIter &I);
209f325ba9dSStephen Wilson 
210f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
211c7bece56SGreg Clayton     size_t
212f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollConstIter &I) const;
213f325ba9dSStephen Wilson 
214f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
215f325ba9dSStephen Wilson     /// m_program_headers.  This method will compute the header list only once.
216f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
21730fdc8d8SChris Lattner     size_t
218f325ba9dSStephen Wilson     ParseProgramHeaders();
21930fdc8d8SChris Lattner 
220f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
221f325ba9dSStephen Wilson     /// m_section_headers.  This method will compute the header list only once.
222f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
22330fdc8d8SChris Lattner     size_t
224f325ba9dSStephen Wilson     ParseSectionHeaders();
22530fdc8d8SChris Lattner 
226a7499c98SMichael Sartain     /// Parses the elf section headers and returns the uuid, debug link name, crc.
227a7499c98SMichael Sartain     static size_t
228a7499c98SMichael Sartain     GetSectionHeaderInfo(SectionHeaderColl &section_headers,
229a7499c98SMichael Sartain                          lldb_private::DataExtractor &data,
230a7499c98SMichael Sartain                          const elf::ELFHeader &header,
231a7499c98SMichael Sartain                          lldb_private::UUID &uuid,
232a7499c98SMichael Sartain                          std::string &gnu_debuglink_file,
233a7499c98SMichael Sartain                          uint32_t &gnu_debuglink_crc);
234a7499c98SMichael Sartain 
235f325ba9dSStephen Wilson     /// Scans the dynamic section and locates all dependent modules (shared
236710dd5aeSGreg Clayton     /// libraries) populating m_filespec_ap.  This method will compute the
237f325ba9dSStephen Wilson     /// dependent module list only once.  Returns the number of dependent
238f325ba9dSStephen Wilson     /// modules parsed.
239f325ba9dSStephen Wilson     size_t
240f325ba9dSStephen Wilson     ParseDependentModules();
24130fdc8d8SChris Lattner 
242499b40e8SStephen Wilson     /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The
243499b40e8SStephen Wilson     /// vector retains the order as found in the object file.  Returns the
244499b40e8SStephen Wilson     /// number of dynamic symbols parsed.
245499b40e8SStephen Wilson     size_t
246499b40e8SStephen Wilson     ParseDynamicSymbols();
247499b40e8SStephen Wilson 
248f325ba9dSStephen Wilson     /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method
249f325ba9dSStephen Wilson     /// will parse the symbols only once.  Returns the number of symbols parsed.
250499b40e8SStephen Wilson     unsigned
251f325ba9dSStephen Wilson     ParseSymbolTable(lldb_private::Symtab *symbol_table,
252499b40e8SStephen Wilson                      lldb::user_id_t start_id,
2533046e668SGreg Clayton                      lldb_private::Section *symtab);
254f325ba9dSStephen Wilson 
255a7499c98SMichael Sartain     /// Helper routine for ParseSymbolTable().
256a7499c98SMichael Sartain     unsigned
257a7499c98SMichael Sartain     ParseSymbols(lldb_private::Symtab *symbol_table,
258a7499c98SMichael Sartain                  lldb::user_id_t start_id,
259a7499c98SMichael Sartain                  lldb_private::SectionList *section_list,
2603046e668SGreg Clayton                  const size_t num_symbols,
261a7499c98SMichael Sartain                  const lldb_private::DataExtractor &symtab_data,
262a7499c98SMichael Sartain                  const lldb_private::DataExtractor &strtab_data);
263a7499c98SMichael Sartain 
264499b40e8SStephen Wilson     /// Scans the relocation entries and adds a set of artificial symbols to the
265499b40e8SStephen Wilson     /// given symbol table for each PLT slot.  Returns the number of symbols
266499b40e8SStephen Wilson     /// added.
267499b40e8SStephen Wilson     unsigned
268499b40e8SStephen Wilson     ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
269499b40e8SStephen Wilson                            lldb::user_id_t start_id,
270a7499c98SMichael Sartain                            const ELFSectionHeaderInfo *rela_hdr,
271499b40e8SStephen Wilson                            lldb::user_id_t section_id);
272499b40e8SStephen Wilson 
273499b40e8SStephen Wilson     /// Returns the section header with the given id or NULL.
274a7499c98SMichael Sartain     const ELFSectionHeaderInfo *
275499b40e8SStephen Wilson     GetSectionHeaderByIndex(lldb::user_id_t id);
276499b40e8SStephen Wilson 
277f325ba9dSStephen Wilson     /// @name  ELF header dump routines
278f325ba9dSStephen Wilson     //@{
27930fdc8d8SChris Lattner     static void
280f325ba9dSStephen Wilson     DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
28130fdc8d8SChris Lattner 
28230fdc8d8SChris Lattner     static void
28330fdc8d8SChris Lattner     DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
284f325ba9dSStephen Wilson                                   unsigned char ei_data);
28530fdc8d8SChris Lattner 
286f325ba9dSStephen Wilson     static void
287f325ba9dSStephen Wilson     DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
288f325ba9dSStephen Wilson     //@}
289f325ba9dSStephen Wilson 
290f325ba9dSStephen Wilson     /// @name ELF program header dump routines
291f325ba9dSStephen Wilson     //@{
29230fdc8d8SChris Lattner     void
29330fdc8d8SChris Lattner     DumpELFProgramHeaders(lldb_private::Stream *s);
29430fdc8d8SChris Lattner 
29530fdc8d8SChris Lattner     static void
29630fdc8d8SChris Lattner     DumpELFProgramHeader(lldb_private::Stream *s,
297f325ba9dSStephen Wilson                          const elf::ELFProgramHeader &ph);
29830fdc8d8SChris Lattner 
29930fdc8d8SChris Lattner     static void
300f325ba9dSStephen Wilson     DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
30130fdc8d8SChris Lattner 
30230fdc8d8SChris Lattner     static void
30330fdc8d8SChris Lattner     DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
304f325ba9dSStephen Wilson                                  elf::elf_word p_flags);
305f325ba9dSStephen Wilson     //@}
30630fdc8d8SChris Lattner 
307f325ba9dSStephen Wilson     /// @name ELF section header dump routines
308f325ba9dSStephen Wilson     //@{
30930fdc8d8SChris Lattner     void
31030fdc8d8SChris Lattner     DumpELFSectionHeaders(lldb_private::Stream *s);
31130fdc8d8SChris Lattner 
31230fdc8d8SChris Lattner     static void
31330fdc8d8SChris Lattner     DumpELFSectionHeader(lldb_private::Stream *s,
314a7499c98SMichael Sartain                          const ELFSectionHeaderInfo& sh);
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner     static void
31730fdc8d8SChris Lattner     DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
318f325ba9dSStephen Wilson                                  elf::elf_word sh_type);
31930fdc8d8SChris Lattner 
32030fdc8d8SChris Lattner     static void
32130fdc8d8SChris Lattner     DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
322c7bece56SGreg Clayton                                   elf::elf_xword sh_flags);
323f325ba9dSStephen Wilson     //@}
32430fdc8d8SChris Lattner 
325f325ba9dSStephen Wilson     /// ELF dependent module dump routine.
326f325ba9dSStephen Wilson     void
327f325ba9dSStephen Wilson     DumpDependentModules(lldb_private::Stream *s);
32830fdc8d8SChris Lattner 
329499b40e8SStephen Wilson     const elf::ELFDynamic *
330499b40e8SStephen Wilson     FindDynamicSymbol(unsigned tag);
331499b40e8SStephen Wilson 
332499b40e8SStephen Wilson     unsigned
333499b40e8SStephen Wilson     PLTRelocationType();
33430fdc8d8SChris Lattner };
33530fdc8d8SChris Lattner 
33630fdc8d8SChris Lattner #endif // #ifndef liblldb_ObjectFileELF_h_
337