1 2class CFGArchOptions(object): 3 """ 4 Stores architecture-specific options and settings, as well as the detailed explanation of those options and 5 settings. 6 7 Suppose `ao` is the CFGArchOptions object, and there is an option called `ret_jumpkind_heuristics`, you can access 8 it by `ao.ret_jumpkind_heuristics` and set its value via `ao.ret_jumpkind_heuristics = True` 9 10 :ivar dict OPTIONS: A dict of all default options for different architectures. 11 :ivar archinfo.Arch arch: The architecture object. 12 :ivar dict _options: Values of all CFG options that are specific to the current architecture. 13 """ 14 15 # option name: (option value type, default option value) 16 17 OPTIONS = { 18 'ARMEL': { 19 # Whether to perform some simple heuristics to detect returns that are incorrectly labeled as boring 20 # branches by VEX 21 'ret_jumpkind_heuristics': (bool, True), 22 # Whether to switch between ARM mode and THUMB mode when VEX fails to decode a block 23 'switch_mode_on_nodecode': (bool, False), 24 }, 25 'ARMHF': { 26 'ret_jumpkind_heuristics': (bool, True), 27 'switch_mode_on_nodecode': (bool, False), 28 }, 29 'ARMCortexM': { 30 'ret_jumpkind_heuristics': (bool, True), 31 'switch_mode_on_nodecode': (bool, False), 32 }, 33 } 34 35 arch = None 36 _options = {} 37 38 def __init__(self, arch, **options): 39 """ 40 Constructor. 41 42 :param archinfo.Arch arch: The architecture instance. 43 :param dict options: Architecture-specific options, which will be used to initialize this object. 44 """ 45 46 self.arch = arch 47 48 self._options = {} 49 50 if self.arch.name in self.OPTIONS: 51 for k, (_, value) in self.OPTIONS[self.arch.name].items(): 52 self._options[k] = value 53 54 # make sure options are valid 55 for k in options.keys(): 56 if self.arch.name not in self.OPTIONS or k not in self.OPTIONS[self.arch.name]: 57 raise KeyError('Architecture %s does not support arch-specific option "%s".' % (self.arch.name, k)) 58 59 for k, v in options.items(): 60 self.__setattr__(k, v) 61 62 def __getattr__(self, option_name): 63 if option_name in self._options: 64 return self._options[option_name] 65 66 return self.__getattribute__(option_name) 67 68 def __setattr__(self, option_name, option_value): 69 if option_name in self._options: 70 71 # type checking 72 sort = self.OPTIONS[self.arch.name][option_name][0] 73 74 if sort is None or isinstance(option_value, sort): 75 self._options[option_name] = option_value 76 else: 77 raise ValueError('Value for option "%s" must be of type %s' % (option_name, sort)) 78 79 else: 80 super(CFGArchOptions, self).__setattr__(option_name, option_value ) 81