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"
1930fdc8d8SChris Lattner 
20f325ba9dSStephen Wilson #include "ELFHeader.h"
2130fdc8d8SChris Lattner 
22f325ba9dSStephen Wilson //------------------------------------------------------------------------------
23f325ba9dSStephen Wilson /// @class ObjectFileELF
24f325ba9dSStephen Wilson /// @brief Generic ELF object file reader.
25f325ba9dSStephen Wilson ///
26f325ba9dSStephen Wilson /// This class provides a generic ELF (32/64 bit) reader plugin implementing the
27f325ba9dSStephen Wilson /// ObjectFile protocol.
2830fdc8d8SChris Lattner class ObjectFileELF :
2930fdc8d8SChris Lattner     public lldb_private::ObjectFile
3030fdc8d8SChris Lattner {
3130fdc8d8SChris Lattner public:
3230fdc8d8SChris Lattner     //------------------------------------------------------------------
3330fdc8d8SChris Lattner     // Static Functions
3430fdc8d8SChris Lattner     //------------------------------------------------------------------
3530fdc8d8SChris Lattner     static void
3630fdc8d8SChris Lattner     Initialize();
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner     static void
3930fdc8d8SChris Lattner     Terminate();
4030fdc8d8SChris Lattner 
41*57abc5d6SGreg Clayton     static lldb_private::ConstString
4230fdc8d8SChris Lattner     GetPluginNameStatic();
4330fdc8d8SChris Lattner 
4430fdc8d8SChris Lattner     static const char *
4530fdc8d8SChris Lattner     GetPluginDescriptionStatic();
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner     static lldb_private::ObjectFile *
48e72dfb32SGreg Clayton     CreateInstance(const lldb::ModuleSP &module_sp,
495ce9c565SGreg Clayton                    lldb::DataBufferSP& data_sp,
505ce9c565SGreg Clayton                    lldb::offset_t data_offset,
5130fdc8d8SChris Lattner                    const lldb_private::FileSpec* file,
525ce9c565SGreg Clayton                    lldb::offset_t file_offset,
535ce9c565SGreg Clayton                    lldb::offset_t length);
5430fdc8d8SChris Lattner 
55c9660546SGreg Clayton     static lldb_private::ObjectFile *
56e72dfb32SGreg Clayton     CreateMemoryInstance (const lldb::ModuleSP &module_sp,
57c9660546SGreg Clayton                           lldb::DataBufferSP& data_sp,
58c9660546SGreg Clayton                           const lldb::ProcessSP &process_sp,
59c9660546SGreg Clayton                           lldb::addr_t header_addr);
60c9660546SGreg Clayton 
61f4d6de6aSGreg Clayton     static size_t
62f4d6de6aSGreg Clayton     GetModuleSpecifications (const lldb_private::FileSpec& file,
63f4d6de6aSGreg Clayton                              lldb::DataBufferSP& data_sp,
64f4d6de6aSGreg Clayton                              lldb::offset_t data_offset,
65f4d6de6aSGreg Clayton                              lldb::offset_t file_offset,
66f4d6de6aSGreg Clayton                              lldb::offset_t length,
67f4d6de6aSGreg Clayton                              lldb_private::ModuleSpecList &specs);
6830fdc8d8SChris Lattner     //------------------------------------------------------------------
69f325ba9dSStephen Wilson     // PluginInterface protocol
7030fdc8d8SChris Lattner     //------------------------------------------------------------------
71*57abc5d6SGreg Clayton     virtual lldb_private::ConstString
72f325ba9dSStephen Wilson     GetPluginName();
7330fdc8d8SChris Lattner 
74f325ba9dSStephen Wilson     virtual uint32_t
75f325ba9dSStephen Wilson     GetPluginVersion();
76f325ba9dSStephen Wilson 
77f325ba9dSStephen Wilson     //------------------------------------------------------------------
78f325ba9dSStephen Wilson     // ObjectFile Protocol.
79f325ba9dSStephen Wilson     //------------------------------------------------------------------
8030fdc8d8SChris Lattner     virtual
8130fdc8d8SChris Lattner     ~ObjectFileELF();
8230fdc8d8SChris Lattner 
8330fdc8d8SChris Lattner     virtual bool
8430fdc8d8SChris Lattner     ParseHeader();
8530fdc8d8SChris Lattner 
8630fdc8d8SChris Lattner     virtual lldb::ByteOrder
8730fdc8d8SChris Lattner     GetByteOrder() const;
8830fdc8d8SChris Lattner 
895aee162fSJim Ingham     virtual bool
905aee162fSJim Ingham     IsExecutable () const;
915aee162fSJim Ingham 
92c7bece56SGreg Clayton     virtual uint32_t
9330fdc8d8SChris Lattner     GetAddressByteSize() const;
9430fdc8d8SChris Lattner 
9530fdc8d8SChris Lattner     virtual lldb_private::Symtab *
9630fdc8d8SChris Lattner     GetSymtab();
9730fdc8d8SChris Lattner 
9830fdc8d8SChris Lattner     virtual lldb_private::SectionList *
9930fdc8d8SChris Lattner     GetSectionList();
10030fdc8d8SChris Lattner 
10130fdc8d8SChris Lattner     virtual void
10230fdc8d8SChris Lattner     Dump(lldb_private::Stream *s);
10330fdc8d8SChris Lattner 
10430fdc8d8SChris Lattner     virtual bool
105514487e8SGreg Clayton     GetArchitecture (lldb_private::ArchSpec &arch);
10630fdc8d8SChris Lattner 
10730fdc8d8SChris Lattner     virtual bool
10830fdc8d8SChris Lattner     GetUUID(lldb_private::UUID* uuid);
10930fdc8d8SChris Lattner 
11030fdc8d8SChris Lattner     virtual uint32_t
11130fdc8d8SChris Lattner     GetDependentModules(lldb_private::FileSpecList& files);
11230fdc8d8SChris Lattner 
1132ab0a585SStephen Wilson     virtual lldb_private::Address
1142ab0a585SStephen Wilson     GetImageInfoAddress();
1152ab0a585SStephen Wilson 
116672e6f59SJim Ingham     virtual lldb_private::Address
117672e6f59SJim Ingham     GetEntryPointAddress ();
1189e00b6a6SGreg Clayton 
1199e00b6a6SGreg Clayton     virtual ObjectFile::Type
1209e00b6a6SGreg Clayton     CalculateType();
1219e00b6a6SGreg Clayton 
1229e00b6a6SGreg Clayton     virtual ObjectFile::Strata
1239e00b6a6SGreg Clayton     CalculateStrata();
124672e6f59SJim Ingham 
125f325ba9dSStephen Wilson private:
126e72dfb32SGreg Clayton     ObjectFileELF(const lldb::ModuleSP &module_sp,
1275ce9c565SGreg Clayton                   lldb::DataBufferSP& data_sp,
1285ce9c565SGreg Clayton                   lldb::offset_t data_offset,
129f325ba9dSStephen Wilson                   const lldb_private::FileSpec* file,
1305ce9c565SGreg Clayton                   lldb::offset_t offset,
1315ce9c565SGreg Clayton                   lldb::offset_t length);
13230fdc8d8SChris Lattner 
133f325ba9dSStephen Wilson     typedef std::vector<elf::ELFProgramHeader>  ProgramHeaderColl;
13430fdc8d8SChris Lattner     typedef ProgramHeaderColl::iterator         ProgramHeaderCollIter;
13530fdc8d8SChris Lattner     typedef ProgramHeaderColl::const_iterator   ProgramHeaderCollConstIter;
13630fdc8d8SChris Lattner 
137f325ba9dSStephen Wilson     typedef std::vector<elf::ELFSectionHeader>  SectionHeaderColl;
13830fdc8d8SChris Lattner     typedef SectionHeaderColl::iterator         SectionHeaderCollIter;
13930fdc8d8SChris Lattner     typedef SectionHeaderColl::const_iterator   SectionHeaderCollConstIter;
14030fdc8d8SChris Lattner 
141499b40e8SStephen Wilson     typedef std::vector<elf::ELFDynamic>        DynamicSymbolColl;
142499b40e8SStephen Wilson     typedef DynamicSymbolColl::iterator         DynamicSymbolCollIter;
143499b40e8SStephen Wilson     typedef DynamicSymbolColl::const_iterator   DynamicSymbolCollConstIter;
144499b40e8SStephen Wilson 
145f325ba9dSStephen Wilson     /// Version of this reader common to all plugins based on this class.
146f325ba9dSStephen Wilson     static const uint32_t m_plugin_version = 1;
147f325ba9dSStephen Wilson 
148f325ba9dSStephen Wilson     /// ELF file header.
149f325ba9dSStephen Wilson     elf::ELFHeader m_header;
150f325ba9dSStephen Wilson 
151f325ba9dSStephen Wilson     /// Collection of program headers.
15230fdc8d8SChris Lattner     ProgramHeaderColl m_program_headers;
153f325ba9dSStephen Wilson 
154f325ba9dSStephen Wilson     /// Collection of section headers.
15530fdc8d8SChris Lattner     SectionHeaderColl m_section_headers;
156f325ba9dSStephen Wilson 
157499b40e8SStephen Wilson     /// Collection of symbols from the dynamic table.
158499b40e8SStephen Wilson     DynamicSymbolColl m_dynamic_symbols;
159499b40e8SStephen Wilson 
160f325ba9dSStephen Wilson     /// List of file specifications corresponding to the modules (shared
161f325ba9dSStephen Wilson     /// libraries) on which this object file depends.
1627b0992d9SGreg Clayton     mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap;
163f325ba9dSStephen Wilson 
164f325ba9dSStephen Wilson     /// Data extractor holding the string table used to resolve section names.
16530fdc8d8SChris Lattner     lldb_private::DataExtractor m_shstr_data;
16630fdc8d8SChris Lattner 
167672e6f59SJim Ingham     /// Cached value of the entry point for this module.
168672e6f59SJim Ingham     lldb_private::Address  m_entry_point_address;
169672e6f59SJim Ingham 
170f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
171c7bece56SGreg Clayton     size_t
172f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollIter &I);
173f325ba9dSStephen Wilson 
174f325ba9dSStephen Wilson     /// Returns a 1 based index of the given section header.
175c7bece56SGreg Clayton     size_t
176f325ba9dSStephen Wilson     SectionIndex(const SectionHeaderCollConstIter &I) const;
177f325ba9dSStephen Wilson 
178f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
179f325ba9dSStephen Wilson     /// m_program_headers.  This method will compute the header list only once.
180f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
18130fdc8d8SChris Lattner     size_t
182f325ba9dSStephen Wilson     ParseProgramHeaders();
18330fdc8d8SChris Lattner 
184f325ba9dSStephen Wilson     /// Parses all section headers present in this object file and populates
185f325ba9dSStephen Wilson     /// m_section_headers.  This method will compute the header list only once.
186f325ba9dSStephen Wilson     /// Returns the number of headers parsed.
18730fdc8d8SChris Lattner     size_t
188f325ba9dSStephen Wilson     ParseSectionHeaders();
18930fdc8d8SChris Lattner 
190f325ba9dSStephen Wilson     /// Scans the dynamic section and locates all dependent modules (shared
191710dd5aeSGreg Clayton     /// libraries) populating m_filespec_ap.  This method will compute the
192f325ba9dSStephen Wilson     /// dependent module list only once.  Returns the number of dependent
193f325ba9dSStephen Wilson     /// modules parsed.
194f325ba9dSStephen Wilson     size_t
195f325ba9dSStephen Wilson     ParseDependentModules();
19630fdc8d8SChris Lattner 
197499b40e8SStephen Wilson     /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The
198499b40e8SStephen Wilson     /// vector retains the order as found in the object file.  Returns the
199499b40e8SStephen Wilson     /// number of dynamic symbols parsed.
200499b40e8SStephen Wilson     size_t
201499b40e8SStephen Wilson     ParseDynamicSymbols();
202499b40e8SStephen Wilson 
203f325ba9dSStephen Wilson     /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method
204f325ba9dSStephen Wilson     /// will parse the symbols only once.  Returns the number of symbols parsed.
205499b40e8SStephen Wilson     unsigned
206f325ba9dSStephen Wilson     ParseSymbolTable(lldb_private::Symtab *symbol_table,
207499b40e8SStephen Wilson                      lldb::user_id_t start_id,
208499b40e8SStephen Wilson                      const elf::ELFSectionHeader *symtab_section,
209f325ba9dSStephen Wilson                      lldb::user_id_t symtab_id);
210f325ba9dSStephen Wilson 
211499b40e8SStephen Wilson     /// Scans the relocation entries and adds a set of artificial symbols to the
212499b40e8SStephen Wilson     /// given symbol table for each PLT slot.  Returns the number of symbols
213499b40e8SStephen Wilson     /// added.
214499b40e8SStephen Wilson     unsigned
215499b40e8SStephen Wilson     ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
216499b40e8SStephen Wilson                            lldb::user_id_t start_id,
217499b40e8SStephen Wilson                            const elf::ELFSectionHeader *rela_hdr,
218499b40e8SStephen Wilson                            lldb::user_id_t section_id);
219499b40e8SStephen Wilson 
220f325ba9dSStephen Wilson     /// Loads the section name string table into m_shstr_data.  Returns the
221f325ba9dSStephen Wilson     /// number of bytes constituting the table.
222f325ba9dSStephen Wilson     size_t
223f325ba9dSStephen Wilson     GetSectionHeaderStringTable();
224f325ba9dSStephen Wilson 
225f325ba9dSStephen Wilson     /// Utility method for looking up a section given its name.  Returns the
226f325ba9dSStephen Wilson     /// index of the corresponding section or zero if no section with the given
227f325ba9dSStephen Wilson     /// name can be found (note that section indices are always 1 based, and so
228f325ba9dSStephen Wilson     /// section index 0 is never valid).
229f325ba9dSStephen Wilson     lldb::user_id_t
230f325ba9dSStephen Wilson     GetSectionIndexByName(const char *name);
231f325ba9dSStephen Wilson 
232499b40e8SStephen Wilson     // Returns the ID of the first section that has the given type.
233499b40e8SStephen Wilson     lldb::user_id_t
234499b40e8SStephen Wilson     GetSectionIndexByType(unsigned type);
235499b40e8SStephen Wilson 
236499b40e8SStephen Wilson     /// Returns the section header with the given id or NULL.
237499b40e8SStephen Wilson     const elf::ELFSectionHeader *
238499b40e8SStephen Wilson     GetSectionHeaderByIndex(lldb::user_id_t id);
239499b40e8SStephen Wilson 
240f325ba9dSStephen Wilson     /// @name  ELF header dump routines
241f325ba9dSStephen Wilson     //@{
24230fdc8d8SChris Lattner     static void
243f325ba9dSStephen Wilson     DumpELFHeader(lldb_private::Stream *s, const elf::ELFHeader& header);
24430fdc8d8SChris Lattner 
24530fdc8d8SChris Lattner     static void
24630fdc8d8SChris Lattner     DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
247f325ba9dSStephen Wilson                                   unsigned char ei_data);
24830fdc8d8SChris Lattner 
249f325ba9dSStephen Wilson     static void
250f325ba9dSStephen Wilson     DumpELFHeader_e_type(lldb_private::Stream *s, elf::elf_half e_type);
251f325ba9dSStephen Wilson     //@}
252f325ba9dSStephen Wilson 
253f325ba9dSStephen Wilson     /// @name ELF program header dump routines
254f325ba9dSStephen Wilson     //@{
25530fdc8d8SChris Lattner     void
25630fdc8d8SChris Lattner     DumpELFProgramHeaders(lldb_private::Stream *s);
25730fdc8d8SChris Lattner 
25830fdc8d8SChris Lattner     static void
25930fdc8d8SChris Lattner     DumpELFProgramHeader(lldb_private::Stream *s,
260f325ba9dSStephen Wilson                          const elf::ELFProgramHeader &ph);
26130fdc8d8SChris Lattner 
26230fdc8d8SChris Lattner     static void
263f325ba9dSStephen Wilson     DumpELFProgramHeader_p_type(lldb_private::Stream *s, elf::elf_word p_type);
26430fdc8d8SChris Lattner 
26530fdc8d8SChris Lattner     static void
26630fdc8d8SChris Lattner     DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
267f325ba9dSStephen Wilson                                  elf::elf_word p_flags);
268f325ba9dSStephen Wilson     //@}
26930fdc8d8SChris Lattner 
270f325ba9dSStephen Wilson     /// @name ELF section header dump routines
271f325ba9dSStephen Wilson     //@{
27230fdc8d8SChris Lattner     void
27330fdc8d8SChris Lattner     DumpELFSectionHeaders(lldb_private::Stream *s);
27430fdc8d8SChris Lattner 
27530fdc8d8SChris Lattner     static void
27630fdc8d8SChris Lattner     DumpELFSectionHeader(lldb_private::Stream *s,
277f325ba9dSStephen Wilson                          const elf::ELFSectionHeader& sh);
27830fdc8d8SChris Lattner 
27930fdc8d8SChris Lattner     static void
28030fdc8d8SChris Lattner     DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
281f325ba9dSStephen Wilson                                  elf::elf_word sh_type);
28230fdc8d8SChris Lattner 
28330fdc8d8SChris Lattner     static void
28430fdc8d8SChris Lattner     DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
285c7bece56SGreg Clayton                                   elf::elf_xword sh_flags);
286f325ba9dSStephen Wilson     //@}
28730fdc8d8SChris Lattner 
288f325ba9dSStephen Wilson     /// ELF dependent module dump routine.
289f325ba9dSStephen Wilson     void
290f325ba9dSStephen Wilson     DumpDependentModules(lldb_private::Stream *s);
29130fdc8d8SChris Lattner 
292499b40e8SStephen Wilson     const elf::ELFDynamic *
293499b40e8SStephen Wilson     FindDynamicSymbol(unsigned tag);
294499b40e8SStephen Wilson 
295499b40e8SStephen Wilson     lldb_private::Section *
296499b40e8SStephen Wilson     PLTSection();
297499b40e8SStephen Wilson 
298499b40e8SStephen Wilson     unsigned
299499b40e8SStephen Wilson     PLTRelocationType();
30030fdc8d8SChris Lattner };
30130fdc8d8SChris Lattner 
30230fdc8d8SChris Lattner #endif // #ifndef liblldb_ObjectFileELF_h_
303