blob: cf247425a1bcadaa56c160b19e388afa5a4e43b1 [file] [log] [blame]
Jim Cownie5e8470a2013-09-27 10:38:44 +00001#!/usr/bin/perl
2
3#
4#//===----------------------------------------------------------------------===//
5#//
6#// The LLVM Compiler Infrastructure
7#//
8#// This file is dual licensed under the MIT and the University of Illinois Open
9#// Source Licenses. See LICENSE.txt for details.
10#//
11#//===----------------------------------------------------------------------===//
12#
13
14use strict;
15use warnings;
16
17use FindBin;
18use lib "$FindBin::Bin/lib";
19
20use tools;
21
22our $VERSION = "0.002";
Jonathan Peyton4c91ad12016-01-26 19:44:31 +000023my $target_arch;
Jim Cownie5e8470a2013-09-27 10:38:44 +000024
25sub execstack($) {
26 my ( $file ) = @_;
27 my @output;
28 my @stack;
Andrey Churbanovd315cea2015-01-16 12:54:51 +000029 my $tool;
30 if($target_arch eq "mic") {
31 $tool = "x86_64-k1om-linux-readelf";
32 } else {
33 $tool = "readelf";
34 }
35 execute( [ $tool, "-l", "-W", $file ], -stdout => \@output );
Jim Cownie5e8470a2013-09-27 10:38:44 +000036 @stack = grep( $_ =~ m{\A\s*(?:GNU_)?STACK\s+}, @output );
37 if ( not @stack ) {
38 # Interpret missed "STACK" line as error.
39 runtime_error( "$file: No stack segment found; looks like stack would be executable." );
40 }; # if
41 if ( @stack > 1 ) {
42 runtime_error( "$file: More than one stack segment found.", "readelf output:", @output, "(eof)" );
43 }; # if
44 # Typical stack lines are:
45 # Linux* OS IA-32 architecture:
46 # GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
47 # Linux* OS Intel(R) 64:
48 # GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x8
49 if ( $stack[ 0 ] !~ m{\A\s*(?:GNU_)?STACK(?:\s+0x[0-9a-f]+){5}\s+([R ][W ][E ])\s+0x[0-9a-f]+\s*\z} ) {
50 runtime_error( "$file: Cannot parse stack segment line:", ">>> $stack[ 0 ]" );
51 }; # if
52 my $attrs = $1;
53 if ( $attrs =~ m{E} ) {
54 runtime_error( "$file: Stack is executable" );
55 }; # if
56}; # sub execstack
57
58get_options(
Jonathan Peyton4c91ad12016-01-26 19:44:31 +000059 "arch=s" => \$target_arch,
Jim Cownie5e8470a2013-09-27 10:38:44 +000060);
61
62foreach my $file ( @ARGV ) {
63 execstack( $file );
64}; # foreach $file
65
66exit( 0 );
67
68__END__
69
70=pod
71
72=head1 NAME
73
74B<check-execstack.pl> -- Check whether stack is executable, issue an error if so.
75
76=head1 SYNOPSIS
77
78B<check-execstack.pl> I<optiion>... I<file>...
79
80=head1 DESCRIPTION
81
82The script checks whether stack of specified executable file, and issues error if stack is
83executable. If stack is not executable, the script exits silently with zero exit code.
84
85The script runs C<readelf> utility to get information about specified executable file. So, the
86script fails if C<readelf> is not available. Effectively it means the script works only on Linux* OS
87(and, probably, Intel(R) Many Integrated Core Architecture).
88
89=head1 OPTIONS
90
91=over
92
93=item Standard Options
94
95=over
96
97=item B<--doc>
98
99=item B<--manual>
100
101Print full help message and exit.
102
103=item B<--help>
104
105Print short help message and exit.
106
107=item B<--usage>
108
109Print very short usage message and exit.
110
111=item B<--verbose>
112
113Do print informational messages.
114
115=item B<--version>
116
117Print program version and exit.
118
119=item B<--quiet>
120
121Work quiet, do not print informational messages.
122
123=back
124
125=back
126
127=head1 ARGUMENTS
128
129=over
130
131=item I<file>
132
133A name of executable or shared object to check. Multiple files may be specified.
134
135=back
136
137=head1 EXAMPLES
138
Jonathan Peytonf0efbb52015-06-01 02:41:44 +0000139Check libomp.so library:
Jim Cownie5e8470a2013-09-27 10:38:44 +0000140
Jonathan Peytonf0efbb52015-06-01 02:41:44 +0000141 $ check-execstack.pl libomp.so
Jim Cownie5e8470a2013-09-27 10:38:44 +0000142
143=cut
144
145# end of file #
146