• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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