-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathlibraryPatcher.h
More file actions
79 lines (67 loc) · 2.45 KB
/
Copy pathlibraryPatcher.h
File metadata and controls
79 lines (67 loc) · 2.45 KB
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
#ifndef _LIBRARYPATCHER_H
#define _LIBRARYPATCHER_H
#include "codeCache.h"
#include "spinLock.h"
#include <atomic>
#ifdef __linux__
// Patch libraries' @plt entries
typedef struct _patchEntry {
CodeCache* _lib;
// library's @plt location
void** _location;
// original function
void* _func;
} PatchEntry;
class LibraryPatcher {
private:
static SpinLock _lock;
static const char* _profiler_name;
static PatchEntry _patched_entries[MAX_NATIVE_LIBS];
static int _size;
static bool _patch_pthread_create;
// Separate tracking for sigaction patches
static PatchEntry _sigaction_entries[MAX_NATIVE_LIBS];
static int _sigaction_size;
// Separate tracking for socket (send/recv/write/read) patches.
// Each library can contribute up to 4 GOT slots (send/recv/write/read).
static PatchEntry _socket_entries[4 * MAX_NATIVE_LIBS];
static int _socket_size;
static void patch_library_unlocked(CodeCache* lib);
static void patch_pthread_create();
static void patch_pthread_setspecific();
static void patch_sigaction_in_library(CodeCache* lib);
public:
// True while socket hooks are installed; read by Profiler::dlopen_hook
// to decide whether to re-patch after a new library is loaded.
// Set to true after the first batch of libraries is patched in patch_socket_functions().
// Libraries loaded after profiler start are picked up on the next dlopen_hook call,
// which calls install_socket_hooks() to patch them if _socket_active is true.
// Low-probability race: stop() is called only on JVM exit; atomic<bool> is zero-cost insurance.
static std::atomic<bool> _socket_active;
static void initialize();
static void patch_libraries();
static void unpatch_libraries();
static void patch_sigaction();
static bool patch_socket_functions();
static void unpatch_socket_functions();
// Called from Profiler::dlopen_hook after a new library is loaded.
// No-op when socket hooks are not active.
static inline void install_socket_hooks() {
if (_socket_active.load(std::memory_order_acquire)) {
patch_socket_functions();
}
}
};
#else
class LibraryPatcher {
public:
static void initialize() { }
static void patch_libraries() { }
static void unpatch_libraries() { }
static void patch_sigaction() { }
static bool patch_socket_functions() { return false; }
static void unpatch_socket_functions() { }
static void install_socket_hooks() { }
};
#endif
#endif // _LIBRARYPATCHER_H