1#!/usr/bin/env python 2# coding=utf-8 3 4# 5# Copyright (c) 2024 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import os 20import sys 21 22from exceptions.ohos_exception import OHOSException 23from util.system_util import SystemUtil 24from util.io_util import IoUtil 25from util.log_util import LogUtil 26 27 28class KernelPermission(): 29 30 31 @staticmethod 32 def run(out_path, root_path): 33 log_path = os.path.join(out_path, 'build.log') 34 KernelPermission.execute_kernel_permission_cmd(log_path, out_path, root_path) 35 36 37 @staticmethod 38 def scan_file(out_path): 39 """scan path uild_configs/kernel_permission/ 40 return file_list include kernel_permission.json 41 """ 42 file_list = [] 43 file_path = file_path = os.path.join(out_path, "build_configs/kernel_permission/") 44 for root, subdirs, files in os.walk(file_path): 45 for _filename in files: 46 content = IoUtil.read_json_file(os.path.join(root, _filename)) 47 file_list.append(content[0]) 48 return file_list 49 50 51 @staticmethod 52 def execute_kernel_permission_cmd(log_path, out_path, root_path): 53 """execute cmd 54 llvm-object --add-section .kernelpermission=json_file xx/xx.so 55 """ 56 LogUtil.write_log( 57 log_path, 58 "begin run kernel permission cmd log_path:{}".format(log_path), 59 'info') 60 61 try: 62 llvm_tool = KernelPermission.regist_llvm_objcopy_path(root_path) 63 except OHOSException as e: 64 LogUtil.write_log( 65 log_path, 66 "regist_llvm_objcopy_path failed:{}".format(e), 67 'warning') 68 return 69 70 file_list = KernelPermission.scan_file(out_path) 71 72 cmds = KernelPermission.gen_cmds(file_list, out_path, llvm_tool) 73 if cmds: 74 for cmd in cmds: 75 LogUtil.write_log( 76 log_path, 77 cmd, 78 'info') 79 SystemUtil.exec_command( 80 cmd, 81 log_path 82 ) 83 else: 84 LogUtil.write_log( 85 log_path, 86 "There is no kernel permission json file,no need to run llvm-object cmd.", 87 'info') 88 89 90 @staticmethod 91 def regist_llvm_objcopy_path(root_path): 92 """find llvm_objcopy_path executable 93 :raise OHOSException: when can't find the llvm_objcopy_path excutable 94 """ 95 llvm_objcopy_path = os.path.join(root_path, "prebuilts/clang/ohos/linux-x86_64/llvm/bin/llvm-objcopy") 96 if os.path.exists(llvm_objcopy_path): 97 return llvm_objcopy_path 98 else: 99 raise OHOSException( 100 'There is no llvm-object executable file at {}'.format(llvm_objcopy_path), '0001') 101 102 103 @staticmethod 104 def gen_cmds(file_list, out_path, llvm_path): 105 """generate cmd 106 llvm-object --add-section .kernelpermission=json_file xx/xx.so 107 """ 108 cmds = [] 109 cmd = [] 110 for info in file_list: 111 kernel_permission_file = os.path.join(out_path, info.get("kernel_permission_path")) 112 if not KernelPermission.check_json_file(kernel_permission_file): 113 raise OHOSException( 114 'kernel_permission json file {} invalid!'.format(kernel_permission_file), '0001') 115 target_name = info.get("target_name") 116 module_info_file = os.path.join(out_path, info.get("module_info_file")) 117 target_info = IoUtil.read_json_file(module_info_file) 118 label_name = target_info.get("label_name") 119 target_source = os.path.join(out_path, target_info.get("source")) 120 if target_name == label_name: 121 cmd = [llvm_path, 122 "--add-section", 123 ".kernelpermission=" + kernel_permission_file, 124 target_source 125 ] 126 cmds.append(cmd) 127 return cmds 128 129 130 @staticmethod 131 def check_json_file(file_path): 132 json_data = IoUtil.read_json_file(file_path) 133 if KernelPermission.check_json_content(json_data): 134 return True 135 else: 136 print("kernel_permission.json is invalid at file_path: {}".format(file_path)) 137 return False 138 139 140 @staticmethod 141 def check_json_content(json_data): 142 if len(json_data) == 1 and "kernelpermission" in json_data: 143 json_data = json_data["kernelpermission"] 144 return KernelPermission.check_json_value(json_data) 145 else: 146 return False 147 148 149 @staticmethod 150 def check_json_value(json_data): 151 for key, value in json_data.items(): 152 if not isinstance(value, (bool, str, list)): 153 return False 154 if isinstance(value, list): 155 if not all(isinstance(item, str) for item in value): 156 return False 157 return True 158 159 160if __name__ == "__main__": 161 pass 162