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
|
import os
import shutil
import subprocess
import sys
import tempfile
SYMBOLS_TO_PATCH = (
'connect',
'poll',
'recv',
'recvfrom',
'send',
'sendto',
)
class Error(Exception):
pass
def find_compiler(args):
for arg in args:
if os.path.basename(arg) in ('clang', 'clang++'):
return arg
raise Error('No known compiler found in the command line')
def find_libraries(project, args):
if not project.endswith('/'):
project = project + '/'
for arg in args:
if arg.startswith(project):
yield arg
def rename_symbol(symbol):
return 'green_{}'.format(symbol)
def patch_object(object_path, objcopy):
args = [objcopy]
for symbol in SYMBOLS_TO_PATCH:
args.extend(('--redefine-sym', '{}={}'.format(symbol, rename_symbol(symbol))))
args.append(object_path)
subprocess.check_call(args)
def patch_library(library_path, ar, objcopy):
tmpdir = tempfile.mkdtemp(dir=os.path.dirname(library_path))
try:
subprocess.check_call((ar, 'x', library_path), cwd=tmpdir)
names = os.listdir(tmpdir)
for name in names:
patch_object(os.path.join(tmpdir, name), objcopy=objcopy)
new_library_path = os.path.join(tmpdir, 'library.a')
subprocess.check_call([ar, 'rcs', new_library_path] + names, cwd=tmpdir)
os.rename(new_library_path, library_path)
finally:
shutil.rmtree(tmpdir)
def main():
try:
args = sys.argv[1:]
compiler = find_compiler(args)
compiler_dir = os.path.dirname(compiler)
def get_tool(name):
path = os.path.join(compiler_dir, name)
if not os.path.exists(path):
raise Error('No {} found alongside the compiler'.format(name))
return path
ar = get_tool('llvm-ar')
objcopy = get_tool('llvm-objcopy')
libraries = tuple(find_libraries('contrib/libs/libmysql_r', args))
for library in libraries:
library_path = os.path.abspath(library)
if not os.path.exists(library_path):
raise Error('No {} file exists'.format(library))
patch_library(library_path, ar=ar, objcopy=objcopy)
except Exception as error:
name = os.path.basename(sys.argv[0])
command = ' '.join(args)
message = '{name} failed: {error}\nCommand line: {command}'
print >> sys.stderr, message.format(**locals())
if __name__ == '__main__':
main()
|