2 # Check ELF program headers for WX segments.
3 # Copyright (C) 2020 Free Software Foundation, Inc.
4 # This file is part of the GNU C Library.
6 # The GNU C Library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # The GNU C Library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with the GNU C Library; if not, see
18 # <https://www.gnu.org/licenses/>.
20 """Check that the program headers do not contain write-exec segments."""
27 # Regular expression to extract the RWE flags field. The
28 # address/offset columns have varying width.
30 r
'^ LOAD +(?:0x[0-9a-fA-F]+ +){5}([R ][W ][ E]) +0x[0-9a-fA-F]+\n\Z')
32 def process_file(path
, inp
, xfail
):
33 """Analyze one input file."""
38 if line
.startswith(' LOAD '):
39 match
= RE_LOAD
.match(line
)
41 error
= 'Invalid LOAD line'
43 flags
, = match
.groups()
44 if 'W' in flags
and 'E' in flags
:
46 print('{}: warning: WX segment (as expected)'.format(
52 print('{}: error: {}: {!r}'.format(path
, error
, line
.strip()))
55 if xfail
and errors
== 0:
56 print('{}: warning: missing expected WX segment'.format(path
))
61 """The main entry point."""
62 parser
= argparse
.ArgumentParser(description
=__doc__
)
63 parser
.add_argument('--xfail',
64 help='Mark input files as XFAILed ("*" for all)',
66 parser
.add_argument('phdrs',
67 help='Files containing readelf -Wl output',
69 opts
= parser
.parse_args(sys
.argv
)
71 xfails
= set(opts
.xfail
.split(' '))
72 xfails_all
= opts
.xfail
.strip() == '*'
75 for path
in opts
.phdrs
:
76 xfail
= ((os
.path
.basename(path
) + '.phdrs') in xfails
78 with
open(path
) as inp
:
79 errors
+= process_file(path
, inp
, xfail
)
84 if __name__
== '__main__':