#! /usr/bin/env python

# Copyright (C) 2011-2012 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# This program requires readelf, gdb and objcopy.  The default values are gdb
# from the build tree and objcopy and readelf from $PATH.  They may be
# overridden by setting environment variables GDB, READELF and OBJCOPY
# respectively.  We assume the current directory is either $obj/gdb or
# $obj/gdb/testsuite.
#
# Example usage:
#
# bash$ cd $objdir/gdb/testsuite
# bash$ python test_pubnames_and_indexes.py <binary_name>

"""test_pubnames_and_indexes.py

Test that the gdb_index produced by gold is identical to the gdb_index
produced by gdb itself.

Further check that the pubnames and pubtypes produced by gcc are identical
to those that gdb produces.

Finally, check that all strings are canonicalized identically.
"""

__author__ = 'saugustine@google.com (Sterling Augustine)'

import os
import subprocess
import sys

OBJCOPY = None
READELF = None
GDB = None

def get_pub_info(filename, readelf_option):
  """Parse and return all the pubnames or pubtypes produced by readelf with the
  given option.
  """
  readelf = subprocess.Popen([READELF, '--debug-dump=' + readelf_option,
                                       filename], stdout=subprocess.PIPE)
  pubnames = []

  in_list = False;
  for line in readelf.stdout:
    fields = line.split(None, 1)
    if (len(fields) == 2 and fields[0] == 'Offset'
        and fields[1].strip() == 'Name'):
      in_list = True
    # Either a blank-line or a new Length field terminates the current section.
    elif (len(fields) == 0 or fields[0] == 'Length:'):
      in_list = False;
    elif (in_list):
      pubnames.append(fields[1].strip())

  readelf.wait()
  return pubnames


def get_gdb_index(filename):
  """Use readelf to dump the gdb index and collect the types and names"""
  readelf = subprocess.Popen([READELF, '--debug-dump=gdb_index',
                              filename], stdout=subprocess.PIPE)
  index_symbols = []
  symbol_table_started = False
  for line in readelf.stdout:
    if (line == 'Symbol table:\n'):
      symbol_table_started = True;
    elif (symbol_table_started):
      # Readelf prints gdb-index lines formatted like so:
      # [  4] two::c2<double>::c2: 0
      # So take the string between the first close bracket and the last colon.
      index_symbols.append(line[line.find(']') + 2: line.rfind(':')])

  readelf.wait()
  return index_symbols


def CheckSets(list0, list1, name0, name1):
  """Report any setwise differences between the two lists"""

  if len(list0) == 0 or len(list1) == 0:
    return False

  difference0 = set(list0) - set(list1)
  if len(difference0) != 0:
    print "Elements in " + name0 + " but not " + name1 + ": (",
    print len(difference0),
    print ")"
    for element in difference0:
      print "  " + element

  difference1 = set(list1) - set(list0)
  if len(difference1) != 0:
    print "Elements in " + name1 + " but not " + name0 + ": (",
    print len(difference1),
    print ")"
    for element in difference1:
      print "  " + element

  if (len(difference0) != 0 or len(difference1) != 0):
    return True

  print name0 + " and " + name1 + " are identical."
  return False


def find_executables():
  """Find the copies of readelf, objcopy and gdb to use."""
  # Executable finding logic follows cc-with-index.sh
  global READELF
  READELF = os.getenv('READELF')
  if READELF is None:
    READELF = 'readelf'
  global OBJCOPY
  OBJCOPY = os.getenv('OBJCOPY')
  if OBJCOPY is None:
    OBJCOPY = 'objcopy'

  global GDB
  GDB = os.getenv('GDB')
  if (GDB is None):
    if os.path.isfile('./gdb') and os.access('./gdb', os.X_OK):
      GDB = './gdb'
    elif os.path.isfile('../gdb') and os.access('../gdb', os.X_OK):
      GDB = '../gdb'
    elif os.path.isfile('../../gdb') and os.access('../../gdb', os.X_OK):
      GDB = '../../gdb'
    else:
      # Punt and use the gdb in the path.
      GDB = 'gdb'


def main(argv):
  """The main subprogram."""
  if len(argv) != 2:
    print "Usage: test_pubnames_and_indexes.py <filename>"
    sys.exit(2)

  find_executables();

  # Get the index produced by Gold--It should have been built into the binary.
  gold_index = get_gdb_index(argv[1])

  # Collect the pubnames and types list
  pubs_list = get_pub_info(argv[1], "pubnames")
  pubs_list = pubs_list + get_pub_info(argv[1], "pubtypes")

  # Generate a .gdb_index with gdb
  gdb_index_file = argv[1] + '.gdb-generated-index'
  subprocess.check_call([OBJCOPY, '--remove-section', '.gdb_index',
                         argv[1], gdb_index_file])
  subprocess.check_call([GDB, '-batch', '-nx', gdb_index_file,
                         '-ex', 'save gdb-index ' + os.path.dirname(argv[1]),
                         '-ex', 'quit'])
  subprocess.check_call([OBJCOPY, '--add-section',
                         '.gdb_index=' + gdb_index_file + '.gdb-index',
                         gdb_index_file])
  gdb_index = get_gdb_index(gdb_index_file)
  os.remove(gdb_index_file)
  os.remove(gdb_index_file + '.gdb-index')

  failed = False
  gdb_index.sort()
  gold_index.sort()
  pubs_list.sort()

  # Find the differences between the various indices.
  if len(gold_index) == 0:
    print "Gold index is empty"
    failed |= True

  if len(gdb_index) == 0:
    print "Gdb index is empty"
    failed |= True

  if len(pubs_list) == 0:
    print "Pubs list is empty"
    failed |= True

  failed |= CheckSets(gdb_index, gold_index, "gdb index", "gold index")
  failed |= CheckSets(pubs_list, gold_index, "pubs list", "gold index")
  failed |= CheckSets(pubs_list, gdb_index, "pubs list", "gdb index")

  if failed:
    print "Test failed"
    sys.exit(1)


if __name__ == '__main__':
  main(sys.argv)
