#!/bin/sh
# Checks whether given debug symbol files package is correctly done.
# This file is part of maemo-debug-scripts.
#
# Copyright (C) 2007 by Nokia Corporation
#
# Contact: Eero Tamminen <eero.tamminen@nokia.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License 
# version 2 as published by the Free Software Foundation. 
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
# 02110-1301 USA
#
# Changes
# -------
# 2007-10-16:
# - Exit with an error code if there's a problem with the debug package
# - Check that debug package architecture is correct
# - Don't check debug package for packages without ELF files

if [ $# -ne 1 ]; then
	echo
	echo "usage: ${0##*/} <package name>"
	echo
	echo "Gets debug symbol package for given package and checks that"
	echo "each binary and library has corresponding debug symbol file"
	echo "and there are no problems with the debug symbols."
	echo
	echo "Requires either 'readelf' or 'objdump' (from binutils)."
	echo
	exit 1
fi
pkg=$1
if [ "${pkg%-dbg}" != "$pkg" ]; then
	pkg=${pkg%-dbg}
fi
# check tools (both are in binutils package)
if [ \! -z $(which readelf) ]; then
	sections="readelf -S"
	arch_check="readelf -h"
	arch_string="Machine"
elif [ \! -z $(which objdump) ]; then
	sections="objdump -h"
	arch_check="objdump -h"
	arch_string="format"
else
	echo
	echo "ERROR: either 'readelf' or 'objdump' (from binutils) is needed,"
	echo "       both are missing!"
	exit 1
fi
if [ -f /targets/links/scratchbox.config ]; then
	apt_get="fakeroot apt-get"
else
	# no fakeroot on target
	apt_get="apt-get --allow-unauthenticated"
fi
$apt_get install $pkg
if [ $? -ne 0 ]; then
	echo
	echo "ERROR: unknown package '$pkg'"
	exit 1
fi

debug_install()
{
	$apt_get install $1-dbg
	if [ $? -ne 0 ]; then
		echo "ERROR: package doesn't have a corresponding debug package:"
		echo "  $1-dbg"
		exit 1
	fi
}
# check for binaries and libraries
echo "Checking package contents..."
checked=""
skipped=""
missing=""
oldstyle=""
wrongarch=""
havecode=""
nodebug=""
for file in $(dpkg -L $pkg); do
	if [ -d $file ] || [ -h $file ] || [ \! -f $file ]; then
		# skipping dirs, symlinks and non-files
		continue
	fi
	# check architecture
	bin_arch=$($arch_check $file 2> /dev/null | grep $arch_string)
	if [ $? -ne 0 ]; then
		# not an ELF file
		skipped="$skipped $file"
		continue
	else
		if [ \! $debug ]; then
			debug_install $pkg
			debug=1
		fi
		checked="$checked $file"
	fi
	if [ -f /usr/lib/debug/${file##*/} ]; then
		oldstyle="$oldstyle $file"
		continue
	fi
	dbg=/usr/lib/debug/$file
	if [ \! -f $dbg ]; then
		missing="$missing $file"
		continue
	fi
	dbg_arch=$($arch_check $dbg 2> /dev/null | grep $arch_string)
	if [ "$bin_arch" != "$dbg_arch" ]; then
		wrongarch="$wrongarch $dbg"
		continue
	fi
	if [ -z "$($sections $dbg|grep .text|grep NOBITS)" ]; then
		havecode="$havecode $dbg"
	fi
	if [ -z "$($sections $dbg|grep .debug_frame|grep PROGBITS)" ]; then
		nodebug="$nodebug $dbg"
	fi
done

if [ \! -z "$skipped" ]; then
	echo
	echo "Skipped following files as they don't need debug symbols:"
	for file in $skipped; do
		echo "- $file"
	done
fi
if [ \! -z "$checked" ]; then
	echo
	echo "...and checked following files:"
	for file in $checked; do
		echo "- $file"
	done
fi

if [ \! -z "$missing" ]; then
	echo
	echo "ERROR: debug symbol files are missing for following files:"
	for file in $missing; do
		echo "- $file"
	done
	echo "Most likely reason for this is incorrect dh_strip use in debian/rules."
	errors=1
fi
if [ \! -z "$oldstyle" ]; then
	echo
	echo "ERROR: files which have old style debug symbols:"
	for file in $oldstyle; do
		echo "- $file"
	done
	echo "Most likely reason for this is incorrect dh_strip use in debian/rules."
	errors=1
fi
if [ \! -z "$wrongarch" ]; then
	echo
	echo "ERROR: debug files with wrong architecture:"
	for file in $wrongarch; do
		echo "- $file"
	done
	echo "Most likely reason for this is incorrect package architecture in debian/control file."
	errors=1
fi
if [ \! -z "$havecode" ]; then
	echo
	echo "ERROR: debug symbol files which contain code (.text section with PROGBITS):"
	for file in $havecode; do
		echo "- $file"
	done
	echo "Most likely reason for this is incorrect dh_strip use in debian/rules file."
	errors=1
fi
if [ \! -z "$nodebug" ]; then
	echo
	echo "ERROR: .debug_frame section needed for backtraces is missing from:"
	for file in $nodebug; do
		echo "- $file"
	done
	echo "Most likely reason for this is missing -g compile option."
	errors=1
fi
echo
if [ $errors ]; then
	echo "ERROR! There are errors in debug symbol files."
	exit 1
else
	echo "DONE! No issues found."
fi
