1# -*- coding: utf-8 -*- 2# Copyright 2018 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""check whether intended components exists in the given dso.""" 7 8 9import os 10import subprocess 11 12from allowlist import is_allowlisted 13 14 15def check_debug_info(dso_path, readelf_content): 16 """Check whether debug info section exists in the elf file. 17 18 Args: 19 dso_path: path to the dso. 20 readelf_content: debug info dumped by command readelf. 21 22 Returns: 23 True if debug info section exists, otherwise False. 24 """ 25 26 # Return True if it is allowlisted 27 if is_allowlisted("exist_debug_info", dso_path): 28 return True 29 30 for l in readelf_content: 31 if "debug_info" in l: 32 return True 33 return False 34 35 36def check_producer(dso_path, readelf_content): 37 """Check whether DW_AT_producer exists in each compile unit. 38 39 Args: 40 dso_path: path to the dso. 41 readelf_content: debug info dumped by command readelf. 42 43 Returns: 44 True if DW_AT_producer exists in each compile unit, otherwise False. 45 Notice: If no compile unit in DSO, also return True. 46 """ 47 48 # Return True if it is allowlisted 49 if is_allowlisted("exist_producer", dso_path): 50 return True 51 52 # Indicate if there is a producer under each cu 53 cur_producer = False 54 55 first_cu = True 56 producer_exist = True 57 58 for l in readelf_content: 59 if "DW_TAG_compile_unit" in l: 60 if not first_cu and not cur_producer: 61 producer_exist = False 62 break 63 first_cu = False 64 cur_producer = False 65 elif "DW_AT_producer" in l: 66 cur_producer = True 67 68 # Check whether last producer of compile unit exists in the elf, 69 # also return True if no cu in the DSO. 70 if not first_cu and not cur_producer: 71 producer_exist = False 72 73 return producer_exist 74 75 76def check_exist_all(dso_path): 77 """check whether intended components exists in the given dso. 78 79 Args: 80 dso_path: path to the dso. 81 82 Returns: 83 True if everything looks fine otherwise False. 84 """ 85 86 readelf = subprocess.Popen( 87 ["llvm-dwarfdump", "--recurse-depth=0", dso_path], 88 stdout=subprocess.PIPE, 89 stderr=open(os.devnull, "w"), 90 encoding="utf-8", 91 ) 92 readelf_content = list(readelf.stdout) 93 94 exist_checks = [check_debug_info, check_producer] 95 96 for e in exist_checks: 97 if not e(dso_path, readelf_content): 98 check_failed = e.__module__ + ": " + e.__name__ 99 print("%s failed check: %s" % (dso_path, check_failed)) 100 return False 101 102 return True 103