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
|
#!/usr/bin/env python
import sys, os
sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), 'script'))
import mconfig
settings = mconfig.settings_root
settings.package_unix_name.value = 'substitute'
c = settings.host_machine().c_tools()
c.cc.required()
c.dsymutil.required()
settings.add_setting_option('imaon2', '--with-imaon2', 'path to imaon2 (optional)', '')
settings.add_setting_option('gen_dia', '--enable-recompile-dia', 'generate darwin-inject-asm.S', False, bool=True)
asm_archs = [
('x86_64', []),
('i386', []),
('arm', ['-marm']),
('arm64', []), # XXX
]
machs = []
for name, cflags in asm_archs:
mach = mconfig.Machine('asm-' + name, settings, 'for cross-compiling the inject baton', name + '-apple-darwin10')
machs.append(mach)
cc = mach.c_tools().cc
cc.optional()
def f():
if settings.gen_dia:
cc.argv()
mach_settings = settings[mach.name]
mach_settings.cflags = cflags + mach_settings.cflags
mconfig.post_parse_args_will_need.append(f)
mconfig.parse_args()
####################################
mconfig.mark_safe_to_clean('(src)/generated/darwin-inject-asm.S', settings)
settings.host.cflags = ['-I%s/lib' % (settings.src,)] + settings.host.cflags
settings.host.debug_info = True
emitter = settings.emitter
balco = lambda *args, **kwargs: mconfig.build_and_link_c_objs(emitter, settings.host_machine(), settings, *args, **kwargs)
def cb(fn):
if fn.endswith('/objc.c'):
return settings.specialize(obj_ldflag_sets=[('-lobjc',)])
return settings
# Note: the order of darwin-inject-asm.o is significant. Per man page, ld is
# guaranteed to link objects in order, which is necessary because
# darwin-inject-asm.S does not itself ensure there is at least 0x4000 bytes of
# executable stuff after inject_page_start (so that arm can remap into arm64).
# By putting it at the beginning, we can just reuse the space for the rest of
# the library rather than having to pad with zeroes.
# (This only matters on 32-bit ARM, and the text segment is currently 0xa000
# bytes there, more than enough.)
balco(
'dylib',
'(out)/libsubstitute.dylib',
[
'(src)/generated/darwin-inject-asm.S',
'(src)/lib/darwin/find-syms.c',
'(src)/lib/darwin/inject.c',
'(src)/lib/darwin/interpose.c',
'(src)/lib/darwin/objc-asm.S',
'(src)/lib/darwin/objc.c',
'(src)/lib/darwin/read.c',
'(src)/lib/darwin/substrate-compat.c',
'(src)/lib/darwin/execmem.c',
'(src)/lib/cbit/vec.c',
'(src)/lib/jump-dis.c',
'(src)/lib/transform-dis.c',
'(src)/lib/hook-functions.c',
'(src)/lib/strerror.c',
],
settings_cb=cb
)
#settings.test = 'foo baz'
if settings.gen_dia:
bins = []
for (name, _cflags), mach in zip(asm_archs, machs):
exe = '(out)/inject-asm-raw-%s' % (name,)
bin = exe + '.bin'
mconfig.build_and_link_c_objs(emitter, mach,
settings.specialize(
override_obj_fn='(out)/inject-asm-raw-%s.o' % (name,),
override_ldflags=['-Wl,-order_file,(src)/lib/darwin/inject-asm-raw.order'] + settings[mach.name].ldflags,
),
'exec',
exe,
['(src)/lib/darwin/inject-asm-raw.c'])
bins.append(bin)
emitter.add_command(settings, [bin], [exe], ['segedit -extract __TEXT __text (outs[0]) (ins[0])'])
emitter.add_command(settings, ['(src)/generated/darwin-inject-asm.S'], bins, [['(src)/script/gen-inject-asm.sh', '(out)'] + bins])
emitter.add_command(settings, ['all'], ['(out)/libsubstitute.dylib'], [], phony=True)
emitter.set_default_rule('all')
mconfig.finish_and_emit()
|