• 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 __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