File indexing completed on 2024-05-19 05:44:08
0001 /* 0002 Copyright (C) 2013-2014 Volker Krause <vkrause@kde.org> 0003 0004 This program is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <https://www.gnu.org/licenses/>. 0016 */ 0017 0018 #ifndef ELFFILE_H 0019 #define ELFFILE_H 0020 0021 #include "elfsectionheader.h" 0022 #include "elfsection.h" 0023 #include "elfdynamicsection.h" 0024 #include "elfreverserelocator.h" 0025 0026 #include <QFile> 0027 #include <QMetaType> 0028 #include <QVector> 0029 0030 #include <memory> 0031 0032 class DwarfInfo; 0033 class ElfHashSection; 0034 class ElfHeader; 0035 class ElfSymbolTableSection; 0036 class ElfSegmentHeader; 0037 0038 /** Represents a ELF file. */ 0039 class ElfFile 0040 { 0041 public: 0042 explicit ElfFile(const QString &fileName); 0043 ElfFile(const ElfFile &other) = delete; 0044 /** Closes the file. */ 0045 ~ElfFile(); 0046 0047 ElfFile& operator=(const ElfFile &other) = delete; 0048 0049 /** Open the file and parse its content. Must be called before the file can be used. */ 0050 bool open(QIODevice::OpenMode openMode); 0051 void close(); 0052 0053 0054 /** Returns @c true if the file could be loaded and is parsed correctly. */ 0055 bool isValid() const; 0056 0057 /** Returns a user readable label for this file. */ 0058 QString displayName() const; 0059 /** Returns the full path of this file. */ 0060 QString fileName() const; 0061 /** Returns the size of the entire file. */ 0062 uint64_t size() const; 0063 0064 /** Returns a pointer to the raw ELF data. */ 0065 unsigned char* rawData() const; 0066 0067 /** ELF class type (32/64 bit). */ 0068 int type() const; 0069 /** Returns the numbers of bytes needed to store an address. */ 0070 int addressSize() const; 0071 /** Endianess. */ 0072 int byteOrder() const; 0073 /** OS ABI. */ 0074 uint8_t osAbi() const; 0075 0076 /** Returns the ELF header. */ 0077 ElfHeader* header() const; 0078 0079 /** Returns the number of sections. 0080 * Use this rather than header()->sectionHeaderCount() to include sections merged 0081 * from separate debug files. 0082 */ 0083 int sectionCount() const; 0084 /** Returns a list of all available section headers. */ 0085 QVector<ElfSectionHeader*> sectionHeaders() const; 0086 /** Returns the section at index @p index. */ 0087 template <typename T> 0088 inline T* section(int index) const 0089 { 0090 return dynamic_cast<T*>(m_sections.at(index)); 0091 } 0092 /** Finds a section by type. */ 0093 int indexOfSection(uint32_t type) const; 0094 /** Finds a section by name. */ 0095 int indexOfSection(const char* name) const; 0096 /** Finds the section containing @p virtAddr. */ 0097 int indexOfSectionWithVirtualAddress(uint64_t virtAddr) const; 0098 0099 /** Returns the dynamic section. */ 0100 ElfDynamicSection* dynamicSection() const; 0101 /** Returns .symtab if present, .dynsym otherwise. */ 0102 ElfSymbolTableSection* symbolTable() const; 0103 /** Returns a symbol table hash section for fast lookup. */ 0104 ElfHashSection* hash() const; 0105 /** Reverse relocation lookup. */ 0106 const ElfReverseRelocator* reverseRelocator() const; 0107 0108 /** Returns the build-id, if present. */ 0109 QByteArray buildId() const; 0110 0111 /** Sets the path to a separate file containing the DWARF debug information. */ 0112 void setSeparateDebugFile(const QString &fileName); 0113 /** Returns the separate debug file, if present. */ 0114 ElfFile* separateDebugFile() const; 0115 /** Returns @c true if this is a separate debug file. */ 0116 bool isSeparateDebugFile() const; 0117 /** Returns the file with the actual content if this is a separate debug file. */ 0118 ElfFile* contentFile() const; 0119 0120 /** DWARF debug information, if present. */ 0121 DwarfInfo* dwarfInfo() const; 0122 0123 /** Returns a lost of all available segment headers. */ 0124 QVector<ElfSegmentHeader*> segmentHeaders() const; 0125 0126 private: 0127 void parse(); 0128 void parseHeader(); 0129 void parseSections(); 0130 void parseSection(uint16_t index); 0131 void parseSegments(); 0132 0133 private: 0134 QFile m_file; 0135 uchar *m_data; 0136 std::unique_ptr<ElfHeader> m_header; 0137 QVector<ElfSectionHeader*> m_sectionHeaders; 0138 QVector<ElfSection*> m_sections; 0139 ElfDynamicSection* m_dynamicSection = nullptr; 0140 ElfHashSection* m_hashSection = nullptr; 0141 ElfReverseRelocator m_reverseReloc; 0142 std::unique_ptr<ElfFile> m_separateDebugFile; 0143 ElfFile *m_contentFile = nullptr; // the counter part for a separate debug file 0144 DwarfInfo *m_dwarfInfo = nullptr; 0145 QVector<ElfSegmentHeader*> m_segmentHeaders; 0146 }; 0147 0148 Q_DECLARE_METATYPE(ElfFile*) 0149 0150 #endif // ELFFILE_H