1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #ifndef ELFREADER_H
30 #define ELFREADER_H
31 
32 #include <QtCore/QtEndian>
33 #include <QtCore/QString>
34 #include <QtCore/QVector>
35 
36 QT_BEGIN_NAMESPACE
37 
38 enum ElfProgramHeaderType
39 {
40     Elf_PT_NULL    = 0,
41     Elf_PT_LOAD    = 1,
42     Elf_PT_DYNAMIC = 2,
43     Elf_PT_INTERP  = 3,
44     Elf_PT_NOTE    = 4,
45     Elf_PT_SHLIB   = 5,
46     Elf_PT_PHDR    = 6,
47     Elf_PT_TLS     = 7,
48     Elf_PT_NUM     = 8
49 };
50 
51 enum ElfSectionHeaderType
52 {
53     Elf_SHT_NULL          = 0,
54     Elf_SHT_PROGBITS      = 1,
55     Elf_SHT_SYMTAB        = 2,
56     Elf_SHT_STRTAB        = 3,
57     Elf_SHT_RELA          = 4,
58     Elf_SHT_HASH          = 5,
59     Elf_SHT_DYNAMIC       = 6,
60     Elf_SHT_NOTE          = 7,
61     Elf_SHT_NOBITS        = 8,
62     Elf_SHT_REL           = 9,
63     Elf_SHT_SHLIB         = 10,
64     Elf_SHT_DYNSYM        = 11,
65     Elf_SHT_INIT_ARRAY    = 14,
66     Elf_SHT_FINI_ARRAY    = 15,
67     Elf_SHT_PREINIT_ARRAY = 16,
68     Elf_SHT_GROUP         = 17,
69     Elf_SHT_SYMTAB_SHNDX  = 18
70 };
71 
72 enum ElfEndian
73 {
74     Elf_ELFDATANONE = 0,
75     Elf_ELFDATA2LSB = 1,
76     Elf_ELFDATA2MSB = 2,
77     Elf_ELFDATANUM  = 3
78 };
79 
80 enum ElfClass
81 {
82     Elf_ELFCLASS32 = 1,
83     Elf_ELFCLASS64 = 2
84 };
85 
86 enum ElfType
87 {
88     Elf_ET_NONE = 0,
89     Elf_ET_REL  = 1,
90     Elf_ET_EXEC = 2,
91     Elf_ET_DYN  = 3,
92     Elf_ET_CORE = 4
93 };
94 
95 enum ElfMachine
96 {
97     Elf_EM_386    =  3,
98     Elf_EM_ARM    = 40,
99     Elf_EM_X86_64 = 62
100 };
101 
102 enum DebugSymbolsType
103 {
104     UnknownSymbols   = 0,    // Unknown.
105     NoSymbols        = 1,    // No usable symbols.
106     LinkedSymbols    = 2,    // Link to symols available.
107     BuildIdSymbols   = 4,    // BuildId available.
108     PlainSymbols     = 8,    // Ordinary symbols available.
109     FastSymbols      = 16    // Dwarf index available.
110 };
111 
112 class ElfSectionHeader
113 {
114 public:
115     QByteArray name;
116     quint32 index;
117     quint32 type;
118     quint32 flags;
119     quint64 offset;
120     quint64 size;
121     quint64 addr;
122 };
123 
124 class ElfProgramHeader
125 {
126 public:
127     quint32 name;
128     quint32 type;
129     quint64 offset;
130     quint64 filesz;
131     quint64 memsz;
132 };
133 
134 class ElfData
135 {
136 public:
ElfData()137     ElfData() : symbolsType(UnknownSymbols) {}
138     int indexOf(const QByteArray &name) const;
139 
140 public:
141     ElfEndian  endian;
142     ElfType    elftype;
143     ElfMachine elfmachine;
144     ElfClass   elfclass;
145     quint64    entryPoint;
146     QByteArray debugLink;
147     QByteArray buildId;
148     DebugSymbolsType symbolsType;
149     QVector<ElfSectionHeader> sectionHeaders;
150     QVector<ElfProgramHeader> programHeaders;
151 };
152 
153 class ElfReader
154 {
155 public:
156     explicit ElfReader(const QString &binary);
157     enum Result { Ok, NotElf, Corrupt };
158 
159     ElfData readHeaders();
160     QByteArray readSection(const QByteArray &sectionName);
errorString()161     QString errorString() const { return m_errorString; }
162     QByteArray readCoreName(bool *isCore);
163     QList<QByteArray> dependencies();
164 
165 private:
166     friend class ElfMapper;
167     Result readIt();
168 
169     QString m_binary;
170     QString m_errorString;
171     ElfData m_elfData;
172 };
173 
174 QT_END_NAMESPACE
175 
176 #endif // ELFREADER_H
177