#!/usr/bin/perl -w
eval 'exec perl -w -S $0 ${1+"$@"}'
    if $running_under_some_shell;
$running_under_some_shell = 0;

######################################################################
#
# Copyright  Freescale Semiconductor, Inc. 2004-2007. All rights reserved.
#
# Stuart Hughes, stuarth@freescale.com,  22nd Feb 2005
# Steve Papacharalambous, stevep@freescale.com, 13 Sept 2005
#
# This file is part of LTIB.
#
# LTIB 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 2 of the License, or
# (at your option) any later version.
#
# LTIB 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 LTIB; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# Description:
#
# Recurse directory and try to strip debug symbols.
#
#
#------------------------------------------------------------------------------
# Permissions: http://www.oreilly.com/pub/a/oreilly/ask_tim/2001/codepolicy.html# Ref:         http://www.oreilly.com/catalog/cookbook/
# Download:    http://examples.oreilly.com/cookbook/pcookexamples.tar.gz
#
# Author:    Tom Christiansen (tchrist@mox.perl.com)
# Book:      Perl Cookbook (example 6.9)
# Publisher: O'Reilly
# ISBN:      1-56592-243-3
#
# Modified by Steve Papacharalambous stevep@freescale.com 03 October 2006
#
######################################################################
use Getopt::Std;
$opt_t = "";
$opt_h = 0;
$opt_v = 0;
$opt_d = 0;
$opt_s = 0;
$opt_e = "";
$opt_w = "";
$ex_pattern = "";
@dont_strip = ();

$usage = <<TXT;
Usage: stripall [ -v ] [ -d ] [ -s ] [ -t <target strip prefix> ] [ -w <workstation strip prefix> ] [ -e <exclude file> ] [ directory ]
    Where:
        -v     : verbose
        -d     : debug
        -s     : speedup (only examine xxx, xxx.exe, .o, .so, .ko, .a files)
TXT

getopts('t:w:e:hvds') or die($usage);
die($usage) if $opt_h;
$dir = shift || ".";
$targ_objdump = ($opt_t . "objdump -f");

if( $opt_w ) {
    $host_objdump = ($opt_w . "objdump -f");
    $host_strip = ($opt_w . "strip");
} else {
    $host_objdump = "/usr/bin/objdump -f";
    $host_strip = "/usr/bin/strip";
}

local $_ = `$host_objdump --version 2> /dev/null` || die "Path to host tools not set up, aborting...\n\n";

local $_ = `$targ_objdump --version 2> /dev/null` || die "Path to target tools not set up, aborting...\n\n";

if( $opt_e ) {
    open(EXCLUDE, "< $opt_e") || die "Can't open $opt_e: $!\n\n";
    while ( <EXCLUDE> ) {
        chomp;
        push(@dont_strip, glob2pat($_));
    }
    close(EXCLUDE);
    $ex_pattern = join "|" , @dont_strip;
    $ex_pattern = "(" . $ex_pattern . ")";
}

print "Host strip: $host_strip\n" if $opt_v;
print "Host objdump: $host_objdump\n" if $opt_v;
print "Target strip: ${opt_t}strip\n" if $opt_v;
print "Target objdump: $targ_objdump\n" if $opt_v;
print "Strip exclude pattern: $ex_pattern\n" if $opt_v;


strip_subdir();


sub strip_subdir
{
    foreach $fn ( split( /\n/, `find $dir -type f`) ) {
        if( $opt_e && $fn =~ m#$ex_pattern$#o ) {
            warn("$fn excluded from stripping, skipping.\n") if $opt_v || $opt_d;
            next;
        }
        if( $opt_s ) {
            if( $fn =~ m,(?:/[^.]+|.\.exe|\.o|\.so|\.so[.\d]+|\.a|\.ko)$, ) {
                warn "Do : $fn\n" if $opt_d;
            } else {
                warn "Skip: $fn\n" if $opt_d;
                next;
            }
        }
    
        warn "running $targ_objdump $fn\n" if $opt_d;
        $_ = `$targ_objdump $fn 2>&1`;

        # Test whether the format of the file to be stripped is one that can
        # be stripped by the target tools.
        if( ! m#(?:architecture:\s+UNKNOWN!)|(?:File\s+format\s+not\s+recognized)# ) {
            warn "running file $fn\n" if $opt_d;
            $_ = `file $fn`;
            warn("WARN: $fn statically linked\n") if m#statically#;

            # Second test whether the file format is one that can be stripped.
            if ( m#(?:not\s+stripped)|(?:Intel\s+80386\s+console\s+executable\s+not\s+relocatable)# ) {
                warn("Stripping targ (${opt_t}strip): $fn\n") if $opt_v || $opt_d;
                system($opt_t . "strip -g $fn 2> /dev/null");
            }
            next;
        }
        warn "running $host_objdump $fn\n" if $opt_d;
        $_ = `$host_objdump $fn 2>&1`;

        # Test whether the format of the file to be stripped is one that can
        # be stripped by the host tools.
        if( ! m#(?:architecture:\s+UNKNOWN!)|(?:File\s+format\s+not\s+recognized)# ) {
            warn "running file $fn\n" if $opt_d;
            $_ = `file $fn`;
            warn("WARN: $fn statically linked\n") if m#statically#;

            # Second test whether the file format is one that can be stripped.
            if ( m#(?:not\s+stripped)|(?:Intel\s+80386\s+console\s+executable\s+not\s+relocatable)# ) {
                warn("Stripping host ($host_strip): $fn\n") if $opt_v || $opt_d;
                system($host_strip . " -g $fn 2> /dev/null");
            }
            next;
        }
    }
    return 1;
}


# Convert four shell wildcard characters to their equivalent regular
# expression, all other characters will be quoted to render them literals.
sub glob2pat {
    my $globstr = shift;
    my %patmap = (
        '*' => '.*',
        '?' => '.',
        '[' => '[',
        ']' => ']',
    );
    $globstr =~ s{(.)} { $patmap{$1} || "\Q$1" }ge;
    return $globstr . '$';
}

