build post process support deps_guard

Signed-off-by: handyohos <zhangxiaotian@huawei.com>
Change-Id: Id983d04084d8f41c8ad13b1d45f34ee28c71283c

#I67BUG
This commit is contained in:
handyohos 2022-12-25 09:20:22 +08:00
parent 6c51ce97a2
commit c50eb75686
6 changed files with 50 additions and 176 deletions

View File

@ -3,7 +3,7 @@
from elf_file_mgr import ElfFileMgr
def createArgParser():
def __createArgParser():
import argparse
parser = argparse.ArgumentParser(description='Check architecture information from compiled output files.')
@ -19,14 +19,22 @@ def createArgParser():
return parser
if __name__ == '__main__':
parser = createArgParser()
args = parser.parse_args()
# Scan
mgr = ElfFileMgr(args.input)
def deps_guard(out_path, args=None):
mgr = ElfFileMgr(out_path)
mgr.scan_all_files()
from rules_checker import check_all_rules
check_all_rules(mgr, args)
passed = check_all_rules(mgr, args)
if passed:
print("All rules passed")
return
raise Exception("ERROR: deps_guard failed.")
if __name__ == '__main__':
parser = __createArgParser()
args = parser.parse_args()
deps_guard(args.input, args)

View File

@ -58,7 +58,26 @@ class ElfFile(dict):
def library_depends(self):
if not os.access(self._f, os.F_OK):
raise Exception("Cannot find lib: " + self._f)
return command("mklibs-readelf", "--print-needed", self._f_safe)
dynamics = command("readelf", "--dynamic", self._f_safe)
res = []
for line in dynamics:
pos = line.find("(NEEDED)")
if pos <= 0:
continue
line = line[pos + 8:]
line = line.strip()
if not line.startswith("Shared library:"):
continue
line = line[15:]
line = line.strip()
if line.startswith("["):
line = line[1:]
if line.endswith("]"):
line = line[:-1]
line = line.strip()
res.append(line)
return res
if __name__ == '__main__':
import elf_walker

View File

@ -14,18 +14,11 @@ class ElfFileWithDepsInfo(ElfFile):
self["deps"] = []
self["dependedBy"] = []
self["deps_indirect"] = []
self["dependedBy_indirect"] = []
self["deps_total"] = 0
self["dependedBy_total"] = 0
self._cached = False
def __eq__(self, other):
if not isinstance(other, ElfFileWithDepsInfo):
return NotImplemented
return self["id"] == other["id"]#and self["name"] == other["name"]
return self["id"] == other["id"]
def dependsOn(self, mod):
for dep in self["deps"]:
@ -33,18 +26,11 @@ class ElfFileWithDepsInfo(ElfFile):
return True
return False
def getAllDependedModules(self):
res = []
for dep in self["deps"]:
res.append(dep["callee"])
return res + self["deps_indirect"]
def __repr__(self):
return self.__str__()
def __str__(self):
#return "%s deps:%s\n%s deps_indirect:%s" % (self["name"], self.getDepends(), self["name"], self.getIndirectDepends())
return "%s:%d deps(%d) depsTotal(%d) dependedBy(%d)" % (self["name"], self["id"], len(self["deps"]), len(self["deps"]) + len(self["deps_indirect"]), len(self["dependedBy"]))
return "%s:%d deps(%d) dependedBy(%d)" % (self["name"], self["id"], len(self["deps"]), len(self["dependedBy"]))
class Dependency(dict):
def __init__(self, idx, caller, callee):
@ -106,19 +92,6 @@ class ElfFileMgr(object):
self._maxDepth = 0
self._maxTotalDepends = 0
print("Build indirect dependence tree for %d ELF files now ..." % len(self._elfFiles))
for mod in self._elfFiles:
mod["_recursiveFinished"] = False
for mod in self._elfFiles:
self.__update_indirect_deps_recursive(mod)
for mod in self._elfFiles:
mod["_recursiveFinished"] = False
for mod in self._elfFiles:
self.__update_indirect_dependedBy_recursive(mod)
for mod in self._elfFiles:
del mod["_recursiveFinished"]
print("Load compile information now ...")
CompileInfoLoader.load(self, self._product_out_path)
HdiParser.load(self, self._product_out_path)
@ -274,101 +247,14 @@ class ElfFileMgr(object):
def get_all_deps(self):
return self._deps
def __update_indirect_dependedBy_recursive(self, mod):
# Already finished
if mod["_recursiveFinished"]:
return mod["dependedBy_depth"]
maxDepth = 0
for item in mod["dependedBy"]:
# update caller first
caller = item["caller"]
depth = self.__update_indirect_dependedBy_recursive(caller)
if depth > maxDepth:
maxDepth = depth
for dep in caller["dependedBy"]:
grand_caller = dep["caller"]
if grand_caller.dependsOn(mod):
continue
if grand_caller in mod["dependedBy_indirect"]:
continue
mod["dependedBy_indirect"].append(grand_caller)
for dep in caller["dependedBy_indirect"]:
if dep.dependsOn(mod):
continue
if dep in mod["dependedBy_indirect"]:
continue
mod["dependedBy_indirect"].append(dep)
if len(mod["dependedBy"]) > 0:
maxDepth = maxDepth + 1
mod["_recursiveFinished"] = True
mod["dependedBy_depth"] = maxDepth
if maxDepth > self._maxDepth:
self._maxDepth = maxDepth
depsTotal = len(mod["dependedBy"]) + len(mod["dependedBy_indirect"])
if depsTotal > self._maxTotalDepends:
self._maxTotalDepends = depsTotal
mod["dependedBy_total"] = depsTotal
return maxDepth
def __update_indirect_deps_recursive(self, mod):
# Already finished
if mod["_recursiveFinished"]:
return mod["depth"]
maxDepth = 0
for item in mod["deps"]:
# update child first
child = item["callee"]
depth = self.__update_indirect_deps_recursive(child)
if depth > maxDepth:
maxDepth = depth
for dep in child["deps"]:
if mod.dependsOn(dep["callee"]):
continue
if dep["callee"] in mod["deps_indirect"]:
continue
mod["deps_indirect"].append(dep["callee"])
for dep in child["deps_indirect"]:
if mod.dependsOn(dep):
continue
if dep in mod["deps_indirect"]:
continue
mod["deps_indirect"].append(dep)
if len(mod["deps"]) > 0:
maxDepth = maxDepth + 1
mod["_recursiveFinished"] = True
mod["depth"] = maxDepth
if maxDepth > self._maxDepth:
self._maxDepth = maxDepth
depsTotal = len(mod["deps"]) + len(mod["deps_indirect"])
if depsTotal > self._maxTotalDepends:
self._maxTotalDepends = depsTotal
mod["deps_total"] = depsTotal
return maxDepth
if __name__ == '__main__':
mgr = ElfFileMgr("/home/z00325844/demo/archinfo/assets/rk3568/3.2.7.5")
mgr.scan_all_files()
elf = mgr.get_elf_by_path("system/lib/libskia_ohos.z.so")
print("Get skia now ...")
#print(len(elf["deps_indirect"]))
#print(len(elf["dependedBy_indirect"]))
#print(elf["deps_indirect"][0])
res = mgr.get_elf_by_path("system/lib/platformsdk/libhmicui18n.z.so")
print(res)
#print(mgr.get_all())
#print(elf["deps_indirect"])
#print(elf.matchCalls())
#print(len(elf["dependedBy"]))

View File

@ -67,25 +67,9 @@ class CompileInfoLoader(object):
res.append(info)
return res
@staticmethod
def __load_predefined_module_info():
cur_file_dir = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(cur_file_dir, "modules.json")) as f:
info = json.load(f)
try:
with open(os.path.join(cur_file_dir, "modules-ex.json")) as f:
info_ex = json.load(f)
info = info + info_ex
except:
pass
return info
@staticmethod
def load(mgr, product_out_path):
info = CompileInfoLoader.__load_output_module_info(product_out_path)
if not info:
info = CompileInfoLoader.__load_predefined_module_info()
defaultInfo = {
"subsystem": "unknown",
@ -99,12 +83,13 @@ class CompileInfoLoader(object):
"labelPath": ""
}
for item in info:
elf = mgr.get_elf_by_path(item["name"])
if not elf:
continue
for k in defaultInfo.keys():
elf[k] = item[k]
if info:
for item in info:
elf = mgr.get_elf_by_path(item["name"])
if not elf:
continue
for k in defaultInfo.keys():
elf[k] = item[k]
unknown_items = []
for elf in mgr.get_all():
@ -232,33 +217,6 @@ class CompileInfoLoader(object):
if callee["sa_id"] > 0 or callee["type"] == "bin":
callee["modGroup"] = "pentry"
# Set innerapi_chc_indirect modGroup and platformsdk
for mod in platformsdks:
for m in mod.getAllDependedModules():
if m not in platformsdks and m not in chipsetsdks:
if m["modGroup"] == "private":
m["modGroup"] = "innerapi_chc_indirect"
#elif m["modGroup"] == "innerapi_cc":
# m["modGroup"] = "innerapi_chc"
# Set innerapi_chc_indirect modGroup and chipsetsdk
for mod in chipsetsdks:
for m in mod.getAllDependedModules():
if m not in platformsdks and m not in chipsetsdks:
if m["modGroup"] == "private":
m["modGroup"] = "innerapi_chc_indirect"
#elif m["modGroup"] == "innerapi_cc":
# m["modGroup"] = "innerapi_chc"
# Set innerapi_cc_indirect
for mod in innerapi_ccs:
if mod["modGroup"] != "innerapi_cc":
continue
for m in mod.getAllDependedModules():
if m not in innerapi_ccs and m not in platformsdks and m not in chipsetsdks:
if m["modGroup"] == "private":
m["modGroup"] = "innerapi_cc_indirect"
if __name__ == "__main__":
import sqlite3
import elf_modules

View File

@ -41,6 +41,9 @@ class SAParser(object):
def load(mgr, out_root_path):
all_sa = {}
path = os.path.join(out_root_path, "packages/phone/system/profile")
if not os.path.exists(path):
return
for f in os.listdir(path):
full_name = os.path.join(path, f)
if os.path.isfile(full_name) and f.endswith(".xml"):

View File

@ -9,7 +9,7 @@ def check_all_rules(mgr, args):
if not napi.check():
passed = False
if args.no_fail:
if args and args.no_fail:
return True
return passed