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 §ion_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