Skip to content

Commit

Permalink
Drop explicitly passed -lc unless -nodefaultlibs or similar is passed
Browse files Browse the repository at this point in the history
There have been a lot of bugs when the caller passes `-lc` over the years. For
example it crashes if we do:
```
emcc -lc -sDISABLE_EXCEPTION_CATCHING=0 -sMIN_SAFARI_VERSION=150000
```

Rust likes to pass `-lc`. Let's drop it and stop causing trouble for Rust.

Resolves emscripten-core#22758, emscripten-core#22742 and would have resolved emscripten-core#16680 if it hadn't disappeared
first.
  • Loading branch information
hoodmane committed Oct 18, 2024
1 parent ac381b8 commit 3414463
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
3 changes: 3 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -15169,3 +15169,6 @@ def test_fp16(self, opts):

def test_embool(self):
self.do_other_test('test_embool.c')

def test_user_passed_lc(self):
self.run_process([EMCC, '-lc', '-sDISABLE_EXCEPTION_CATCHING=0', '-sMIN_SAFARI_VERSION=150000'])
16 changes: 12 additions & 4 deletions tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -2749,7 +2749,7 @@ def map_to_js_libs(library_name):
return None


def process_libraries(state, linker_inputs):
def process_libraries(state, linker_inputs, nodefaultlibc):
new_flags = []
libraries = []
suffixes = STATICLIB_ENDINGS + DYNAMICLIB_ENDINGS
Expand All @@ -2761,6 +2761,12 @@ def process_libraries(state, linker_inputs):
new_flags.append((i, flag))
continue
lib = removeprefix(flag, '-l')
if lib == 'c' and not nodefaultlibc:
# Drop explicitly passed -lc unless they also passed -nodefaultlibs or
# similar. It's important to link libc after our other injected system
# libraries like libbulkmemory, but user linked libraries go ahead of
# system libraries, so if the user passes `-lc` then we can get crashes.
continue

logger.debug('looking for library "%s"', lib)

Expand Down Expand Up @@ -3026,12 +3032,12 @@ def package_files(options, target):


@ToolchainProfiler.profile_block('calculate linker inputs')
def phase_calculate_linker_inputs(options, state, linker_inputs):
def phase_calculate_linker_inputs(options, state, linker_inputs, nodefaultlibc):
using_lld = not (options.oformat == OFormat.OBJECT and settings.LTO)
state.link_flags = filter_link_flags(state.link_flags, using_lld)

# Decide what we will link
process_libraries(state, linker_inputs)
process_libraries(state, linker_inputs, nodefaultlibc)

# Interleave the linker inputs with the linker flags while maintainging their
# relative order on the command line (both of these list are pairs, with the
Expand Down Expand Up @@ -3072,8 +3078,10 @@ def run(linker_inputs, options, state, newargs):

target, wasm_target = phase_linker_setup(options, state, newargs)

nodefaultlibc = '-nodefaultlibs' in newargs or '-nolibc' in newargs or '-nostdlib' in newargs

# Link object files using wasm-ld or llvm-link (for bitcode linking)
linker_arguments = phase_calculate_linker_inputs(options, state, linker_inputs)
linker_arguments = phase_calculate_linker_inputs(options, state, linker_inputs, nodefaultlibc)

# Embed and preload files
if len(options.preload_files) or len(options.embed_files):
Expand Down

0 comments on commit 3414463

Please sign in to comment.