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