blob: 5f51d8dc5954f8053051b05c33cf207d0c75208f (
plain)
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef POINTER_CONVERTER_H
#define POINTER_CONVERTER_H
#include <hooks/hooks.h>
namespace isc {
namespace hooks {
/// @brief Local class for conversion of void pointers to function pointers
///
/// Converting between void* and function pointers in C++ is fraught with
/// difficulty and pitfalls, e.g. see
/// https://groups.google.com/forum/?hl=en&fromgroups#!topic/comp.lang.c++/37o0l8rtEE0
///
/// The method given in that article - convert using a union is used here. A
/// union is declared (and zeroed) and the appropriate member extracted when
/// needed.
class PointerConverter {
public:
/// @brief Constructor
///
/// Zeroes the union and stores the void* pointer we wish to convert (the
/// one returned by dlsym).
///
/// @param dlsym_ptr void* pointer returned by call to dlsym()
PointerConverter(void* dlsym_ptr) {
memset(&pointers_, 0, sizeof(pointers_));
pointers_.dlsym_ptr = dlsym_ptr;
}
/// @brief Constructor
///
/// Zeroes the union and stores the CalloutPtr pointer we wish to convert.
/// This constructor is used in debug messages; output of a pointer to
/// an object (including to a function) is, on some compilers, printed as
/// "1".
///
/// @param callout_ptr Pointer to callout function
PointerConverter(CalloutPtr callout_ptr) {
memset(&pointers_, 0, sizeof(pointers_));
pointers_.callout_ptr = callout_ptr;
}
/// @name Pointer accessor functions
///
/// It is up to the caller to ensure that the correct member is called so
/// that the correct type of pointer is returned.
///
///@{
/// @brief Return pointer returned by dlsym call
///
/// @return void* pointer returned by the call to dlsym(). This can be
/// used in statements that print the hexadecimal value of the
/// symbol.
void* dlsymPtr() const {
return (pointers_.dlsym_ptr);
}
/// @brief Return pointer to callout function
///
/// @return Pointer to the callout function
CalloutPtr calloutPtr() const {
return (pointers_.callout_ptr);
}
/// @brief Return pointer to load function
///
/// @return Pointer to the load function
load_function_ptr loadPtr() const {
return (pointers_.load_ptr);
}
/// @brief Return pointer to unload function
///
/// @return Pointer to the unload function
unload_function_ptr unloadPtr() const {
return (pointers_.unload_ptr);
}
/// @brief Return pointer to version function
///
/// @return Pointer to the version function
version_function_ptr versionPtr() const {
return (pointers_.version_ptr);
}
/// @brief Return pointer to multi_threading_compatible function
///
/// @return Pointer to the multi_threading_compatible function
multi_threading_compatible_function_ptr multiThreadingCompatiblePtr() const {
return (pointers_.multi_threading_compatible_ptr);
}
///@}
private:
/// @brief Union linking void* and pointers to functions.
union {
void* dlsym_ptr; // void* returned by dlsym
CalloutPtr callout_ptr; // Pointer to callout
load_function_ptr load_ptr; // Pointer to load function
unload_function_ptr unload_ptr; // Pointer to unload function
version_function_ptr version_ptr; // Pointer to version function
multi_threading_compatible_function_ptr multi_threading_compatible_ptr;
// Pointer to multi_threading_compatible function
} pointers_;
};
} // namespace hooks
} // namespace isc
#endif // POINTER_CONVERTER_H
|