Skip to content

Commit 5eeeaca

Browse files
authored
Merge pull request #11429 from hugueskamba/hk-no-float-validation
Move script to check for floats and make it Python 2 compatible
2 parents fe12608 + c712d2f commit 5eeeaca

File tree

2 files changed

+85
-61
lines changed

2 files changed

+85
-61
lines changed

tools/executable_analysis_tools/elf-float-checker.py renamed to tools/test/examples/elf_float_checker.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22
# Copyright (c) 2019 Arm Limited and Contributors. All rights reserved.
33
#
44
# SPDX-License-Identifier: Apache-2.0
@@ -10,6 +10,15 @@
1010
import re
1111
import subprocess
1212
import sys
13+
from enum import Enum
14+
15+
class ReturnCode(Enum):
16+
"""Return codes."""
17+
18+
SUCCESS = 0
19+
ERROR = 1
20+
INVALID_OPTIONS = 2
21+
1322

1423
log = logging.getLogger(__name__)
1524

@@ -41,25 +50,26 @@ def get_symbol_table(self, elf_file):
4150
"Get the symbol table for ELF format file '{}'".format(elf_file)
4251
)
4352

44-
cmd = [*OBJECT_FILE_ANALYSIS_CMD, elf_file]
53+
cmd = [OBJECT_FILE_ANALYSIS_CMD[0], OBJECT_FILE_ANALYSIS_CMD[1], elf_file]
4554
log.debug("command: '{}'".format(cmd))
4655
try:
47-
process = subprocess.run(
48-
cmd,
49-
check=True,
50-
stdin=None,
51-
stdout=subprocess.PIPE,
52-
stderr=subprocess.STDOUT,
56+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
57+
except OSError as error:
58+
raise SymbolTableError(
59+
"Getting symbol table for ELF format file '{}' failed,"
60+
" error: {}".format(elf_file, error)
5361
)
54-
except subprocess.CalledProcessError as error:
55-
err_output = error.stdout.decode()
56-
msg = (
62+
63+
stdout, _ = process.communicate()
64+
65+
if process.returncode:
66+
raise SymbolTableError(
5767
"Getting symbol table for ELF format file '{}' failed,"
58-
" error: {}".format(elf_file, err_output)
68+
" error: {}".format(elf_file, stdout.decode())
5969
)
60-
raise SymbolTableError(msg)
6170

62-
symbol_table = process.stdout.decode()
71+
symbol_table = stdout.decode()
72+
6373
log.debug("Symbol table:\n{}\n".format(symbol_table))
6474

6575
return symbol_table
@@ -69,13 +79,17 @@ class SymbolTableError(Exception):
6979
"""An exception for a failure to obtain a symbol table."""
7080

7181

82+
class FloatSymbolsFound(Exception):
83+
"""An exception generated when floating point symbols are found."""
84+
7285
class ArgumentParserWithDefaultHelp(argparse.ArgumentParser):
7386
"""Subclass that always shows the help message on invalid arguments."""
7487

7588
def error(self, message):
7689
"""Error handler."""
7790
sys.stderr.write("error: {}\n".format(message))
7891
self.print_help()
92+
raise SystemExit(ReturnCode.INVALID_OPTIONS.value)
7993

8094

8195
def set_log_verbosity(increase_verbosity):
@@ -91,6 +105,7 @@ def check_float_symbols(elf_file):
91105
92106
Return the floating point symbols found.
93107
"""
108+
print("Checking {} for floating point symbols".format(elf_file))
94109
parser = SymbolParser()
95110
symbol_table = parser.get_symbol_table(elf_file)
96111

@@ -105,11 +120,12 @@ def check_action(args):
105120
"""Entry point for checking the ELF file."""
106121
float_symbols = check_float_symbols(args.elf_file)
107122
if float_symbols:
108-
print("Found float symbols:")
123+
print("Failed - Found float symbols:")
109124
for float_symbol in float_symbols:
110125
print(float_symbol)
126+
raise FloatSymbolsFound("Found float symbols in {}".format(args.elf_file))
111127
else:
112-
print("No float symbols found.")
128+
print("Passed - No float symbols found.")
113129

114130

115131
def parse_args():
@@ -160,9 +176,15 @@ def run_elf_floats_checker():
160176
args.func(args)
161177

162178

163-
if __name__ == "__main__":
179+
def _main():
164180
"""Run elf-floats-checker."""
165181
try:
166182
run_elf_floats_checker()
167183
except Exception as error:
168184
print(error)
185+
return ReturnCode.ERROR.value
186+
else:
187+
return ReturnCode.SUCCESS.value
188+
189+
if __name__ == "__main__":
190+
sys.exit(_main())

tools/executable_analysis_tools/test_elf-float-checker.py renamed to tools/test/examples/test_elf_float_checker.py

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77

88
import importlib
99
import mock
10+
import os
1011
import subprocess
11-
from pathlib import Path
1212

1313

14-
TARGET = importlib.import_module("elf-float-checker")
14+
TARGET = importlib.import_module("elf_float_checker")
1515

1616
SYMBOL_TABLE_WITHOUT_FLOATS = (
1717
" Symbol table '.symtab' contains 2723 entries:\n"
@@ -39,82 +39,84 @@
3939
]
4040

4141
SYMBOL_TABLE_WITH_FLOATS = (
42-
" Symbol table '.symtab' contains 2723 entries:\n"
43-
"Num: Value Size Type Bind Vis Ndx Name\n"
44-
f" 0: 00000000 0 NOTYPE LOCAL DEFAULT UND \n"
45-
f" 1: 000045fd 16 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[0]}\n"
46-
f" 2: 00004609 16 FUNC GLOBAL HIDDEN 3 lp_ticker_disable_interrupt\n"
47-
f" 3: 00004615 16 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[1]}\n"
48-
f" 4: 00004625 36 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[2]}\n"
49-
f" 5: 00004645 8 FUNC GLOBAL HIDDEN 3 lp_ticker_get_info\n"
50-
f" 6: 0000464d 116 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[3]}\n"
51-
f" 7: 000046bd 20 FUNC GLOBAL HIDDEN 3 lp_ticker_irq_handler\n"
52-
f" 8: 000046d1 16 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[4]}\n"
53-
f" 9: 000046e1 52 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[5]}\n"
54-
f" 10: 000046f1 52 FUNC GLOBAL HIDDEN 3 {FLOAT_SYMBOLS[6]}\n"
42+
" Symbol table '.symtab' contains 2723 entries:\n"+
43+
"Num: Value Size Type Bind Vis Ndx Name\n"+
44+
" 0: 00000000 0 NOTYPE LOCAL DEFAULT UND \n"+
45+
" 1: 000045fd 16 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[0])+
46+
" 2: 00004609 16 FUNC GLOBAL HIDDEN 3 lp_ticker_disable_interrupt\n"+
47+
" 3: 00004615 16 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[1])+
48+
" 4: 00004625 36 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[2])+
49+
" 5: 00004645 8 FUNC GLOBAL HIDDEN 3 lp_ticker_get_info\n"+
50+
" 6: 0000464d 116 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[3])+
51+
" 7: 000046bd 20 FUNC GLOBAL HIDDEN 3 lp_ticker_irq_handler\n"+
52+
" 8: 000046d1 16 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[4])+
53+
" 9: 000046e1 52 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[5])+
54+
" 10: 000046f1 52 FUNC GLOBAL HIDDEN 3 {}\n".format(FLOAT_SYMBOLS[6])
5555
)
5656

5757

5858
ELF_FORMAT_FILE = "mbed-os-example.elf"
59-
OBJECT_FILE_ANALYSIS_CMD = [*(TARGET.OBJECT_FILE_ANALYSIS_CMD), f"{ELF_FORMAT_FILE}"]
59+
OBJECT_FILE_ANALYSIS_CMD = [
60+
TARGET.OBJECT_FILE_ANALYSIS_CMD[0],
61+
TARGET.OBJECT_FILE_ANALYSIS_CMD[1],
62+
"{}".format(ELF_FORMAT_FILE)
63+
]
6064

6165
class TestElfFloatChecker:
6266
"""Test class"""
6367

6468
@classmethod
6569
def setup_class(cls):
6670
# Create a dummy ELF format file
67-
Path(ELF_FORMAT_FILE).touch()
71+
if not os.path.exists(ELF_FORMAT_FILE):
72+
with open(ELF_FORMAT_FILE, 'w'): pass
6873

6974
@classmethod
7075
def teardown_class(cls):
7176
# Remove the dummy ELF format file
72-
Path(ELF_FORMAT_FILE).unlink()
77+
if os.path.exists(ELF_FORMAT_FILE):
78+
os.remove(ELF_FORMAT_FILE)
7379

74-
@mock.patch("subprocess.run")
80+
@mock.patch("subprocess.Popen")
7581
def test_correctly_detect_absence_of_float_symbols(
76-
self, mock_subprocess_run
82+
self, mock_subprocess_popen
7783
):
7884
"""Test that no false positive occur."""
79-
mock_subprocess_run.return_value = subprocess.CompletedProcess(
80-
args=(
81-
f"{OBJECT_FILE_ANALYSIS_CMD}"
82-
" check=True, stderr=-2, stdin=None, stdout=-1"
85+
process_mock = mock.Mock()
86+
attrs = {
87+
"communicate.return_value":(
88+
SYMBOL_TABLE_WITHOUT_FLOATS.encode(), None
8389
),
84-
returncode=0,
85-
stdout=SYMBOL_TABLE_WITHOUT_FLOATS.encode(),
86-
stderr=None,
87-
)
90+
"returncode": 0,
91+
}
92+
process_mock.configure_mock(**attrs)
93+
mock_subprocess_popen.return_value = process_mock
8894
assert [] == TARGET.check_float_symbols(ELF_FORMAT_FILE)
89-
mock_subprocess_run.assert_called_with(
95+
mock_subprocess_popen.assert_called_with(
9096
OBJECT_FILE_ANALYSIS_CMD,
91-
check=True,
92-
stdin=None,
9397
stdout=subprocess.PIPE,
9498
stderr=subprocess.STDOUT,
9599
)
96100

97-
@mock.patch("subprocess.run")
101+
@mock.patch("subprocess.Popen")
98102
def test_correctly_detect_presence_of_float_symbols(
99-
self, mock_subprocess_run
103+
self, mock_subprocess_popen
100104
):
101105
"""Test that float symbols can be discovered in a symbol table."""
102-
mock_subprocess_run.return_value = subprocess.CompletedProcess(
103-
args=(
104-
f"{OBJECT_FILE_ANALYSIS_CMD}"
105-
" check=True, stderr=-2, stdin=None, stdout=-1"
106+
process_mock = mock.Mock()
107+
attrs = {
108+
"communicate.return_value":(
109+
SYMBOL_TABLE_WITH_FLOATS.encode(), None
106110
),
107-
returncode=0,
108-
stdout=SYMBOL_TABLE_WITH_FLOATS.encode(),
109-
stderr=None,
110-
)
111+
"returncode": 0,
112+
}
113+
process_mock.configure_mock(**attrs)
114+
mock_subprocess_popen.return_value = process_mock
111115
assert FLOAT_SYMBOLS == TARGET.check_float_symbols(
112116
ELF_FORMAT_FILE
113117
)
114-
mock_subprocess_run.assert_called_with(
118+
mock_subprocess_popen.assert_called_with(
115119
OBJECT_FILE_ANALYSIS_CMD,
116-
check=True,
117-
stdin=None,
118120
stdout=subprocess.PIPE,
119121
stderr=subprocess.STDOUT,
120122
)

0 commit comments

Comments
 (0)