#!/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()