#!/bin/sh -x

#
# SMP-analyze.sh - perform SMP analysis on a binary file.
#
# Copyright (c) 2000, 2001, 2010 - University of Virginia 
#
# This file is part of the Memory Error Detection System (MEDS) infrastructure.
# This file may be used and modified for non-commercial purposes as long as 
# all copyright, permission, and nonwarranty notices are preserved.  
# Redistribution is prohibited without prior written consent from the University 
# of Virginia.
#
# Please contact the authors for restrictions applying to commercial use.
#
# THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# Author: University of Virginia
# e-mail: jwd@virginia.com
# URL   : http://www.cs.virginia.edu/
#
#

# Make terminal ansi-color
export TVOPT=ansi
# Set IDA path.
export IDADIR=$IDAROOT
# Make sure that the idal executable can be reached from PATH.
export PATH=$PATH:$IDADIR
export STARS_ROOT_FILENAME=$1
export IDALOG=$1.log
export IDALOG_SILENT=1

shift

export STARS_OPTIONS=$@

# install plugin and IDC file in case the IDA distribitution isn't available
# at build time.

for whole_file in $(ls $SMPSA_HOME/install/*plx* $SMPSA_HOME/install/*so)
do
	file=$(basename $whole_file)
	if [ ! -e $IDAROOT/plugins/$file -o $SMPSA_HOME/install/$file -nt $IDAROOT/plugins/$file ]; then
		cp $SMPSA_HOME/install/$file $IDAROOT/plugins/$file
	fi
done

for whole_file in $SMPSA_HOME/install/SMP7noasm.idc 
do
	file=$(basename $whole_file)
	if [ ! -e $IDAROOT/idc/$file -o $SMPSA_HOME/install/$file -nt $IDAROOT/idc/$file ]; then
		cp $SMPSA_HOME/install/$file $IDAROOT/idc/$file
	fi
done


# Extract the code addresses with objdump.
$PS_OBJDUMP -d --prefix-addresses $STARS_ROOT_FILENAME | grep "^[0-9]" > ${STARS_ROOT_FILENAME}.SMPobjdump

# Extract the exception-handling function target addresses.
# dwarfdump -F $1 | grep "^<" | cut --delimiter="<" --field=3 | cut --delimiter=":" --field=1 | cut --bytes 4-10 > $1.eh_frame_addrs
  
# Make readelf do the same thing as the above dwarfdump command, to
#  eliminate configuration dependence on dwarfdump.
readelf -wF $STARS_ROOT_FILENAME | grep "pc=" | cut --delimiter="=" --field=3 | cut --delimiter="." --field=1 > ${STARS_ROOT_FILENAME}.eh_frame_addrs

if [ "${IDAROOT}"X = "X"  ];  then echo Please set IDAROOT; exit 1; fi
if [ ! -f ${IDAROOT}/libida.so ]; then echo IDAROOT is set poorly, please fix.; exit 1; fi


# remove tmp files
rm -f ${STARS_ROOT_FILENAME}.id? ${STARS_ROOT_FILENAME}.{nam,til,log,syms} `basename $STARS_ROOT_FILENAME .ncexe`.id?
rm -f ${IDALOG}

old_stty=`stty -g` || true

# we can always use idal64, as it analyzes 32-bit binaries just fine.  May use a bit more space, but isn't typically a problem.

# if LANG is set, ida can core dump
unset LANG

case "$IDAROOT" in
	*idapro5* )
		echo "IDAPro 5.* support depreciated"
		exit 1
		;;
	*idapro6*)
		echo "Trying TVHEADLESS IDA6"
		myidal=idal64
		;;
	*idapro7* | *idaproCur* | *IDAPro7*)
		echo "Trying TVHEADLESS IDA7"
		myidal=idat64
		;;

	*)
		echo Cannot determine idapro version: $IDAROOT
		exit 1
		;;
esac

TVHEADLESS=1 time ${IDAROOT}/$myidal  -A -SSMP7noasm.idc -L${IDALOG} $STARS_OPTIONS -OSMPStaticAnalyzer:Reduced:NoGenAsm  $STARS_ROOT_FILENAME > $STARS_ROOT_FILENAME.idaoutput 2>&1

if [ -f $PEASOUP_HOME/tools/add_ifunc_attr.sh ]; then
	$PEASOUP_HOME/tools/add_ifunc_attr.sh ${STARS_ROOT_FILENAME} ${STARS_ROOT_FILENAME}.annot
fi



# SMP seems to mess up the terminal, using this to fix it.
#/usr/bin/reset  || true
#stty $old_stty || true

# Get the output file SMP.syms into $1.syms.
# mv SMP.annot $1.annot

