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