aboutsummaryrefslogtreecommitdiff
path: root/debug_info_test/check_exist.py
blob: f2cc7c6ba53dd10ad3e3a5dd5f4dbcf751a24165 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# 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."""

from __future__ import print_function

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(
      ['readelf', '--debug-dump=info', '--dwarf-depth=1', 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