1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2022 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16def get_type_def(file): 17 offset = file.tell() 18 file.seek(0, 2) 19 file_size = file.tell() 20 file.seek(offset, 0) 21 startline = "" 22 type_def_lines = [] 23 while file.tell() < file_size: 24 startline = file.readline() 25 index = startline.find("struct sys") 26 if index == 0: 27 type_def_lines.append(startline) 28 while True: 29 line = file.readline() 30 line = line.strip() 31 type_def_lines.append(line) 32 if line == "};": 33 break 34 break 35 return type_def_lines 36 37 38def get_args_name(type_def_lines): 39 startline = type_def_lines[0] 40 splitted_startline = startline.split(' ') 41 type_name = splitted_startline[1] 42 return type_name[4:-2] 43 44 45def get_converter_name(type_def_lines): 46 startline = type_def_lines[0] 47 splitted_startline = startline.split(' ') 48 type_name = splitted_startline[1] 49 splitted_type_name = type_name.split('_') 50 splitted_type_name = splitted_type_name[1:-1] 51 converter_name = "" 52 for item in splitted_type_name: 53 converter_name = "{}{}".format(converter_name, item.capitalize() 54 converter_name = "{}Converter".format(converter_name) 55 return converter_name 56 57 58BAD_MEMBER = "bad nr" 59VOID_MEMBER = "void" 60 61 62def get_argmember_name(type_def_lines, nr_member): 63 max_nr_members = len(type_def_lines) - 2 64 max_nr_members_limit = 4 65 if max_nr_members > max_nr_members_limit: 66 max_nr_members = max_nr_members_limit 67 if nr_member < 1: 68 return BAD_MEMBER 69 if max_nr_members < nr_member and nr_member <= max_nr_members_limit: 70 return VOID_MEMBER 71 if max_nr_members_limit < nr_member: 72 return BAD_MEMBER 73 member_line = type_def_lines[nr_member] 74 splitted_member_line = member_line.split(' ') 75 member_name = splitted_member_line[-1] 76 member_name = member_name[:-1] 77 return member_name 78 79converter_table = [] 80 81 82def generate_converter(type_def_lines): 83 fn_name = get_converter_name(type_def_lines) 84 fn_decl = "static int {}(__u64* args, const struct fstrace_start_event_t* start_event)\n".format(fn_name) 85 max_nr_args = 4 86 expressions = "" 87 for nr in range(max_nr_args): 88 expression_line = "" 89 arg_name = get_args_name(type_def_lines) 90 member_name = get_argmember_name(type_def_lines, nr + 1) 91 if member_name == BAD_MEMBER: 92 break 93 if member_name == VOID_MEMBER: 94 expression_line = " args[{}] = 0xFFFFFFFFFFFFFFFF;\n".format(str(nr)) 95 else: 96 expression_line = " args[{}] = (__u64) start_event->{}.{};\n".format(str(nr), arg_name, member_name) 97 expressions.join(expression_line) 98 converter = "{}{\n{} return 0;\n}\n\n".format(fn_decl, expressions) 99 converter_table.append(("&" + fn_name)) 100 return converter 101 102CONVERTER_FILE_HEAD = ''' 103#include "type_headers.h" 104 105 106''' 107 108 109def output_converter_code(fstrace_types_file, converters_file): 110 nr_converters = 1 111 with open(converters_file, 'w') as outf: 112 outf.write(CONVERTER_FILE_HEAD) 113 with open(fstrace_types_file, 'r') as inf: 114 while True: 115 type_def_lines = get_type_def(inf) 116 if len(type_def_lines) == 0: 117 break 118 converter = generate_converter(type_def_lines) 119 outf.write(converter) 120 nr_converters = nr_converters + 1 121 converter_table_code = ( 122 "using ConverterType = int (*) (__u64*, const struct fstrace_start_event_t *);\n") 123 converter_table_code = "{}ConverterType g_argsConverterTable[{}] = {\n nullptr".format(converter_table_code, str(nr_converters)) 124 for fn_ptr in converter_table: 125 converter_table_code = "{},\n {}".format(converter_table_code, fn_ptr) 126 converter_table_code = "%s\n};\n" % (converter_table_code) 127 outf.write(converter_table_code) 128 129if __name__ == '__main__': 130 output_converter_code("../include/fstrace_types.h", "../src/fstrace_args_converter.cpp") 131