1 #!/usr/bin/env python3 1 #!/usr/bin/env python3 2 # SPDX-License-Identifier: GPL-2.0-only 2 # SPDX-License-Identifier: GPL-2.0-only 3 # 3 # 4 # Copyright (C) 2019-2022 Red Hat, Inc. Daniel< 4 # Copyright (C) 2019-2022 Red Hat, Inc. Daniel Bristot de Oliveira <bristot@kernel.org> 5 # 5 # 6 # dot2k: transform dot files into a monitor fo 6 # dot2k: transform dot files into a monitor for the Linux kernel. 7 # 7 # 8 # For further information, see: 8 # For further information, see: 9 # Documentation/trace/rv/da_monitor_synthesi 9 # Documentation/trace/rv/da_monitor_synthesis.rst 10 10 11 from dot2.dot2c import Dot2c 11 from dot2.dot2c import Dot2c 12 import platform 12 import platform 13 import os 13 import os 14 14 15 class dot2k(Dot2c): 15 class dot2k(Dot2c): 16 monitor_types = { "global" : 1, "per_cpu" 16 monitor_types = { "global" : 1, "per_cpu" : 2, "per_task" : 3 } 17 monitor_templates_dir = "dot2k/rv_template 17 monitor_templates_dir = "dot2k/rv_templates/" 18 monitor_type = "per_cpu" 18 monitor_type = "per_cpu" 19 19 20 def __init__(self, file_path, MonitorType) 20 def __init__(self, file_path, MonitorType): 21 super().__init__(file_path) 21 super().__init__(file_path) 22 22 23 self.monitor_type = self.monitor_types 23 self.monitor_type = self.monitor_types.get(MonitorType) 24 if self.monitor_type == None: 24 if self.monitor_type == None: 25 raise Exception("Unknown monitor t 25 raise Exception("Unknown monitor type: %s" % MonitorType) 26 26 27 self.monitor_type = MonitorType 27 self.monitor_type = MonitorType 28 self.__fill_rv_templates_dir() 28 self.__fill_rv_templates_dir() 29 self.main_c = self.__open_file(self.mo 29 self.main_c = self.__open_file(self.monitor_templates_dir + "main_" + MonitorType + ".c") 30 self.enum_suffix = "_%s" % self.name 30 self.enum_suffix = "_%s" % self.name 31 31 32 def __fill_rv_templates_dir(self): 32 def __fill_rv_templates_dir(self): 33 33 34 if os.path.exists(self.monitor_templat 34 if os.path.exists(self.monitor_templates_dir) == True: 35 return 35 return 36 36 37 if platform.system() != "Linux": 37 if platform.system() != "Linux": 38 raise Exception("I can only run on 38 raise Exception("I can only run on Linux.") 39 39 40 kernel_path = "/lib/modules/%s/build/t 40 kernel_path = "/lib/modules/%s/build/tools/verification/dot2/dot2k_templates/" % (platform.release()) 41 41 42 if os.path.exists(kernel_path) == True 42 if os.path.exists(kernel_path) == True: 43 self.monitor_templates_dir = kerne 43 self.monitor_templates_dir = kernel_path 44 return 44 return 45 45 46 if os.path.exists("/usr/share/dot2/dot 46 if os.path.exists("/usr/share/dot2/dot2k_templates/") == True: 47 self.monitor_templates_dir = "/usr 47 self.monitor_templates_dir = "/usr/share/dot2/dot2k_templates/" 48 return 48 return 49 49 50 raise Exception("Could not find the te 50 raise Exception("Could not find the template directory, do you have the kernel source installed?") 51 51 52 52 53 def __open_file(self, path): 53 def __open_file(self, path): 54 try: 54 try: 55 fd = open(path) 55 fd = open(path) 56 except OSError: 56 except OSError: 57 raise Exception("Cannot open the f 57 raise Exception("Cannot open the file: %s" % path) 58 58 59 content = fd.read() 59 content = fd.read() 60 60 61 return content 61 return content 62 62 63 def __buff_to_string(self, buff): 63 def __buff_to_string(self, buff): 64 string = "" 64 string = "" 65 65 66 for line in buff: 66 for line in buff: 67 string = string + line + "\n" 67 string = string + line + "\n" 68 68 69 # cut off the last \n 69 # cut off the last \n 70 return string[:-1] 70 return string[:-1] 71 71 72 def fill_tracepoint_handlers_skel(self): 72 def fill_tracepoint_handlers_skel(self): 73 buff = [] 73 buff = [] 74 for event in self.events: 74 for event in self.events: 75 buff.append("static void handle_%s 75 buff.append("static void handle_%s(void *data, /* XXX: fill header */)" % event) 76 buff.append("{") 76 buff.append("{") 77 if self.monitor_type == "per_task" 77 if self.monitor_type == "per_task": 78 buff.append("\tstruct task_str 78 buff.append("\tstruct task_struct *p = /* XXX: how do I get p? */;"); 79 buff.append("\tda_handle_event 79 buff.append("\tda_handle_event_%s(p, %s%s);" % (self.name, event, self.enum_suffix)); 80 else: 80 else: 81 buff.append("\tda_handle_event 81 buff.append("\tda_handle_event_%s(%s%s);" % (self.name, event, self.enum_suffix)); 82 buff.append("}") 82 buff.append("}") 83 buff.append("") 83 buff.append("") 84 return self.__buff_to_string(buff) 84 return self.__buff_to_string(buff) 85 85 86 def fill_tracepoint_attach_probe(self): 86 def fill_tracepoint_attach_probe(self): 87 buff = [] 87 buff = [] 88 for event in self.events: 88 for event in self.events: 89 buff.append("\trv_attach_trace_pro 89 buff.append("\trv_attach_trace_probe(\"%s\", /* XXX: tracepoint */, handle_%s);" % (self.name, event)) 90 return self.__buff_to_string(buff) 90 return self.__buff_to_string(buff) 91 91 92 def fill_tracepoint_detach_helper(self): 92 def fill_tracepoint_detach_helper(self): 93 buff = [] 93 buff = [] 94 for event in self.events: 94 for event in self.events: 95 buff.append("\trv_detach_trace_pro 95 buff.append("\trv_detach_trace_probe(\"%s\", /* XXX: tracepoint */, handle_%s);" % (self.name, event)) 96 return self.__buff_to_string(buff) 96 return self.__buff_to_string(buff) 97 97 98 def fill_main_c(self): 98 def fill_main_c(self): 99 main_c = self.main_c 99 main_c = self.main_c 100 min_type = self.get_minimun_type() 100 min_type = self.get_minimun_type() 101 nr_events = self.events.__len__() 101 nr_events = self.events.__len__() 102 tracepoint_handlers = self.fill_tracep 102 tracepoint_handlers = self.fill_tracepoint_handlers_skel() 103 tracepoint_attach = self.fill_tracepoi 103 tracepoint_attach = self.fill_tracepoint_attach_probe() 104 tracepoint_detach = self.fill_tracepoi 104 tracepoint_detach = self.fill_tracepoint_detach_helper() 105 105 106 main_c = main_c.replace("MIN_TYPE", mi 106 main_c = main_c.replace("MIN_TYPE", min_type) 107 main_c = main_c.replace("MODEL_NAME", 107 main_c = main_c.replace("MODEL_NAME", self.name) 108 main_c = main_c.replace("NR_EVENTS", s 108 main_c = main_c.replace("NR_EVENTS", str(nr_events)) 109 main_c = main_c.replace("TRACEPOINT_HA 109 main_c = main_c.replace("TRACEPOINT_HANDLERS_SKEL", tracepoint_handlers) 110 main_c = main_c.replace("TRACEPOINT_AT 110 main_c = main_c.replace("TRACEPOINT_ATTACH", tracepoint_attach) 111 main_c = main_c.replace("TRACEPOINT_DE 111 main_c = main_c.replace("TRACEPOINT_DETACH", tracepoint_detach) 112 112 113 return main_c 113 return main_c 114 114 115 def fill_model_h_header(self): 115 def fill_model_h_header(self): 116 buff = [] 116 buff = [] 117 buff.append("/*") 117 buff.append("/*") 118 buff.append(" * Automatically generate 118 buff.append(" * Automatically generated C representation of %s automaton" % (self.name)) 119 buff.append(" * For further informatio 119 buff.append(" * For further information about this format, see kernel documentation:") 120 buff.append(" * Documentation/trace/ 120 buff.append(" * Documentation/trace/rv/deterministic_automata.rst") 121 buff.append(" */") 121 buff.append(" */") 122 buff.append("") 122 buff.append("") 123 123 124 return buff 124 return buff 125 125 126 def fill_model_h(self): 126 def fill_model_h(self): 127 # 127 # 128 # Adjust the definition names 128 # Adjust the definition names 129 # 129 # 130 self.enum_states_def = "states_%s" % s 130 self.enum_states_def = "states_%s" % self.name 131 self.enum_events_def = "events_%s" % s 131 self.enum_events_def = "events_%s" % self.name 132 self.struct_automaton_def = "automaton 132 self.struct_automaton_def = "automaton_%s" % self.name 133 self.var_automaton_def = "automaton_%s 133 self.var_automaton_def = "automaton_%s" % self.name 134 134 135 buff = self.fill_model_h_header() 135 buff = self.fill_model_h_header() 136 buff += self.format_model() 136 buff += self.format_model() 137 137 138 return self.__buff_to_string(buff) 138 return self.__buff_to_string(buff) 139 139 140 def __create_directory(self): 140 def __create_directory(self): 141 try: 141 try: 142 os.mkdir(self.name) 142 os.mkdir(self.name) 143 except FileExistsError: 143 except FileExistsError: 144 return 144 return 145 except: 145 except: 146 print("Fail creating the output di 146 print("Fail creating the output dir: %s" % self.name) 147 147 148 def __create_file(self, file_name, content 148 def __create_file(self, file_name, content): 149 path = "%s/%s" % (self.name, file_name 149 path = "%s/%s" % (self.name, file_name) 150 try: 150 try: 151 file = open(path, 'w') 151 file = open(path, 'w') 152 except FileExistsError: 152 except FileExistsError: 153 return 153 return 154 except: 154 except: 155 print("Fail creating file: %s" % p 155 print("Fail creating file: %s" % path) 156 156 157 file.write(content) 157 file.write(content) 158 158 159 file.close() 159 file.close() 160 160 161 def __get_main_name(self): 161 def __get_main_name(self): 162 path = "%s/%s" % (self.name, "main.c") 162 path = "%s/%s" % (self.name, "main.c") 163 if os.path.exists(path) == False: 163 if os.path.exists(path) == False: 164 return "main.c" 164 return "main.c" 165 return "__main.c" 165 return "__main.c" 166 166 167 def print_files(self): 167 def print_files(self): 168 main_c = self.fill_main_c() 168 main_c = self.fill_main_c() 169 model_h = self.fill_model_h() 169 model_h = self.fill_model_h() 170 170 171 self.__create_directory() 171 self.__create_directory() 172 172 173 path = "%s.c" % self.name 173 path = "%s.c" % self.name 174 self.__create_file(path, main_c) 174 self.__create_file(path, main_c) 175 175 176 path = "%s.h" % self.name 176 path = "%s.h" % self.name 177 self.__create_file(path, model_h) 177 self.__create_file(path, model_h)
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.