1#!/usr/bin/env python 2# coding=utf-8 3 4# 5# Copyright (c) 2022 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 json 21 22 23class CompileInfoLoader(object): 24 25 @staticmethod 26 def __get_modules_from_file(product_out_path_): 27 try: 28 with open(os.path.join(product_out_path_, "packages/phone/system_module_info.json")) as f: 29 modules = json.load(f) 30 return modules 31 except FileNotFoundError: 32 print("file info not found.") 33 return [] 34 35 36 @staticmethod 37 def __update_info_with_item(info_,item_): 38 if "version_script" in item_: 39 info_["version_script"] = item_["version_script"] 40 CompileInfoLoader.__fill_default_module_info(info_) 41 if "shlib_type" in item_: 42 info_["shlib_type"] = item_["shlib_type"] 43 if "innerapi_tags" in item_: 44 info_["innerapi_tags"] = item_["innerapi_tags"] 45 info_["sa_id"] = 0 46 47 @staticmethod 48 def __load_output_module_info(product_out_path__): 49 modules = CompileInfoLoader.__get_modules_from_file(product_out_path_=product_out_path__) 50 res = [] 51 for item in modules: 52 info = {} 53 info["name"] = item["dest"][0] 54 if info["name"].startswith("updater/"): 55 if len(item["dest"]) > 1: 56 info["name"] = item["dest"][1] 57 else: 58 continue 59 60 if "label" in item: 61 info["labelPath"] = item["label"] 62 else: 63 info["labelPath"] = "" 64 if info["labelPath"].find("(") > 0: 65 info["labelPath"] = info["labelPath"][:info["labelPath"].find("(")] 66 if "subsystem_name" in item: 67 info["subsystem"] = item["subsystem_name"] 68 else: 69 if info["labelPath"].startswith("//build/common"): 70 info["subsystem"] = "commonlibrary" 71 else: 72 info["subsystem"] = "unknown" 73 if "part_name" in item: 74 info["componentName"] = item["part_name"] 75 else: 76 if info["labelPath"].startswith("//build/common"): 77 info["componentName"] = "c_utils" 78 else: 79 info["componentName"] = "unknown" 80 if "label_name" in item: 81 info["moduleName"] = item["label_name"] 82 else: 83 info["moduleName"] = "" 84 CompileInfoLoader.__update_info_with_item(info_=info,item_=item) 85 res.append(info) 86 return res 87 88 @staticmethod 89 def __fill_default_module_info(info_): 90 info_["third_party"] = False 91 info_["chipset"] = False 92 info_["napi"] = False 93 info_["innerapi"] = False 94 info_["innerapi_declared"] = False 95 96 @staticmethod 97 def load(load_mgr, product_out_path): 98 info = CompileInfoLoader.__load_output_module_info(product_out_path) 99 100 default_info = CompileInfoLoader.__get_default_info() 101 102 if info: 103 for item in info: 104 elf = load_mgr.get_elf_by_path(item["name"]) 105 if not elf: 106 continue 107 for k in default_info.keys(): 108 if k in item: 109 elf[k] = item[k] 110 111 unknown_items = [] 112 for elf in load_mgr.get_all(): 113 if "componentName" not in elf: 114 print("%s does not match in module info file" % (elf["path"])) 115 unknown = default_info.copy() 116 unknown["name"] = elf["path"] 117 unknown["fileName"] = elf["name"] 118 for k in default_info.keys(): 119 elf[k] = default_info[k] 120 unknown_items.append(unknown) 121 elif elf["componentName"] == "unknown": 122 print("%s has no componentName info" % (elf["path"])) 123 unknown = default_info.copy() 124 unknown["name"] = elf["path"] 125 for k in default_info.keys(): 126 if k in elf: 127 default_info[k] = elf[k] 128 unknown_items.append(unknown) 129 130 if elf["path"].startswith("system/lib64/module/") or elf["path"].startswith("system/lib/module/"): 131 elf["napi"] = True 132 133 if not elf["path"].startswith("system/"): 134 elf["chipset"] = True 135 136 # Add if not exists 137 if "shlib_type" not in elf: 138 elf["shlib_type"] = "" 139 if "innerapi_tags" not in elf: 140 elf["innerapi_tags"] = [] 141 if elf["labelPath"].startswith("//third_party/"): 142 elf["third_party"] = True 143 144 if len(unknown_items) > 0: 145 print("%d modules has no component info" % len(unknown_items)) 146 with open(os.path.join(product_out_path, "unknown.json"), "w") as f: 147 res = json.dumps(unknown_items, indent=4) 148 f.write(res) 149 150 # init platformsdk, chipsetsdk, innerapi flags 151 CompileInfoLoader.__set_elf_default_value(load_mgr) 152 153 # for component dependedBy_internal and dependedBy_external 154 CompileInfoLoader.__update_deps(load_mgr) 155 156 @staticmethod 157 def __get_default_info(): 158 return { 159 "subsystem": "unknown", 160 "componentName": "unknown", 161 "moduleName": "unknown", 162 "third_party": False, 163 "chipset": False, 164 "napi": False, 165 "sa_id": 0, 166 "labelPath": "", 167 "version_script": "", 168 "shlib_type": "", 169 "innerapi": False, 170 "innerapi_tags": [], 171 "innerapi_declared": False 172 } 173 174 @staticmethod 175 def __set_elf_default_value(mgr_): 176 for elf in mgr_.get_all(): 177 elf["deps_internal"] = [] 178 elf["deps_external"] = [] 179 elf["dependedBy_internal"] = [] 180 elf["dependedBy_external"] = [] 181 182 elf["modGroup"] = "private" 183 elf["platformsdk"] = False 184 elf["chipsetsdk"] = False 185 186 elf["hdiType"] = "" 187 if elf["shlib_type"] == "hdi_proxy": 188 elf["hdiType"] = "hdi_proxy" # HDI proxy client library 189 elif elf["shlib_type"] == "hdi_stub": 190 elf["hdiType"] = "hdi_stub" # HDI proxy client library 191 192 if elf["name"] in ("libc.so", "libc++.so", "libhilog.so"): 193 elf["innerapi"] = True 194 195 # Highest priority 196 if elf["napi"]: 197 elf["modGroup"] = "publicapi" 198 199 if elf["sa_id"] > 0 or elf["type"] == "bin": 200 elf["modGroup"] = "pentry" 201 202 @staticmethod 203 def __update_deps(mgr_): 204 platformsdks = [] 205 chipsetsdks = [] 206 innerapi_ccs = [] 207 208 for dep in mgr_.get_all_deps(): 209 caller = dep["caller"] 210 callee = dep["callee"] 211 212 dep["platformsdk"] = False 213 dep["chipsetsdk"] = False 214 dep["external"] = False 215 216 # For Inner API modules detection 217 if caller["componentName"] == callee["componentName"]: 218 caller["deps_internal"].append(dep) 219 callee["dependedBy_internal"].append(dep) 220 else: 221 caller["deps_external"].append(dep) 222 callee["dependedBy_external"].append(dep) 223 callee["innerapi"] = True 224 dep["external"] = True 225 226 callee["modGroup"] = "innerapi_cc" # Cross component 227 228 if caller["napi"]: 229 caller["modGroup"] = "publicapi" 230 231 # For Platform SDK modules detection 232 callee["modGroup"] = "innerapi_chc" # Cross high level component 233 234 dep["platformsdk"] = True 235 callee["platformsdk"] = True 236 if callee not in platformsdks: 237 platformsdks.append(callee) 238 elif caller["chipset"] != callee["chipset"]: 239 # For Chipset SDK modules detection 240 if callee["modGroup"] not in ("publicapi", "pentry"): 241 callee["modGroup"] = "innerapi_chc" # Cross high level component 242 if callee["hdiType"] != "hdi_proxy": # hdi proxy modules can be called by both system and chipset 243 dep["chipsetsdk"] = True 244 callee["chipsetsdk"] = True 245 if callee["hdiType"] != "hdi_proxy" and callee not in chipsetsdks: 246 chipsetsdks.append(callee) 247 elif dep["external"] == True: 248 if callee not in innerapi_ccs: 249 innerapi_ccs.append(callee) 250 251 # Highest priority 252 if caller["napi"]: 253 caller["modGroup"] = "publicapi" 254 if callee["napi"]: 255 callee["modGroup"] = "publicapi" 256 257 if caller["sa_id"] > 0 or caller["type"] == "bin": 258 caller["modGroup"] = "pentry" 259 if callee["sa_id"] > 0 or callee["type"] == "bin": 260 callee["modGroup"] = "pentry" 261 262 263if __name__ == "__main__": 264 import sqlite3 265 import elf_modules 266 267 conn = sqlite3.connect("symdb.db") 268 cursor = conn.cursor() 269 270 mgr = elf_modules.ElfModuleMgr(cursor) 271