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 10535729bb1SAshok Thirumurthi virtual lldb_private::Symbol * 10635729bb1SAshok Thirumurthi ResolveSymbolForAddress(const lldb_private::Address& so_addr, bool verify_unique); 10735729bb1SAshok 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 130*5480365bSEd Maste GetImageInfoAddress(lldb_private::Target *target); 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 §ion_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