| # -*- coding: utf-8 -*- | |
| # Copyright 2018 The ChromiumOS Authors | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """check whether intended components exists in the given dso.""" | |
| import os | |
| import subprocess | |
| from allowlist import is_allowlisted | |
| def check_debug_info(dso_path, readelf_content): | |
| """Check whether debug info section exists in the elf file. | |
| Args: | |
| dso_path: path to the dso. | |
| readelf_content: debug info dumped by command readelf. | |
| Returns: | |
| True if debug info section exists, otherwise False. | |
| """ | |
| # Return True if it is allowlisted | |
| if is_allowlisted("exist_debug_info", dso_path): | |
| return True | |
| for l in readelf_content: | |
| if "debug_info" in l: | |
| return True | |
| return False | |
| def check_producer(dso_path, readelf_content): | |
| """Check whether DW_AT_producer exists in each compile unit. | |
| Args: | |
| dso_path: path to the dso. | |
| readelf_content: debug info dumped by command readelf. | |
| Returns: | |
| True if DW_AT_producer exists in each compile unit, otherwise False. | |
| Notice: If no compile unit in DSO, also return True. | |
| """ | |
| # Return True if it is allowlisted | |
| if is_allowlisted("exist_producer", dso_path): | |
| return True | |
| # Indicate if there is a producer under each cu | |
| cur_producer = False | |
| first_cu = True | |
| producer_exist = True | |
| for l in readelf_content: | |
| if "DW_TAG_compile_unit" in l: | |
| if not first_cu and not cur_producer: | |
| producer_exist = False | |
| break | |
| first_cu = False | |
| cur_producer = False | |
| elif "DW_AT_producer" in l: | |
| cur_producer = True | |
| # Check whether last producer of compile unit exists in the elf, | |
| # also return True if no cu in the DSO. | |
| if not first_cu and not cur_producer: | |
| producer_exist = False | |
| return producer_exist | |
| def check_exist_all(dso_path): | |
| """check whether intended components exists in the given dso. | |
| Args: | |
| dso_path: path to the dso. | |
| Returns: | |
| True if everything looks fine otherwise False. | |
| """ | |
| readelf = subprocess.Popen( | |
| ["llvm-dwarfdump", "--recurse-depth=0", dso_path], | |
| stdout=subprocess.PIPE, | |
| stderr=open(os.devnull, "w"), | |
| encoding="utf-8", | |
| ) | |
| readelf_content = list(readelf.stdout) | |
| exist_checks = [check_debug_info, check_producer] | |
| for e in exist_checks: | |
| if not e(dso_path, readelf_content): | |
| check_failed = e.__module__ + ": " + e.__name__ | |
| print("%s failed check: %s" % (dso_path, check_failed)) | |
| return False | |
| return True |