Index: pydir/sz-clang.py |
diff --git a/pydir/sz-clang.py b/pydir/sz-clang.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..be5022cf442d637907517801269f590adaebebbf |
--- /dev/null |
+++ b/pydir/sz-clang.py |
@@ -0,0 +1,84 @@ |
+#!/usr/bin/env python2 |
+ |
+import os |
+import shutil |
+import subprocess |
+import sys |
+import tempfile |
+ |
+from utils import FindBaseNaCl, shellcmd |
+ |
+def subsToMacros(subs): |
+ macros = '#include <stddef.h>\n' |
+ for func in subs: |
+ args = [('{atype} a{num}').format(atype=atype, num=i) for |
+ i, atype in enumerate(subs[func]['sig'][1:])] |
+ macros += ( |
+ '{ftype} {name}({args});\n' |
+ ).format(ftype=subs[func]['sig'][0], |
+ name=subs[func]['sub'], |
+ args=', '.join(args)) |
+ macros += ( |
+ '#define {func}(args...) ({sub}(args))\n' |
+ ).format(func=func, sub=subs[func]['sub']) |
+ return macros |
+ |
+def main(): |
+ """Passes its arguments directly to pnacl-clang. |
+ |
+ If -fsanitize-address is specified, extra information is passed to |
+ pnacl-clang to ensure that later instrumentation in pnacl-sz can be |
+ performed. For example, clang automatically inlines many memory allocation |
+ functions, so this script will redefine them at compile time to make sure |
+ they can be correctly instrumented by pnacl-sz. |
+ """ |
+ pnacl_root = FindBaseNaCl() |
+ dummy_subs = {'calloc': {'sig': ['void *', 'size_t', 'size_t'], |
+ 'sub': '__asan_dummy_calloc'}, |
+ '_calloc': {'sig': ['void *', 'size_t', 'size_t'], |
+ 'sub': '__asan_dummy_calloc'}} |
+ subs_src = ( |
+ '{root}/toolchain_build/src/subzero/pydir/sz_clang_dummies.c' |
+ ).format(root=pnacl_root) |
+ clang = ( |
+ '{root}/toolchain/linux_x86/pnacl_newlib_raw/bin/pnacl-clang' |
+ ).format(root=pnacl_root) |
+ args = sys.argv |
+ args[0] = clang |
+ tmp_dir = '' |
+ if '-fsanitize-address' in args: |
+ args.remove('-fsanitize-address') |
+ include_dirs = set() |
+ tmp_dir = tempfile.mkdtemp() |
+ for i, arg in enumerate(args[1:], 1): |
+ if not os.path.isfile(arg): |
+ continue |
+ src = os.path.basename(arg) |
+ ext = os.path.splitext(arg)[1] |
+ if ext in ['.c', '.cc', '.cpp']: |
+ include_dirs |= {os.path.dirname(arg)} |
+ dest_name = os.path.join(tmp_dir, src) |
+ with open(dest_name, 'w') as dest: |
+ dest.write(subsToMacros(dummy_subs)) |
+ dest.write('#line 1 "{file}"\n'.format(file=arg)) |
+ with open(arg) as src: |
+ for line in src: |
+ dest.write(line) |
+ args[i] = dest_name |
Karl
2016/07/14 17:33:50
Ok. I now understand the following code. I suggest
tlively
2016/07/14 20:26:14
Done.
|
+ if not ('-o' in args and |
+ ('-c' in args or '-S' in args or '-E' in args)): |
+ args.append(subs_src) |
+ for d in include_dirs: |
+ args.append('-iquote {d}'.format(d=d)) |
+ err_code = 0 |
+ try: |
+ shellcmd(args, echo=True) |
+ except subprocess.CalledProcessError as e: |
+ print e.output |
+ err_code = e.returncode |
+ if tmp_dir != '': |
+ shutil.rmtree(tmp_dir) |
+ exit(err_code) |
+ |
+if __name__ == '__main__': |
+ main() |