xref: /llvm-project/openmp/runtime/tools/check-execstack.py (revision 88dae3d5d0230747f3cbabdde9ac5ae9e5dc3f8d)
1#!/usr/bin/env python3
2
3#
4# //===----------------------------------------------------------------------===//
5# //
6# // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
7# // See https://llvm.org/LICENSE.txt for license information.
8# // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9# //
10# //===----------------------------------------------------------------------===//
11#
12
13import argparse
14import os
15import re
16import sys
17from libomputils import ScriptError, error, print_error_line, execute_command
18
19
20def is_stack_executable_readelf(library):
21    """Returns true if stack of library file is executable"""
22    r = execute_command(["readelf", "-l", "-W", library])
23    if r.returncode != 0:
24        error("{} failed".format(r.command))
25    stack_lines = []
26    for line in r.stdout.split(os.linesep):
27        if re.search("STACK", line):
28            stack_lines.append(line.strip())
29    if not stack_lines:
30        error("{}: Not stack segment found".format(library))
31    if len(stack_lines) > 1:
32        error("{}: More than one stack segment found".format(library))
33    h = r"0x[0-9a-fA-F]+"
34    m = re.search(
35        r"((GNU_)?STACK)\s+({0})\s+({0})\s+({0})\s+({0})\s+({0})"
36        " ([R ][W ][E ])".format(h),
37        stack_lines[0],
38    )
39    if not m:
40        error("{}: Cannot parse stack segment line".format(library))
41    if m:
42        flags = m.group(8)
43        if "E" in flags:
44            return True
45    return False
46
47
48def main():
49    parser = argparse.ArgumentParser(
50        description="Check library does not have" " executable stack"
51    )
52    parser.add_argument("library", help="The library file to check")
53    commandArgs = parser.parse_args()
54    if is_stack_executable_readelf(commandArgs.library):
55        error("{}: Stack is executable".format(commandArgs.library))
56
57
58if __name__ == "__main__":
59    try:
60        main()
61    except ScriptError as e:
62        print_error_line(str(e))
63        sys.exit(1)
64
65# end of file
66