From 1917a52dda461ad8039fe2728aa5c7125a69c381 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 30 Jan 2024 10:25:53 -0800 Subject: [PATCH] Handle `-Wl,--stack-first` being passed explicitly Fixes: #21215 --- test/test_other.py | 9 +++++++++ tools/link.py | 24 +++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/test/test_other.py b/test/test_other.py index 4a226a7b490b..8fe7c710171c 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -1197,6 +1197,15 @@ def test_wl_linkflags(self): self.run_process([EMCC, 'main.c', '-Wl,-L.', '-Wl,-lfoo']) self.run_process([EMCC, 'main.c', '-Wl,@linkflags.txt']) + def test_wl_stackfirst(self): + cmd = [EMCC, test_file('hello_world.c'), '-Wl,--stack-first'] + self.run_process(cmd + ['-O0']) + self.run_process(cmd + ['-O2']) + err = self.expect_fail(cmd + ['-fsanitize=address']) + self.assertContained('error: --stack-first is not compatible with asan', err) + err = self.expect_fail(cmd + ['-sGLOBAL_BASE=1024']) + self.assertContained('error: --stack-first is not compatible with -sGLOBAL_BASE', err) + def test_l_link(self): # Linking with -lLIBNAME and -L/DIRNAME should work, also should work with spaces create_file('main.c', ''' diff --git a/tools/link.py b/tools/link.py index e4b0517b4d14..e0dc389d4ae7 100644 --- a/tools/link.py +++ b/tools/link.py @@ -879,14 +879,6 @@ def phase_linker_setup(options, state, newargs): else: default_setting('INCOMING_MODULE_JS_API', []) - if 'GLOBAL_BASE' not in user_settings and not settings.SHRINK_LEVEL and not settings.OPT_LEVEL: - # When optimizing for size it helps to put static data first before - # the stack (since this makes instructions for accessing this data - # use a smaller LEB encoding). - # However, for debugability is better to have the stack come first - # (because stack overflows will trap rather than corrupting data). - settings.STACK_FIRST = True - # Default to TEXTDECODER=2 (always use TextDecoder to decode UTF-8 strings) # in -Oz builds, since custom decoder for UTF-8 takes up space. # In pthreads enabled builds, TEXTDECODER==2 may not work, see @@ -1592,7 +1584,6 @@ def check_memory_setting(setting): # We start our global data after the shadow memory. # We don't need to worry about alignment here. wasm-ld will take care of that. settings.GLOBAL_BASE = shadow_size - settings.STACK_FIRST = False if not settings.ALLOW_MEMORY_GROWTH: settings.INITIAL_MEMORY = total_mem @@ -1615,6 +1606,21 @@ def check_memory_setting(setting): if sanitize and settings.GENERATE_SOURCE_MAP: settings.LOAD_SOURCE_MAP = 1 + if 'GLOBAL_BASE' not in user_settings and not settings.SHRINK_LEVEL and not settings.OPT_LEVEL and not settings.USE_ASAN: + # When optimizing for size it helps to put static data first before + # the stack (since this makes instructions for accessing this data + # use a smaller LEB encoding). + # However, for debugability is better to have the stack come first + # (because stack overflows will trap rather than corrupting data). + settings.STACK_FIRST = True + + if '--stack-first' in [x for _, x in state.link_flags]: + settings.STACK_FIRST = True + if settings.USE_ASAN: + exit_with_error('--stack-first is not compatible with asan') + if 'GLOBAL_BASE' in user_settings: + exit_with_error('--stack-first is not compatible with -sGLOBAL_BASE') + set_max_memory() # check if we can address the 2GB mark and higher.