zip_sources.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #!/usr/bin/env python3
  2. #
  3. # Copyright 2016 The Chromium Authors. All rights reserved.
  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. Invoked by libfuzzer buildbots. Executes dwarfdump to parse debug info.
  8. """
  9. from __future__ import print_function
  10. import argparse
  11. import os
  12. import re
  13. import subprocess
  14. import zipfile
  15. compile_unit_re = re.compile('.*DW_TAG_compile_unit.*')
  16. at_name_re = re.compile('.*DW_AT_name.*"(.*)".*')
  17. def main():
  18. parser = argparse.ArgumentParser(description="Zip binary sources.")
  19. parser.add_argument('--binary', required=True,
  20. help='binary file to read')
  21. parser.add_argument('--workdir', required=True,
  22. help='working directory to use to resolve relative paths')
  23. parser.add_argument('--srcdir', required=True,
  24. help='sources root directory to calculate zip entry names')
  25. parser.add_argument('--output', required=True,
  26. help='output zip file name')
  27. parser.add_argument('--dwarfdump', required=False,
  28. default='dwarfdump', help='path to dwarfdump utility')
  29. args = parser.parse_args()
  30. # Dump .debug_info section.
  31. out = subprocess.check_output(
  32. [args.dwarfdump, '-i', args.binary])
  33. looking_for_unit = True
  34. compile_units = set()
  35. # Look for DW_AT_name within DW_TAG_compile_unit
  36. for line in out.splitlines():
  37. if looking_for_unit and compile_unit_re.match(line):
  38. looking_for_unit = False
  39. elif not looking_for_unit:
  40. match = at_name_re.match(line)
  41. if match:
  42. compile_units.add(match.group(1))
  43. looking_for_unit = True
  44. # Zip sources.
  45. with zipfile.ZipFile(args.output, 'w') as z:
  46. for compile_unit in sorted(compile_units):
  47. src_file = os.path.abspath(os.path.join(args.workdir, compile_unit))
  48. print(src_file)
  49. z.write(src_file, os.path.relpath(src_file, args.srcdir))
  50. if __name__ == '__main__':
  51. main()