1# -*- coding: utf-8 -*- 2# Copyright 2018 The Chromium OS Authors. All rights reserved. 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 8from __future__ import print_function 9 10import os 11import subprocess 12 13from allowlist import is_allowlisted 14 15 16def check_debug_info(dso_path, readelf_content): 17 """Check whether debug info section exists in the elf file. 18 19 Args: 20 dso_path: path to the dso. 21 readelf_content: debug info dumped by command readelf. 22 23 Returns: 24 True if debug info section exists, otherwise False. 25 """ 26 27 # Return True if it is allowlisted 28 if is_allowlisted('exist_debug_info', dso_path): 29 return True 30 31 for l in readelf_content: 32 if 'debug_info' in l: 33 return True 34 return False 35 36 37def check_producer(dso_path, readelf_content): 38 """Check whether DW_AT_producer exists in each compile unit. 39 40 Args: 41 dso_path: path to the dso. 42 readelf_content: debug info dumped by command readelf. 43 44 Returns: 45 True if DW_AT_producer exists in each compile unit, otherwise False. 46 Notice: If no compile unit in DSO, also return True. 47 """ 48 49 # Return True if it is allowlisted 50 if is_allowlisted('exist_producer', dso_path): 51 return True 52 53 # Indicate if there is a producer under each cu 54 cur_producer = False 55 56 first_cu = True 57 producer_exist = True 58 59 for l in readelf_content: 60 if 'DW_TAG_compile_unit' in l: 61 if not first_cu and not cur_producer: 62 producer_exist = False 63 break 64 first_cu = False 65 cur_producer = False 66 elif 'DW_AT_producer' in l: 67 cur_producer = True 68 69 # Check whether last producer of compile unit exists in the elf, 70 # also return True if no cu in the DSO. 71 if not first_cu and not cur_producer: 72 producer_exist = False 73 74 return producer_exist 75 76 77def check_exist_all(dso_path): 78 """check whether intended components exists in the given dso. 79 80 Args: 81 dso_path: path to the dso. 82 83 Returns: 84 True if everything looks fine otherwise False. 85 """ 86 87 readelf = subprocess.Popen( 88 ['readelf', '--debug-dump=info', '--dwarf-depth=1', dso_path], 89 stdout=subprocess.PIPE, 90 stderr=open(os.devnull, 'w'), 91 encoding='utf-8') 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