summaryrefslogtreecommitdiff
path: root/Porting/findrfuncs
blob: ea019c982a1dd5acb3219a5b2926f2b0add7e10e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/perl -w

#
# findrfuncs: find reentrant variants of functions used in an executable.
# Requires a functional "nm -u".  Searches headers in /usr/include
# to find available *_r functions and looks for non-reentrant
# variants used in the supplied executable.
#
# Gurusamy Sarathy
# gsar@ActiveState.com
#
# Hacked to automatically find the executable and shared objects.
# --jhi

use strict;
use File::Find;

my @EXES;
my $NMU = 'nm -u';
my @INCDIRS = qw(/usr/include);
my $SO = 'so';
my $EXE = '';

if (open(CONFIG, "config.sh")) {
    local $/;
    my $CONFIG = <CONFIG>;
    $SO  = $1 if $CONFIG =~ /^so='(\w+)'/m;
    $EXE = $1 if $CONFIG =~ /^_exe='\.(\w+)'/m;
    close(CONFIG);
}

push @EXES, "perl$EXE";

find(sub {push @EXES, $File::Find::name if /\.$SO$/}, '.' );

push @EXES, @ARGV;

if ($^O eq 'dec_osf') {
    $NMU = 'nm -Bu';
} elsif ($^O eq 'irix') {
    $NMU = 'nm -pu';
}

my %rfuncs;
my @syms;
find(sub {
	return unless -f $File::Find::name;
	local *F;
	open F, "<$File::Find::name"
	    or die "Can't open $File::Find::name: $!";
	my $line;
	# None of the <netdb.h> _r prototypes are to be used in Tru64.
	return if $^O eq 'dec_osf' && $_ eq 'netdb.h';
	while (defined ($line = <F>)) {
	    if ($line =~ /\b(\w+_r)\b/) {
		#warn "$1 => $File::Find::name\n";
		$rfuncs{$1}->{$File::Find::name}++;
	    }
	}
	close F;
     }, @INCDIRS);

# delete bogus symbols grepped out of comments and such
delete $rfuncs{setlocale_r} if $^O eq 'linux';

# delete obsolete (as promised by man pages) symbols
if ($^O eq 'hpux') {
    delete $rfuncs{crypt_r};
    delete $rfuncs{setlocale_r};
    delete $rfuncs{strerror_r};
} elsif ($^O eq 'dec_osf') {
    delete $rfuncs{crypt_r};
    delete $rfuncs{strerror_r};
}

my %syms;

for my $exe (@EXES) {
    # warn "#--- $exe\n";
    for my $sym (`$NMU $exe`) {
        chomp $sym;
        $sym =~ s/^\s+//;
        $sym =~ s/^([0-9A-Fa-f]+\s+)?[Uu]\s+//;
        $sym =~ s/\s+[Uu]\s+-$//;
        next if /\s/;
        $sym =~ s/\@.*\z//;	# remove @@GLIBC_2.0 etc
        # warn "#### $sym\n";
        if (exists $rfuncs{"${sym}_r"} && ! $syms{"$sym:$exe"}++) {
    	    push @syms, $sym;
        }
    }
    
    if (@syms) {
        print "\nFollowing symbols in $exe have reentrant versions:\n";
        for my $sym (@syms) {
	    my @f = sort keys %{$rfuncs{$sym . '_r'}};
    	    print "$sym => $sym" . "_r (@f)\n";
        }
    }
    @syms = ();
}