#!/bin/sh

# The default perl modules are properly rebased, a rebase clash is very unlikely.
# However with more and more CPAN XS extensions being added over time,
# *** fatal error - unable to remap some.dll to same address as parent
# will become more likely, and those new DLLs are not rebased by a normal rebaseall.
# perlrebase starts afresh all perl DLLs from a pretty low base upwards.

usage()
{
  echo "usage: $ProgramName [-d Directory -d ...] [perlversion [baseaddr]]"
  echo "       Extra -d directories are ADDED to the default perl locations"
  echo "       Typically used to add blib/ dirs while building XS extensions"
  exit 1
}

ProgramName=`basename $0`
ProgramOptions='d:'
Dirs=
while getopts $ProgramOptions Option "$@"
do
  case $Option in
  d)
    Dirs="$Dirs $OPTARG";;
  \?)
    usage ;;
  esac
done
shift $(($OPTIND - 1))

suff=$1
suff=${suff:=5.8.8}
baseaddr=$2
offset=0x20000

# use a rather low base and go upwards, might clash with some Win7 system dlls
baseaddr=${baseaddr:=0x56000000}
perl=/usr/local/bin/perl$suff.exe
if [ ! -f $perl ]; then
  perl=/usr/bin/perl$suff.exe
  if [ ! -f $perl ]; then
    echo "$perl and /usr/local/bin/perl$suff.exe not found"
    echo "usage: perlrebase [5.13.5 [baseaddr]]"
    exit
  fi
fi

OBJDUMP=${OBJDUMP:-/usr/bin/objdump}
if [ ! -e ${OBJDUMP} -o ! -x ${OBJDUMP} ]
then
  OBJDUMP=/mingw/bin/objdump
  if [ ! -e ${OBJDUMP} -o ! -x ${OBJDUMP} ]
  then
    echo "Warning: can't find objdump in the usual locations" 2>&1
    echo "         I hope it is in \$PATH" 2>&1
    OBJDUMP=objdump
  fi
fi

dll=$(${OBJDUMP} -p $perl | $perl -anle 'print $F[2] if /DLL Name:/ && /msys-perl/')
if [ ! -f /usr/local/bin/$dll ]; then
  if [ ! -f /usr/bin/$dll ]; then
    echo "$dll not found in /usr/local/bin nor /usr/bin"
    echo "usage: perlrebase [5.13.5 [baseaddr]]"
    exit
  else
    dll=/usr/bin/$dll
  fi
else
  dll=/usr/local/bin/$dll
fi
arch=$($perl -MConfig -MFile::Basename -e'print basename($Config{archlib})')
ver=$($perl -MConfig -MFile::Basename -e'print basename(dirname $Config{archlib})')
# write to a local .lst to be able to re-order dlls locally
echo $perl > rebase$suff.lst
if [ ! -d /usr/lib/perl5/$ver/$arch/auto ]; then
  echo "no archlib found for $perl"
  exit
fi
if [ ! -e /usr/bin/rebase.exe ]; then
  echo "/usr/bin/rebase.exe not found. Install the rebase package"
  exit
fi
echo $dll >> rebase$suff.lst
/usr/bin/find /usr/lib/perl5/{,site_perl/,vendor_perl/}$ver/$arch/auto/ -name \*.dll >> rebase$suff.lst 2>/dev/null || /bin/true
for d in $Dirs
do
  /usr/bin/find $d -name \*.dll >> rebase$suff.lst 2>/dev/null || /bin/true
done
/usr/bin/cat rebase$suff.lst | /usr/bin/xargs chmod ug+w
[ -e /usr/bin/peflags.exe ] && /usr/bin/peflags -t1 $perl
/usr/bin/rebase -v -b $baseaddr -o $offset -T rebase$suff.lst
[ -e /usr/bin/peflags.exe ] && /usr/bin/grep .dll rebase$suff.lst | /usr/bin/peflags -d0 -T - >/dev/null
/usr/bin/cat rebase$suff.lst | /usr/bin/xargs chmod g-w
