Mate Toth-Pal | a8797e1 | 2020-06-05 21:14:26 +0200 | [diff] [blame] | 1 | #------------------------------------------------------------------------------- |
| 2 | # Copyright (c) 2020, Arm Limited. All rights reserved. |
| 3 | # |
| 4 | # SPDX-License-Identifier: BSD-3-Clause |
| 5 | # |
| 6 | #------------------------------------------------------------------------------- |
| 7 | |
| 8 | """Script for scanning the source after breakpoints |
| 9 | |
| 10 | This script scans a source code, and finds patterns that sign a location to be |
| 11 | used as a breakpoint. |
| 12 | TODO: Describe format |
| 13 | """ |
| 14 | |
| 15 | import os |
| 16 | import sys |
| 17 | import json |
| 18 | import re |
| 19 | import argparse |
| 20 | |
| 21 | MACRO_PATTERN = re.compile(r'^\s*IRQ_TEST_TOOL_([0-9a-zA-Z_]*)\s*\(([^\)]*)\)\s*') |
| 22 | |
| 23 | def process_line(filename, line, line_num, breakpoints): |
| 24 | m = MACRO_PATTERN.match(line) |
| 25 | if m: |
| 26 | |
| 27 | macro_type = m.group(1) |
| 28 | parameters = m.group(2).split(',') |
| 29 | |
| 30 | print ("Macro " + macro_type + ", parameters: " + str(parameters)) |
| 31 | |
| 32 | if (macro_type == 'SYMBOL'): |
| 33 | if (len(parameters) != 2): |
| 34 | print ("Invalid macro at " + filename + ":" + str(line_num)) |
| 35 | print ("Expected number of parameters for *SYMBOL is 2") |
| 36 | exit(1) |
| 37 | bp = {} |
| 38 | bp["symbol"] = parameters[1].strip() |
| 39 | breakpoints[parameters[0].strip()] = bp |
| 40 | return |
| 41 | |
| 42 | if (macro_type == 'CODE_LOCATION'): |
| 43 | if (len(parameters) != 1): |
| 44 | print ("Invalid macro at " + filename + ":" + str(line_num)) |
| 45 | print ("Expected number of parameters for *CODE_LOCATION is 1") |
| 46 | exit(1) |
| 47 | bp = {} |
| 48 | bp["file"] = filename |
| 49 | bp["line"] = line_num |
| 50 | breakpoints[parameters[0].strip()] = bp |
| 51 | return |
| 52 | |
| 53 | if (macro_type == 'SYMBOL_OFFSET'): |
| 54 | if (len(parameters) != 3): |
| 55 | print ("Invalid macro at " + filename + ":" + str(line_num)) |
| 56 | print ("Expected number of parameters for *SYMBOL_OFFSET is 3") |
| 57 | exit(1) |
| 58 | bp = {} |
| 59 | bp["symbol"] = parameters[1].strip() |
| 60 | bp["offset"] = parameters[2].strip() |
| 61 | breakpoints[parameters[0].strip()] = bp |
| 62 | return |
| 63 | |
| 64 | print ("invalid macro *" + macro_type + "at " + filename + ":" + str(line_num)) |
| 65 | exit(1) |
| 66 | |
| 67 | |
| 68 | def process_file(file_path, filename, breakpoints): |
| 69 | with open(file_path, 'r', encoding='latin_1') as f: |
| 70 | content = f.readlines() |
| 71 | for num, line in enumerate(content): |
| 72 | line_num = num+1 |
| 73 | process_line(filename, line, line_num, breakpoints) |
| 74 | |
| 75 | |
| 76 | def main(): |
| 77 | parser = argparse.ArgumentParser() |
| 78 | parser.add_argument("tfm_source", help="path to the TF-M source code") |
| 79 | parser.add_argument("outfile", help="The output json file with the breakpoints") |
| 80 | args = parser.parse_args() |
| 81 | |
| 82 | tfm_source_dir = args.tfm_source |
| 83 | |
| 84 | breakpoints = {} |
| 85 | |
| 86 | for root, subdirs, files in os.walk(tfm_source_dir): |
| 87 | for filename in files: |
| 88 | # Scan other files as well? |
| 89 | if not filename.endswith('.c'): |
| 90 | continue |
| 91 | file_path = os.path.join(root, filename) |
| 92 | process_file(file_path, filename, breakpoints) |
| 93 | |
| 94 | |
| 95 | breakpoints = {"breakpoints":breakpoints} |
| 96 | |
| 97 | with open(args.outfile, 'w') as outfile: |
| 98 | json.dump(breakpoints, outfile, |
| 99 | sort_keys=True, indent=4, separators=(',', ': ')) |
| 100 | |
| 101 | |
| 102 | if __name__ == "__main__": |
| 103 | main() |