plugin/qelfparser_p.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
5** -
6** This file is part of the QtCore module of the Qt Toolkit. -
7** -
8** $QT_BEGIN_LICENSE:LGPL$ -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/contact-us. -
16** -
17** GNU Lesser General Public License Usage -
18** Alternatively, this file may be used under the terms of the GNU Lesser -
19** General Public License version 2.1 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qelfparser_p.h" -
43 -
44#ifndef QT_NO_LIBRARY -
45#if defined (Q_OF_ELF) && defined(Q_CC_GNU) -
46 -
47#include "qlibrary_p.h" -
48#include <qdebug.h> -
49 -
50QT_BEGIN_NAMESPACE -
51 -
52// #define QELFPARSER_DEBUG 1 -
53 -
54const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh) -
55{ -
56 sh->name = read<qelfword_t>(data);
executed (the execution status of this line is deduced): sh->name = read<qelfword_t>(data);
-
57 data += sizeof(qelfword_t); // sh_name
executed (the execution status of this line is deduced): data += sizeof(qelfword_t);
-
58 sh->type = read<qelfword_t>(data);
executed (the execution status of this line is deduced): sh->type = read<qelfword_t>(data);
-
59 data += sizeof(qelfword_t) // sh_type
executed (the execution status of this line is deduced): data += sizeof(qelfword_t)
-
60 + sizeof(qelfaddr_t) // sh_flags
executed (the execution status of this line is deduced): + sizeof(qelfaddr_t)
-
61 + sizeof(qelfaddr_t); // sh_addr
executed (the execution status of this line is deduced): + sizeof(qelfaddr_t);
-
62 sh->offset = read<qelfoff_t>(data);
executed (the execution status of this line is deduced): sh->offset = read<qelfoff_t>(data);
-
63 data += sizeof(qelfoff_t); // sh_offset
executed (the execution status of this line is deduced): data += sizeof(qelfoff_t);
-
64 sh->size = read<qelfoff_t>(data);
executed (the execution status of this line is deduced): sh->size = read<qelfoff_t>(data);
-
65 data += sizeof(qelfoff_t); // sh_size
executed (the execution status of this line is deduced): data += sizeof(qelfoff_t);
-
66 return data;
executed: return data;
Execution Count:3948
3948
67} -
68 -
69int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen) -
70{ -
71#if defined(QELFPARSER_DEBUG) -
72 qDebug() << "QElfParser::parse " << library; -
73#endif -
74 -
75 if (fdlen < 64){
evaluated: fdlen < 64
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:484
2-484
76 if (lib)
partially evaluated: lib
TRUEFALSE
yes
Evaluation Count:2
no
Evaluation Count:0
0-2
77 lib->errorString = QLibrary::tr("'%1' is not an ELF object (%2)").arg(library).arg(QLatin1String("file too small"));
executed: lib->errorString = QLibrary::tr("'%1' is not an ELF object (%2)").arg(library).arg(QLatin1String("file too small"));
Execution Count:2
2
78 return NotElf;
executed: return NotElf;
Execution Count:2
2
79 } -
80 const char *data = dataStart;
executed (the execution status of this line is deduced): const char *data = dataStart;
-
81 if (qstrncmp(data, "\177ELF", 4) != 0) {
evaluated: qstrncmp(data, "\177ELF", 4) != 0
TRUEFALSE
yes
Evaluation Count:253
yes
Evaluation Count:231
231-253
82 if (lib)
partially evaluated: lib
TRUEFALSE
yes
Evaluation Count:253
no
Evaluation Count:0
0-253
83 lib->errorString = QLibrary::tr("'%1' is not an ELF object").arg(library);
executed: lib->errorString = QLibrary::tr("'%1' is not an ELF object").arg(library);
Execution Count:253
253
84 return NotElf;
executed: return NotElf;
Execution Count:253
253
85 } -
86 // 32 or 64 bit -
87 if (data[4] != 1 && data[4] != 2) {
partially evaluated: data[4] != 1
TRUEFALSE
yes
Evaluation Count:231
no
Evaluation Count:0
partially evaluated: data[4] != 2
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
88 if (lib)
never evaluated: lib
0
89 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd cpu architecture"));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd cpu architecture"));
0
90 return Corrupt;
never executed: return Corrupt;
0
91 } -
92 m_bits = (data[4] << 5);
executed (the execution status of this line is deduced): m_bits = (data[4] << 5);
-
93 -
94 /* If you remove this check, to read ELF objects of a different arch, please make sure you modify the typedefs -
95 to match the _plugin_ architecture. -
96 */ -
97 if ((sizeof(void*) == 4 && m_bits != 32) || (sizeof(void*) == 8 && m_bits != 64)) {
partially evaluated: sizeof(void*) == 4
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
never evaluated: m_bits != 32
partially evaluated: sizeof(void*) == 8
TRUEFALSE
yes
Evaluation Count:231
no
Evaluation Count:0
partially evaluated: m_bits != 64
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
98 if (lib)
never evaluated: lib
0
99 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("wrong cpu architecture"));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("wrong cpu architecture"));
0
100 return Corrupt;
never executed: return Corrupt;
0
101 } -
102 // endian -
103 if (data[5] == 0) {
partially evaluated: data[5] == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
104 if (lib)
never evaluated: lib
0
105 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd endianess"));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd endianess"));
0
106 return Corrupt;
never executed: return Corrupt;
0
107 } -
108 m_endian = (data[5] == 1 ? ElfLittleEndian : ElfBigEndian);
partially evaluated: data[5] == 1
TRUEFALSE
yes
Evaluation Count:231
no
Evaluation Count:0
0-231
109 -
110 data += 16 // e_ident
executed (the execution status of this line is deduced): data += 16
-
111 + sizeof(qelfhalf_t) // e_type
executed (the execution status of this line is deduced): + sizeof(qelfhalf_t)
-
112 + sizeof(qelfhalf_t) // e_machine
executed (the execution status of this line is deduced): + sizeof(qelfhalf_t)
-
113 + sizeof(qelfword_t) // e_version
executed (the execution status of this line is deduced): + sizeof(qelfword_t)
-
114 + sizeof(qelfaddr_t) // e_entry
executed (the execution status of this line is deduced): + sizeof(qelfaddr_t)
-
115 + sizeof(qelfoff_t); // e_phoff
executed (the execution status of this line is deduced): + sizeof(qelfoff_t);
-
116 -
117 qelfoff_t e_shoff = read<qelfoff_t> (data);
executed (the execution status of this line is deduced): qelfoff_t e_shoff = read<qelfoff_t> (data);
-
118 data += sizeof(qelfoff_t) // e_shoff
executed (the execution status of this line is deduced): data += sizeof(qelfoff_t)
-
119 + sizeof(qelfword_t); // e_flags
executed (the execution status of this line is deduced): + sizeof(qelfword_t);
-
120 -
121 qelfhalf_t e_shsize = read<qelfhalf_t> (data);
executed (the execution status of this line is deduced): qelfhalf_t e_shsize = read<qelfhalf_t> (data);
-
122 -
123 if (e_shsize > fdlen) {
partially evaluated: e_shsize > fdlen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
124 if (lib)
never evaluated: lib
0
125 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shsize"));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shsize"));
0
126 return Corrupt;
never executed: return Corrupt;
0
127 } -
128 -
129 data += sizeof(qelfhalf_t) // e_ehsize
executed (the execution status of this line is deduced): data += sizeof(qelfhalf_t)
-
130 + sizeof(qelfhalf_t) // e_phentsize
executed (the execution status of this line is deduced): + sizeof(qelfhalf_t)
-
131 + sizeof(qelfhalf_t); // e_phnum
executed (the execution status of this line is deduced): + sizeof(qelfhalf_t);
-
132 -
133 qelfhalf_t e_shentsize = read<qelfhalf_t> (data);
executed (the execution status of this line is deduced): qelfhalf_t e_shentsize = read<qelfhalf_t> (data);
-
134 -
135 if (e_shentsize % 4){
partially evaluated: e_shentsize % 4
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
136 if (lib)
never evaluated: lib
0
137 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shentsize"));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shentsize"));
0
138 return Corrupt;
never executed: return Corrupt;
0
139 } -
140 data += sizeof(qelfhalf_t); // e_shentsize
executed (the execution status of this line is deduced): data += sizeof(qelfhalf_t);
-
141 qelfhalf_t e_shnum = read<qelfhalf_t> (data);
executed (the execution status of this line is deduced): qelfhalf_t e_shnum = read<qelfhalf_t> (data);
-
142 data += sizeof(qelfhalf_t); // e_shnum
executed (the execution status of this line is deduced): data += sizeof(qelfhalf_t);
-
143 qelfhalf_t e_shtrndx = read<qelfhalf_t> (data);
executed (the execution status of this line is deduced): qelfhalf_t e_shtrndx = read<qelfhalf_t> (data);
-
144 data += sizeof(qelfhalf_t); // e_shtrndx
executed (the execution status of this line is deduced): data += sizeof(qelfhalf_t);
-
145 -
146 if ((quint32)(e_shnum * e_shentsize) > fdlen) {
partially evaluated: (quint32)(e_shnum * e_shentsize) > fdlen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
0-231
147 if (lib)
never evaluated: lib
0
148 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size")) .arg(e_shnum).arg(e_shentsize);
0
149 .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size"))
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size")) .arg(e_shnum).arg(e_shentsize);
0
150 .arg(e_shnum).arg(e_shentsize);
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size")) .arg(e_shnum).arg(e_shentsize);
0
151 return Corrupt;
never executed: return Corrupt;
0
152 } -
153 -
154#if defined(QELFPARSER_DEBUG) -
155 qDebug() << e_shnum << "sections starting at " << ("0x" + QByteArray::number(e_shoff, 16)).data() << "each" << e_shentsize << "bytes"; -
156#endif -
157 -
158 ElfSectionHeader strtab;
executed (the execution status of this line is deduced): ElfSectionHeader strtab;
-
159 qulonglong soff = e_shoff + e_shentsize * (e_shtrndx);
executed (the execution status of this line is deduced): qulonglong soff = e_shoff + e_shentsize * (e_shtrndx);
-
160 -
161 if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) {
partially evaluated: (soff + e_shentsize) > fdlen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:231
evaluated: soff % 4
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:230
partially evaluated: soff == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:230
0-231
162 if (lib)
partially evaluated: lib
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
163 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("shstrtab section header seems to be at %1")) .arg(QString::number(soff, 16));
Execution Count:1
1
164 .arg(QLatin1String("shstrtab section header seems to be at %1"))
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("shstrtab section header seems to be at %1")) .arg(QString::number(soff, 16));
Execution Count:1
1
165 .arg(QString::number(soff, 16));
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("shstrtab section header seems to be at %1")) .arg(QString::number(soff, 16));
Execution Count:1
1
166 return Corrupt;
executed: return Corrupt;
Execution Count:1
1
167 } -
168 -
169 parseSectionHeader(dataStart + soff, &strtab);
executed (the execution status of this line is deduced): parseSectionHeader(dataStart + soff, &strtab);
-
170 m_stringTableFileOffset = strtab.offset;
executed (the execution status of this line is deduced): m_stringTableFileOffset = strtab.offset;
-
171 -
172 if ((quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) {
partially evaluated: (quint32)(m_stringTableFileOffset + e_shentsize) >= fdlen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:230
partially evaluated: m_stringTableFileOffset == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:230
0-230
173 if (lib)
never evaluated: lib
0
174 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("string table seems to be at %1")) .arg(QString::number(soff, 16));
0
175 .arg(QLatin1String("string table seems to be at %1"))
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("string table seems to be at %1")) .arg(QString::number(soff, 16));
0
176 .arg(QString::number(soff, 16));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("string table seems to be at %1")) .arg(QString::number(soff, 16));
0
177 return Corrupt;
never executed: return Corrupt;
0
178 } -
179 -
180#if defined(QELFPARSER_DEBUG) -
181 qDebug(".shstrtab at 0x%s", QByteArray::number(m_stringTableFileOffset, 16).data()); -
182#endif -
183 -
184 const char *s = dataStart + e_shoff;
executed (the execution status of this line is deduced): const char *s = dataStart + e_shoff;
-
185 for (int i = 0; i < e_shnum; ++i) {
evaluated: i < e_shnum
TRUEFALSE
yes
Evaluation Count:3718
yes
Evaluation Count:1
1-3718
186 ElfSectionHeader sh;
executed (the execution status of this line is deduced): ElfSectionHeader sh;
-
187 parseSectionHeader(s, &sh);
executed (the execution status of this line is deduced): parseSectionHeader(s, &sh);
-
188 if (sh.name == 0) {
evaluated: sh.name == 0
TRUEFALSE
yes
Evaluation Count:232
yes
Evaluation Count:3486
232-3486
189 s += e_shentsize;
executed (the execution status of this line is deduced): s += e_shentsize;
-
190 continue;
executed: continue;
Execution Count:232
232
191 } -
192 const char *shnam = dataStart + m_stringTableFileOffset + sh.name;
executed (the execution status of this line is deduced): const char *shnam = dataStart + m_stringTableFileOffset + sh.name;
-
193 -
194 if (m_stringTableFileOffset + sh.name > fdlen) {
evaluated: m_stringTableFileOffset + sh.name > fdlen
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:3485
1-3485
195 if (lib)
partially evaluated: lib
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
196 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("section name %2 of %3 behind end of file")) .arg(i).arg(e_shnum);
Execution Count:1
1
197 .arg(QLatin1String("section name %2 of %3 behind end of file"))
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("section name %2 of %3 behind end of file")) .arg(i).arg(e_shnum);
Execution Count:1
1
198 .arg(i).arg(e_shnum);
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("section name %2 of %3 behind end of file")) .arg(i).arg(e_shnum);
Execution Count:1
1
199 return Corrupt;
executed: return Corrupt;
Execution Count:1
1
200 } -
201 -
202#if defined(QELFPARSER_DEBUG) -
203 qDebug() << "++++" << i << shnam; -
204#endif -
205 -
206 if (qstrcmp(shnam, ".qtmetadata") == 0 || qstrcmp(shnam, ".rodata") == 0) {
evaluated: qstrcmp(shnam, ".qtmetadata") == 0
TRUEFALSE
yes
Evaluation Count:227
yes
Evaluation Count:3258
evaluated: qstrcmp(shnam, ".rodata") == 0
TRUEFALSE
yes
Evaluation Count:230
yes
Evaluation Count:3028
227-3258
207 if (!(sh.type & 0x1)) {
evaluated: !(sh.type & 0x1)
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:456
1-456
208 if (shnam[1] == 'r') {
partially evaluated: shnam[1] == 'r'
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
209 if (lib)
partially evaluated: lib
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
210 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("empty .rodata. not a library."));
Execution Count:1
1
211 .arg(QLatin1String("empty .rodata. not a library."));
executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("empty .rodata. not a library."));
Execution Count:1
1
212 return Corrupt;
executed: return Corrupt;
Execution Count:1
1
213 } -
214#if defined(QELFPARSER_DEBUG) -
215 qDebug()<<"section is not program data. skipped."; -
216#endif -
217 s += e_shentsize;
never executed (the execution status of this line is deduced): s += e_shentsize;
-
218 continue;
never executed: continue;
0
219 } -
220 -
221 if (sh.offset == 0 || (sh.offset + sh.size) > fdlen || sh.size < 1) {
partially evaluated: sh.offset == 0
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:456
partially evaluated: (sh.offset + sh.size) > fdlen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:456
partially evaluated: sh.size < 1
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:456
0-456
222 if (lib)
never evaluated: lib
0
223 lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library)
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("missing section data. This is not a library."));
0
224 .arg(QLatin1String("missing section data. This is not a library."));
never executed: lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) .arg(QLatin1String("missing section data. This is not a library."));
0
225 return Corrupt;
never executed: return Corrupt;
0
226 } -
227 *pos = sh.offset;
executed (the execution status of this line is deduced): *pos = sh.offset;
-
228 *sectionlen = sh.size - 1;
executed (the execution status of this line is deduced): *sectionlen = sh.size - 1;
-
229 if (shnam[1] == 'q')
evaluated: shnam[1] == 'q'
TRUEFALSE
yes
Evaluation Count:227
yes
Evaluation Count:229
227-229
230 return QtMetaDataSection;
executed: return QtMetaDataSection;
Execution Count:227
227
231 }
executed: }
Execution Count:229
229
232 s += e_shentsize;
executed (the execution status of this line is deduced): s += e_shentsize;
-
233 }
executed: }
Execution Count:3257
3257
234 return NoQtSection;
executed: return NoQtSection;
Execution Count:1
1
235} -
236 -
237QT_END_NAMESPACE -
238 -
239#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU) -
240#endif // QT_NO_LIBRARY -
241 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial