Adds comments and some more formatting changes

pull/281/head
rajeevgopalakrishna 6 years ago
parent 2c81043641
commit 29f44a6f62
  1. 43
      slither/printers/summary/evm.py

@ -25,14 +25,14 @@ class PrinterEVM(AbstractPrinter):
_filename(string) _filename(string)
""" """
source_to_pc_mapping = self._process_evm_cfg(self.slither) evm_info = self._extract_evm_info(self.slither)
for contract in self.slither.contracts_derived: for contract in self.slither.contracts_derived:
print('Contract {}'.format(contract.name)) print('Contract {}'.format(contract.name))
contract_file = self.slither.source_code[contract.source_mapping['filename_absolute']].encode('utf-8') contract_file = self.slither.source_code[contract.source_mapping['filename_absolute']].encode('utf-8')
contract_file_lines = open(contract.source_mapping['filename_absolute'],'r').readlines() contract_file_lines = open(contract.source_mapping['filename_absolute'],'r').readlines()
contract_pcs = source_to_pc_mapping['mapping', contract.name] contract_cfg = evm_info['cfg', contract.name]
contract_cfg = source_to_pc_mapping['cfg', contract.name] contract_pcs = evm_info['mapping', contract.name]
for function in contract.functions: for function in contract.functions:
print(f'\tFunction {function.canonical_name}') print(f'\tFunction {function.canonical_name}')
for node in function.nodes: for node in function.nodes:
@ -44,32 +44,44 @@ class PrinterEVM(AbstractPrinter):
for pc in node_pcs: for pc in node_pcs:
print('\t\t\t0x{:x}: {}'.format(int(pc), contract_cfg.get_instruction_at(pc))) print('\t\t\t0x{:x}: {}'.format(int(pc), contract_cfg.get_instruction_at(pc)))
for modifier in contract.modifiers: for modifier in contract.modifiers:
print('\tModifier {}'.format(modifier.canonical_name)) print(f'\tModifier {modifier.canonical_name}')
for node in modifier.nodes: for node in modifier.nodes:
node_source_line = contract_file[0:node.source_mapping['start']].count("\n".encode("utf-8")) + 1 node_source_line = contract_file[0:node.source_mapping['start']].count("\n".encode("utf-8")) + 1
print('\t\tSource line {:x}: {}'.format(node_source_line, contract_file_lines[node_source_line-1].rstrip())) print('\t\tSource line {}: {}'.format(node_source_line, contract_file_lines[node_source_line-1].rstrip()))
print('\t\tEVM Instructions:') print('\t\tEVM Instructions:')
node_pcs = contract_pcs.get(node_source_line, []) node_pcs = contract_pcs.get(node_source_line, [])
for pc in node_pcs: for pc in node_pcs:
print('\t\t\t0x{:x}: {}'.format(int(pc), contract_cfg.get_instruction_at(pc))) print('\t\t\t0x{:x}: {}'.format(int(pc), contract_cfg.get_instruction_at(pc)))
def _process_evm_cfg(self, slither): def _extract_evm_info(self, slither):
source_to_pc_mapping = {} '''
Extract evm information for all derived contracts using evm_cfg_builder
Returns: evm CFG and Solidity source to Program Counter (pc) mapping
'''
evm_info = {}
for contract in slither.contracts_derived: for contract in slither.contracts_derived:
contract_bytecode_runtime = slither.crytic_compile.bytecode_runtime(contract.name) contract_bytecode_runtime = slither.crytic_compile.bytecode_runtime(contract.name)
contract_srcmap_runtime = slither.crytic_compile.srcmap_runtime(contract.name) contract_srcmap_runtime = slither.crytic_compile.srcmap_runtime(contract.name)
cfg = CFG(contract_bytecode_runtime) cfg = CFG(contract_bytecode_runtime)
source_to_pc_mapping['cfg', contract.name] = cfg evm_info['cfg', contract.name] = cfg
source_to_pc_mapping['mapping', contract.name] = self._generate_source_to_ins_mapping(cfg.instructions, evm_info['mapping', contract.name] = self._generate_source_to_evm_ins_mapping(cfg.instructions,
contract_srcmap_runtime, slither, contract_srcmap_runtime, slither,
contract.source_mapping['filename_absolute']) contract.source_mapping['filename_absolute'])
return(source_to_pc_mapping) return(evm_info)
def _generate_source_to_evm_ins_mapping(self, evm_instructions, srcmap_runtime, slither, filename):
'''
Generate Solidity source to EVM instruction mapping using evm_cfg_builder:cfg.instructions and solc:srcmap_runtime
def _generate_source_to_ins_mapping(self, evm_instructions, srcmap_runtime, slither, filename): Returns: Solidity source to EVM instruction mapping
source_to_pc_mapping = {} '''
source_to_evm_mapping = {}
file_source = slither.source_code[filename].encode('utf-8') file_source = slither.source_code[filename].encode('utf-8')
prev_mapping = [] prev_mapping = []
for idx, mapping in enumerate(srcmap_runtime): for idx, mapping in enumerate(srcmap_runtime):
# Parse srcmap_runtime according to its format
# See https://solidity.readthedocs.io/en/v0.5.9/miscellaneous.html#source-mappings
mapping_item = mapping.split(':') mapping_item = mapping.split(':')
mapping_item += prev_mapping[len(mapping_item):] mapping_item += prev_mapping[len(mapping_item):]
for i in range(len(mapping_item)): for i in range(len(mapping_item)):
@ -83,5 +95,8 @@ class PrinterEVM(AbstractPrinter):
offset = int(offset) offset = int(offset)
line_number = file_source[0:offset].count("\n".encode("utf-8")) + 1 line_number = file_source[0:offset].count("\n".encode("utf-8")) + 1
prev_mapping = mapping_item prev_mapping = mapping_item
source_to_pc_mapping.setdefault(line_number, []).append(evm_instructions[idx].pc) # Append evm instructions to the corresponding source line number
return(source_to_pc_mapping) # Note: Some evm instructions in mapping are not necessarily in program execution order
# Note: The order depends on how solc creates the srcmap_runtime
source_to_evm_mapping.setdefault(line_number, []).append(evm_instructions[idx].pc)
return(source_to_evm_mapping)

Loading…
Cancel
Save