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 system_module_info_file = os.path.join(product_out_path_, "packages/phone/system_module_info.json") 90 if not os.path.exists(system_module_info_file): 91 system_module_info_file = os.path.join(product_out_path_, 92 "packages/phone/single/phone_install_module/system_module_info.json") 93 with open(system_module_info_file) as f: 94 modules = json.load(f) 95 return modules 96 except FileNotFoundError: 97 print("file info not found.") 98 return [] 99 100 101 @staticmethod 102 def __update_info_with_item(info_, item_): 103 if "version_script" in item_: 104 info_["version_script"] = item_["version_script"] 105 CompileInfoLoader.__fill_default_module_info(info_) 106 if "shlib_type" in item_: 107 info_["shlib_type"] = item_["shlib_type"] 108 if "innerapi_tags" in item_: 109 info_["innerapi_tags"] = item_["innerapi_tags"] 110 info_["sa_id"] = 0 111 112 @staticmethod 113 def __load_output_module_info(product_out_path__): 114 modules = CompileInfoLoader.__get_modules_from_file(product_out_path_=product_out_path__) 115 res = [] 116 for item in modules: 117 info = {} 118 info["name"] = item["dest"][0] 119 if info["name"].startswith("updater/"): 120 if len(item["dest"]) > 1: 121 info["name"] = item["dest"][1] 122 else: 123 continue 124 125 if "label" in item: 126 info["labelPath"] = item["label"] 127 else: 128 info["labelPath"] = "" 129 if info["labelPath"].find("(") > 0: 130 info["labelPath"] = info["labelPath"][:info["labelPath"].find("(")] 131 if "subsystem_name" in item: 132 info["subsystem"] = item["subsystem_name"] 133 else: 134 if info["labelPath"].startswith("//build/common"): 135 info["subsystem"] = "commonlibrary" 136 else: 137 info["subsystem"] = "unknown" 138 if "part_name" in item: 139 info["componentName"] = item["part_name"] 140 else: 141 if info["labelPath"].startswith("//build/common"): 142 info["componentName"] = "c_utils" 143 else: 144 info["componentName"] = "unknown" 145 if "label_name" in item: 146 info["moduleName"] = item["label_name"] 147 else: 148 info["moduleName"] = "" 149 CompileInfoLoader.__update_info_with_item(info_=info, item_=item) 150 res.append(info) 151 return res 152 153 @staticmethod 154 def __fill_default_module_info(info_): 155 info_["third_party"] = False 156 info_["chipset"] = False 157 info_["napi"] = False 158 info_["innerapi"] = False 159 info_["innerapi_declared"] = False 160 161 @staticmethod 162 def __get_default_info(): 163 return { 164 "subsystem": "unknown", 165 "componentName": "unknown", 166 "moduleName": "unknown", 167 "third_party": False, 168 "chipset": False, 169 "napi": False, 170 "sa_id": 0, 171 "labelPath": "", 172 "version_script": "", 173 "shlib_type": "", 174 "innerapi": False, 175 "innerapi_tags": [], 176 "innerapi_declared": False 177 } 178 179 @staticmethod 180 def __set_elf_default_value(mgr_): 181 for elf in mgr_.get_all(): 182 elf["deps_internal"] = [] 183 elf["deps_external"] = [] 184 elf["dependedBy_internal"] = [] 185 elf["dependedBy_external"] = [] 186 187 elf["modGroup"] = "private" 188 elf["platformsdk"] = False 189 elf["chipsetsdk"] = False 190 191 elf["hdiType"] = "" 192 if elf["shlib_type"] == "hdi_proxy": 193 elf["hdiType"] = "hdi_proxy" # HDI proxy client library 194 elif elf["shlib_type"] == "hdi_stub": 195 elf["hdiType"] = "hdi_stub" # HDI proxy client library 196 197 if elf["name"] in ("libc.so", "libc++.so", "libhilog.so"): 198 elf["innerapi"] = True 199 200 # Highest priority 201 if elf["napi"]: 202 elf["modGroup"] = "publicapi" 203 204 if elf["sa_id"] > 0 or elf["type"] == "bin": 205 elf["modGroup"] = "pentry" 206 207 @staticmethod 208 def __update_deps(mgr_): 209 platformsdks = [] 210 chipsetsdks = [] 211 innerapi_ccs = [] 212 213 for dep in mgr_.get_all_deps(): 214 caller = dep["caller"] 215 callee = dep["callee"] 216 217 dep["platformsdk"] = False 218 dep["chipsetsdk"] = False 219 dep["external"] = False 220 221 # For Inner API modules detection 222 if caller["componentName"] == callee["componentName"]: 223 caller["deps_internal"].append(dep) 224 callee["dependedBy_internal"].append(dep) 225 else: 226 caller["deps_external"].append(dep) 227 callee["dependedBy_external"].append(dep) 228 callee["innerapi"] = True 229 dep["external"] = True 230 231 callee["modGroup"] = "innerapi_cc" # Cross component 232 233 if caller["napi"]: 234 caller["modGroup"] = "publicapi" 235 236 # For Platform SDK modules detection 237 callee["modGroup"] = "innerapi_chc" # Cross high level component 238 239 dep["platformsdk"] = True 240 callee["platformsdk"] = True 241 if callee not in platformsdks: 242 platformsdks.append(callee) 243 elif caller["chipset"] != callee["chipset"]: 244 # For Chipset SDK modules detection 245 if callee["modGroup"] not in ("publicapi", "pentry"): 246 callee["modGroup"] = "innerapi_chc" # Cross high level component 247 if callee["hdiType"] != "hdi_proxy": # hdi proxy modules can be called by both system and chipset 248 dep["chipsetsdk"] = True 249 callee["chipsetsdk"] = True 250 if callee["hdiType"] != "hdi_proxy" and callee not in chipsetsdks: 251 chipsetsdks.append(callee) 252 elif dep["external"] == True: 253 if callee not in innerapi_ccs: 254 innerapi_ccs.append(callee) 255 256 # Highest priority 257 if caller["napi"]: 258 caller["modGroup"] = "publicapi" 259 if callee["napi"]: 260 callee["modGroup"] = "publicapi" 261 262 if caller["sa_id"] > 0 or caller["type"] == "bin": 263 caller["modGroup"] = "pentry" 264 if callee["sa_id"] > 0 or callee["type"] == "bin": 265 callee["modGroup"] = "pentry" 266 267 268if __name__ == "__main__": 269 import sqlite3 270 import elf_modules 271 272 conn = sqlite3.connect("symdb.db") 273 cursor = conn.cursor() 274 275 mgr = elf_modules.ElfModuleMgr(cursor) 276