Chromium Code Reviews| 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() |