1#!/usr/bin/env python3 2# 3# Copyright 2016 The Chromium Authors 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6"""Archive all source files that are references in binary debug info. 7 8Invoked by libfuzzer buildbots. Executes dwarfdump to parse debug info. 9""" 10 11from __future__ import print_function 12 13import argparse 14import os 15import re 16import subprocess 17import zipfile 18 19compile_unit_re = re.compile('.*DW_TAG_compile_unit.*') 20at_name_re = re.compile('.*DW_AT_name.*"(.*)".*') 21 22 23def main(): 24 parser = argparse.ArgumentParser(description='Zip binary sources.') 25 parser.add_argument('--binary', required=True, help='binary file to read') 26 parser.add_argument('--workdir', 27 required=True, 28 help='working directory to use to resolve relative paths') 29 parser.add_argument( 30 '--srcdir', 31 required=True, 32 help='sources root directory to calculate zip entry names') 33 parser.add_argument('--output', required=True, help='output zip file name') 34 parser.add_argument('--dwarfdump', 35 required=False, 36 default='dwarfdump', 37 help='path to dwarfdump utility') 38 args = parser.parse_args() 39 40 # Dump .debug_info section. 41 out = subprocess.check_output([args.dwarfdump, '-i', args.binary]) 42 43 looking_for_unit = True 44 compile_units = set() 45 46 # Look for DW_AT_name within DW_TAG_compile_unit 47 for line in out.splitlines(): 48 if looking_for_unit and compile_unit_re.match(line): 49 looking_for_unit = False 50 elif not looking_for_unit: 51 match = at_name_re.match(line) 52 if match: 53 compile_units.add(match.group(1)) 54 looking_for_unit = True 55 56 # Zip sources. 57 with zipfile.ZipFile(args.output, 'w') as z: 58 for compile_unit in sorted(compile_units): 59 src_file = os.path.abspath(os.path.join(args.workdir, compile_unit)) 60 print(src_file) 61 z.write(src_file, os.path.relpath(src_file, args.srcdir)) 62 63 64if __name__ == '__main__': 65 main() 66