1#!/usr/bin/python2 2# 3# Copyright (c) 2015 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"""Generate or update an existing config (.options file) for libfuzzer test. 7 8Invoked by GN from fuzzer_test.gni. 9""" 10 11import ConfigParser 12import argparse 13import os 14import sys 15 16 17def AddSectionOptions(config, section_name, options): 18 """Add |options| to the |section_name| section of |config|. 19 20 Throws an 21 assertion error if any option in |options| does not have exactly two 22 elements. 23 """ 24 if not options: 25 return 26 27 config.add_section(section_name) 28 for option_and_value in options: 29 assert len(option_and_value) == 2, ( 30 '%s is not an option, value pair' % option_and_value) 31 32 config.set(section_name, *option_and_value) 33 34 35def main(): 36 parser = argparse.ArgumentParser(description='Generate fuzzer config.') 37 parser.add_argument('--config', required=True) 38 parser.add_argument('--dict') 39 parser.add_argument('--libfuzzer_options', nargs='+', default=[]) 40 parser.add_argument('--asan_options', nargs='+', default=[]) 41 parser.add_argument('--msan_options', nargs='+', default=[]) 42 parser.add_argument('--ubsan_options', nargs='+', default=[]) 43 parser.add_argument( 44 '--environment_variables', 45 nargs='+', 46 default=[], 47 choices=['AFL_DRIVER_DONT_DEFER=1']) 48 args = parser.parse_args() 49 50 # Script shouldn't be invoked without any arguments, but just in case. 51 if not (args.dict or args.libfuzzer_options or args.environment_variables or 52 args.asan_options or args.msan_options or args.ubsan_options): 53 return 54 55 config = ConfigParser.ConfigParser() 56 libfuzzer_options = [] 57 if args.dict: 58 libfuzzer_options.append(('dict', os.path.basename(args.dict))) 59 libfuzzer_options.extend( 60 option.split('=') for option in args.libfuzzer_options) 61 62 AddSectionOptions(config, 'libfuzzer', libfuzzer_options) 63 64 AddSectionOptions(config, 'asan', 65 [option.split('=') for option in args.asan_options]) 66 67 AddSectionOptions(config, 'msan', 68 [option.split('=') for option in args.msan_options]) 69 70 AddSectionOptions(config, 'ubsan', 71 [option.split('=') for option in args.ubsan_options]) 72 73 AddSectionOptions( 74 config, 'env', 75 [option.split('=') for option in args.environment_variables]) 76 77 # Generate .options file. 78 config_path = args.config 79 with open(config_path, 'w') as options_file: 80 options_file.write( 81 '# This is an automatically generated config for ClusterFuzz.\n') 82 config.write(options_file) 83 84 85if __name__ == '__main__': 86 main() 87