1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
/*
Copyright 2012 Canonical
This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
*/
#include "qttestability.h"
#include <link.h>
#include <string>
#include <iostream>
typedef enum
{
QT_VERSION_4,
QT_VERSION_5,
QT_VERSION_UNKNOWN
} QtVersion;
static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
(void) size;
QtVersion *v = (QtVersion*) data;
if (*v == QT_VERSION_UNKNOWN)
{
std::string lib_path(info->dlpi_name);
if (lib_path.rfind("libQtCore.so.4") != std::string::npos)
{
*v = QT_VERSION_4;
}
else if (lib_path.rfind("libQtCore.so.5") != std::string::npos || lib_path.rfind("libQt5Core.so.5") != std::string::npos)
{
*v = QT_VERSION_5;
}
}
return 0;
}
void qt_testability_init(void)
{
QtVersion version = QT_VERSION_UNKNOWN;
dl_iterate_phdr(callback, &version);
std::string driver_name;
if (version == QT_VERSION_4)
{
driver_name = "libautopilot_driver_qt4.so.1";
}
else if (version == QT_VERSION_5)
{
driver_name = "libautopilot_driver_qt5.so.1";
}
else
{
std::cerr << "We don't seem to link to version 4 or 5 of QtCore." << std::endl
<< "Unable to determine which autopilot driver to load." << std::endl
<< "Autopilot introspection will not be available for this process." << std::endl;
return;
}
void* driver = dlopen(driver_name.c_str(), RTLD_LAZY);
if (!driver)
{
std::cerr << "Cannot load library: " << dlerror() << std::endl
<< "Autopilot introspection will not be available for this process." << std::endl;
return;
}
// load the entry point function for the actual driver:
typedef void (*entry_t)();
// clear errors:
dlerror();
entry_t entry_point = (entry_t) dlsym(driver, "qt_testability_init");
const char* err = dlerror();
if (err)
{
std::cerr << "Cannot load library entry point symbol: " << err << std::endl
<< "Autopilot introspection will not be available for this process." << std::endl;
return;
}
entry_point();
}
|