-
Notifications
You must be signed in to change notification settings - Fork 5
/
clr-avx2-move.pl
executable file
·112 lines (95 loc) · 3.01 KB
/
clr-avx2-move.pl
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
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/perl
use strict;
use File::Path qw(make_path);
if (scalar @ARGV < 3) {
print "clr-avx2-move.pl <libsubdir> <pluginsuffix> <buildroot>\n";
print "Examples:\n";
print " clr-avx2-move.pl haswell .avx2 /var/tmp/buildroot\n";
print " clr-avx2-move.pl haswell/avx512_1 .avx512 /var/tmp/buildroot\n";
exit 0;
}
my $libsubdir = shift @ARGV;
my $pluginsuffix = shift @ARGV;
my $root = shift @ARGV;
my %moves;
my %createddirs;
sub scandir($$) {
my $dir = $_[0];
my $lambda = $_[1];
# Only recurse into this dir if it exists and is not a symlink
return unless (-d $dir && ! -l $dir);
opendir(my $dh, $dir) or die "Couldn't open $dir: $!";
while (readdir $dh) {
next if $_ eq "." || $_ eq "..";
$lambda->("$dir/$_");
}
closedir $dh;
}
sub add_file($) {
my $f = $_[0];
my $soname = 0;
my $interpreter = 0;
my $elftype;
# Run readelf -hdl on the file to get the SONAME and INTERP
open READELF, "-|", "readelf", "-hdl", $f;
while (<READELF>) {
$elftype = $1 if /^\s*Type:\s*(\w+)\b/;
$soname = 1 if / *0x\w+ \(SONAME\)\s/;
$interpreter = 1 if /^\s*INTERP\s/;
}
close READELF;
return if $? >> 8; # not ELF, ignore (could be a script)
return unless $elftype eq "EXEC" || $elftype eq "DYN";
my $to;
if ($soname || $interpreter) {
# This ELF file either has a SONAME (it's a library), an interpreter
# (it's an executable), or both (it's an executable library).
# Move it to the $libsubdir subdir.
$f =~ m,^(.*?)/?([^/]+)$,;
my $dirname = "$1/$libsubdir";
$to = "$dirname/$2";
my $ignored_error;
make_path($dirname, { error => \$ignored_error })
unless defined($createddirs{$dirname});
$createddirs{$dirname} = 1;
} else {
# No SONAME or interpreter, it must be a plugin.
$to = $f . $pluginsuffix;
}
$moves{$f} = $to;
}
# Save STDERR for us, but redirect it to /dev/null for readelf
open(REAL_STDERR, ">&STDERR");
open(STDERR, ">/dev/null");
# Make sure readelf outputs in English
$ENV{LC_ALL} = 'C';
# Build the file listing
my $binlambda = sub {
# executables must be regular files and +x
my $f = $_[0];
add_file($f) if (-f $f && -x $f);
};
scandir("$root/bin", $binlambda);
scandir("$root/sbin", $binlambda);
scandir("$root/usr/bin", $binlambda);
scandir("$root/usr/sbin", $binlambda);
scandir("$root/usr/local/bin", $binlambda);
scandir("$root/usr/local/sbin", $binlambda);
my $liblambda;
$liblambda = sub {
$_ = $_[0];
if (-f $_) {
# It's a library if it's named *.so, *.so.* (except *.so.avx*)
add_file($_) if /\.so($|\.(?!avx))/;
} elsif (-d $_) {
# Lib dirs are recursive
scandir($_, $liblambda) unless m,/$libsubdir$,;
}
};
scandir("$root/usr/lib64", $liblambda);
# Automatically flush STDOUT
$| = 1;
while (my ($f, $to) = each %moves) {
rename($f, $to) and print "$f -> $to\n"
or print REAL_STDERR "rename(\"$f\", \"$to\"): $!\n";
}