1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite 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 EMULATIONDETECTOR_H
30#define EMULATIONDETECTOR_H
31
32#include <QtCore/qglobal.h>
33
34#if defined(Q_OS_LINUX) && defined(Q_PROCESSOR_ARM)
35#define SHOULD_CHECK_ARM_ON_X86
36
37#include <QFileInfo>
38
39#if QT_CONFIG(process) && QT_CONFIG(regularexpression)
40#include <QProcess>
41#include <QRegularExpression>
42#endif
43
44#endif
45
46QT_BEGIN_NAMESPACE
47
48// Helper functions for detecting if running emulated
49namespace EmulationDetector {
50
51#ifdef SHOULD_CHECK_ARM_ON_X86
52static bool isX86SpecificFileAvailable(void);
53static bool isReportedArchitectureX86(void);
54#endif
55
56/*
57 * Check if we are running Arm binary on x86 machine.
58 *
59 * Currently this is only able to check on Linux. If not able to
60 * detect, return false.
61 */
62static Q_DECL_UNUSED bool isRunningArmOnX86()
63{
64#ifdef SHOULD_CHECK_ARM_ON_X86
65 if (isX86SpecificFileAvailable())
66 return true;
67
68 if (isReportedArchitectureX86())
69 return true;
70#endif
71 return false;
72}
73
74#ifdef SHOULD_CHECK_ARM_ON_X86
75/*
76 * Check if we can find a file that's only available on x86
77 */
78static bool isX86SpecificFileAvailable()
79{
80 // MTRR (Memory Type Range Registers) are a feature of the x86 architecture
81 // and /proc/mtrr is only present (on Linux) for that family.
82 // However, it's an optional kernel feature, so the absence of the file is
83 // not sufficient to conclude we're on real hardware.
84 QFileInfo mtrr("/proc/mtrr");
85 if (mtrr.exists())
86 return true;
87 return false;
88}
89
90/*
91 * Check if architecture reported by the OS is x86
92 */
93static bool isReportedArchitectureX86(void)
94{
95#if QT_CONFIG(process) && QT_CONFIG(regularexpression)
96 QProcess unamer;
97 QString machineString;
98
99 // Using syscall "uname" is not possible since that would be captured by
100 // QEMU and result would be the architecture being emulated (e.g. armv7l).
101 // By using QProcess we get the architecture used by the host.
102 unamer.start("uname -a");
103 if (!unamer.waitForFinished()) {
104 return false;
105 }
106 machineString = unamer.readAll();
107
108 // Is our current host cpu x86?
109 if (machineString.contains(QRegularExpression("i386|i686|x86"))) {
110 return true;
111 }
112#endif
113
114 return false;
115}
116#endif // SHOULD_CHECK_ARM_ON_X86
117
118} // EmulationDetector namespace
119
120QT_END_NAMESPACE
121
122#endif
123
124

source code of qtbase/tests/shared/emulationdetector.h