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