mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-05 07:28:29 -04:00
waf: prevent use of C++ library calls that can cause exceptions
this cleans up our blacklist of library functions, and ensures there can be no accidential use of std:: functions that cause exceptions in flight code on HAL_ChibiOS
This commit is contained in:
parent
20cb709ca2
commit
4ad1231c8f
@ -262,6 +262,7 @@ def ap_program(bld,
|
|||||||
program_dir=None,
|
program_dir=None,
|
||||||
use_legacy_defines=True,
|
use_legacy_defines=True,
|
||||||
program_name=None,
|
program_name=None,
|
||||||
|
vehicle_binary=True,
|
||||||
**kw):
|
**kw):
|
||||||
if 'target' in kw:
|
if 'target' in kw:
|
||||||
bld.fatal('Do not pass target for program')
|
bld.fatal('Do not pass target for program')
|
||||||
@ -300,6 +301,9 @@ def ap_program(bld,
|
|||||||
program_dir=program_dir,
|
program_dir=program_dir,
|
||||||
**kw
|
**kw
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tg.env.vehicle_binary = vehicle_binary
|
||||||
|
|
||||||
if 'use' in kw and bld.env.STATIC_LINKING:
|
if 'use' in kw and bld.env.STATIC_LINKING:
|
||||||
# ensure we link against vehicle library
|
# ensure we link against vehicle library
|
||||||
tg.env.STLIB += [kw['use']]
|
tg.env.STLIB += [kw['use']]
|
||||||
@ -313,7 +317,7 @@ def ap_program(bld,
|
|||||||
@conf
|
@conf
|
||||||
def ap_example(bld, **kw):
|
def ap_example(bld, **kw):
|
||||||
kw['program_groups'] = 'examples'
|
kw['program_groups'] = 'examples'
|
||||||
ap_program(bld, use_legacy_defines=False, **kw)
|
ap_program(bld, use_legacy_defines=False, vehicle_binary=False, **kw)
|
||||||
|
|
||||||
def unique_list(items):
|
def unique_list(items):
|
||||||
'''remove duplicate elements from a list while maintaining ordering'''
|
'''remove duplicate elements from a list while maintaining ordering'''
|
||||||
@ -383,6 +387,7 @@ def ap_find_tests(bld, use=[], DOUBLE_PRECISION_SOURCES=[]):
|
|||||||
program_name=f.change_ext('').name,
|
program_name=f.change_ext('').name,
|
||||||
program_groups='tests',
|
program_groups='tests',
|
||||||
use_legacy_defines=False,
|
use_legacy_defines=False,
|
||||||
|
vehicle_binary=False,
|
||||||
cxxflags=['-Wno-undef'],
|
cxxflags=['-Wno-undef'],
|
||||||
)
|
)
|
||||||
filename = os.path.basename(f.abspath())
|
filename = os.path.basename(f.abspath())
|
||||||
@ -444,6 +449,7 @@ def ap_find_benchmarks(bld, use=[]):
|
|||||||
includes=includes,
|
includes=includes,
|
||||||
source=[f],
|
source=[f],
|
||||||
use=use,
|
use=use,
|
||||||
|
vehicle_binary=False,
|
||||||
program_name=f.change_ext('').name,
|
program_name=f.change_ext('').name,
|
||||||
program_groups='benchmarks',
|
program_groups='benchmarks',
|
||||||
use_legacy_defines=False,
|
use_legacy_defines=False,
|
||||||
|
@ -14,6 +14,7 @@ import re
|
|||||||
import pickle
|
import pickle
|
||||||
import struct
|
import struct
|
||||||
import base64
|
import base64
|
||||||
|
import subprocess
|
||||||
|
|
||||||
_dynamic_env_data = {}
|
_dynamic_env_data = {}
|
||||||
def _load_dynamic_env_data(bld):
|
def _load_dynamic_env_data(bld):
|
||||||
@ -143,6 +144,27 @@ class set_default_parameters(Task.Task):
|
|||||||
defaults.save()
|
defaults.save()
|
||||||
|
|
||||||
|
|
||||||
|
def check_elf_symbols(task):
|
||||||
|
'''
|
||||||
|
check for disallowed symbols in elf file, such as C++ exceptions
|
||||||
|
'''
|
||||||
|
elfpath = task.inputs[0].abspath()
|
||||||
|
|
||||||
|
if not task.env.vehicle_binary or task.env.SIM_ENABLED:
|
||||||
|
# we only want to check symbols for vehicle binaries, allowing examples
|
||||||
|
# to use C++ exceptions. We also allow them in simulator builds
|
||||||
|
return
|
||||||
|
|
||||||
|
# we use string find on these symbols, so this catches all types of throw
|
||||||
|
# calls this should catch all uses of exceptions unless the compiler
|
||||||
|
# manages to inline them
|
||||||
|
blacklist = ['std::__throw']
|
||||||
|
|
||||||
|
nmout = subprocess.getoutput("%s -C %s" % (task.env.get_flat('NM'), elfpath))
|
||||||
|
for b in blacklist:
|
||||||
|
if nmout.find(b) != -1:
|
||||||
|
raise Errors.WafError("Disallowed symbol in %s: %s" % (elfpath, b))
|
||||||
|
|
||||||
class generate_bin(Task.Task):
|
class generate_bin(Task.Task):
|
||||||
color='CYAN'
|
color='CYAN'
|
||||||
# run_str="${OBJCOPY} -O binary ${SRC} ${TGT}"
|
# run_str="${OBJCOPY} -O binary ${SRC} ${TGT}"
|
||||||
@ -154,6 +176,8 @@ class generate_bin(Task.Task):
|
|||||||
def keyword(self):
|
def keyword(self):
|
||||||
return "Generating"
|
return "Generating"
|
||||||
def run(self):
|
def run(self):
|
||||||
|
check_elf_symbols(self)
|
||||||
|
|
||||||
if self.env.HAS_EXTERNAL_FLASH_SECTIONS:
|
if self.env.HAS_EXTERNAL_FLASH_SECTIONS:
|
||||||
ret = self.split_sections()
|
ret = self.split_sections()
|
||||||
if (ret < 0):
|
if (ret < 0):
|
||||||
@ -529,6 +553,7 @@ def configure(cfg):
|
|||||||
cfg.find_program('make', var='MAKE')
|
cfg.find_program('make', var='MAKE')
|
||||||
#cfg.objcopy = cfg.find_program('%s-%s'%(cfg.env.TOOLCHAIN,'objcopy'), var='OBJCOPY', mandatory=True)
|
#cfg.objcopy = cfg.find_program('%s-%s'%(cfg.env.TOOLCHAIN,'objcopy'), var='OBJCOPY', mandatory=True)
|
||||||
cfg.find_program('arm-none-eabi-objcopy', var='OBJCOPY')
|
cfg.find_program('arm-none-eabi-objcopy', var='OBJCOPY')
|
||||||
|
cfg.find_program('arm-none-eabi-nm', var='NM')
|
||||||
env = cfg.env
|
env = cfg.env
|
||||||
bldnode = cfg.bldnode.make_node(cfg.variant)
|
bldnode = cfg.bldnode.make_node(cfg.variant)
|
||||||
def srcpath(path):
|
def srcpath(path):
|
||||||
@ -716,16 +741,19 @@ def build(bld):
|
|||||||
if bld.env.ENABLE_CRASHDUMP:
|
if bld.env.ENABLE_CRASHDUMP:
|
||||||
bld.env.LINKFLAGS += ['-Wl,-whole-archive', 'modules/ChibiOS/libcc.a', '-Wl,-no-whole-archive']
|
bld.env.LINKFLAGS += ['-Wl,-whole-archive', 'modules/ChibiOS/libcc.a', '-Wl,-no-whole-archive']
|
||||||
# list of functions that will be wrapped to move them out of libc into our
|
# list of functions that will be wrapped to move them out of libc into our
|
||||||
# own code note that we also include functions that we deliberately don't
|
# own code
|
||||||
# implement anywhere (the FILE* functions). This allows us to get link
|
wraplist = ['sscanf', 'fprintf', 'snprintf', 'vsnprintf', 'vasprintf', 'asprintf', 'vprintf', 'scanf', 'printf']
|
||||||
# errors if we accidentially try to use one of those functions either
|
|
||||||
# directly or via another libc call
|
# list of functions that we will give a link error for if they are
|
||||||
wraplist = ['sscanf', 'fprintf', 'snprintf', 'vsnprintf','vasprintf','asprintf','vprintf','scanf',
|
# used. This is to prevent accidential use of these functions
|
||||||
'printf',
|
blacklist = ['_sbrk', '_sbrk_r', '_malloc_r', '_calloc_r', '_free_r', 'ftell',
|
||||||
'fopen', 'fflush', 'fwrite', 'fread', 'fputs', 'fgets',
|
'fopen', 'fflush', 'fwrite', 'fread', 'fputs', 'fgets',
|
||||||
'clearerr', 'fseek', 'ferror', 'fclose', 'tmpfile', 'getc', 'ungetc', 'feof',
|
'clearerr', 'fseek', 'ferror', 'fclose', 'tmpfile', 'getc', 'ungetc', 'feof',
|
||||||
'ftell', 'freopen', 'remove', 'vfprintf', 'fscanf',
|
'ftell', 'freopen', 'remove', 'vfprintf', 'vfprintf_r', 'fscanf',
|
||||||
'_gettimeofday', '_times', '_times_r', '_gettimeofday_r', 'time', 'clock',
|
'_gettimeofday', '_times', '_times_r', '_gettimeofday_r', 'time', 'clock']
|
||||||
'_sbrk', '_sbrk_r', '_malloc_r', '_calloc_r', '_free_r']
|
|
||||||
for w in wraplist:
|
# these functions use global state that is not thread safe
|
||||||
|
blacklist += ['gmtime']
|
||||||
|
|
||||||
|
for w in wraplist + blacklist:
|
||||||
bld.env.LINKFLAGS += ['-Wl,--wrap,%s' % w]
|
bld.env.LINKFLAGS += ['-Wl,--wrap,%s' % w]
|
||||||
|
Loading…
Reference in New Issue
Block a user