Skip to content

[WIP] Merge musl-1.2.1 into #13006 #13007

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 22 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ff72c7d
Reapply emscripten patches
kleisauke Dec 6, 2020
c1d360c
Reapply emscripten libc include changes
kleisauke Dec 7, 2020
38830f0
Reapply arch/emscripten/bits changes
kleisauke Dec 7, 2020
e6348af
Update alltypes.h{,in} to have emscripten-specific changes
kleisauke Dec 7, 2020
fb0845e
Deduplicate arch/emscripten/bits directory
kleisauke Dec 11, 2020
bbb3982
Deduplicate arch/emscripten/bits/alltypes.h{,in} with include/libc/al…
kleisauke Dec 12, 2020
20c8376
Cherry-pick remainder of PR 15739
kleisauke Nov 19, 2021
a9275b7
Minor cleanups
kleisauke Nov 19, 2021
7b45945
Ignore unsupported syscalls
kleisauke May 14, 2021
c7e20f8
PI mutexes are unsupported
kleisauke May 14, 2021
6d149ef
Robust mutexes are unsupported
kleisauke May 14, 2021
1e3deda
get/setsockopt: remove fallback
kleisauke May 14, 2021
5b39cb0
Improve test_nl_types
kleisauke May 14, 2021
5e038c0
Ignore default timezone from filesystem
kleisauke Dec 14, 2020
4f03f15
Move pthread_barrier_wait logic to __futexwait. NFC
kleisauke Feb 18, 2021
51d5e47
Simplify thread clean / exit / terminate logic. NFC
kleisauke Feb 27, 2021
6205af7
Disable warnings on thread pool exhaustion in posixtest
kleisauke Jun 30, 2021
99e1b14
Minor improvements
kleisauke Jun 30, 2021
75ad624
Remove early return from `exitRuntime()`. NFC
kleisauke Jul 23, 2021
5aed4a5
Improve sanitizer detection
kleisauke Aug 11, 2021
10bd41b
Rebaseline codesize tests. NFC
kleisauke Jun 30, 2021
f26f6d5
Use correct types for syscalls
kleisauke Jul 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/library_noderawfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ addToLibrary({
// generic function for all node creation
cwd() { return process.cwd(); },
chdir(...args) { process.chdir(...args); },
mknod(path, mode) {
mknod(path, mode/*, dev */) {
if (FS.isDir(path)) {
fs.mkdirSync(path, mode);
} else {
Expand Down
50 changes: 16 additions & 34 deletions src/library_pthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ globalThis.MAX_PTR = (2 ** 32) - 1
var LibraryPThread = {
$PThread__postset: 'PThread.init();',
$PThread__deps: ['_emscripten_thread_init',
'$killThread',
'$terminateWorker',
'$cancelThread', '$cleanupThread', '$zeroMemory',
#if MAIN_MODULE
'$markAsFinished',
Expand Down Expand Up @@ -170,7 +170,6 @@ var LibraryPThread = {
setExitStatus: (status) => EXITSTATUS = status,
#endif

terminateAllThreads__deps: ['$terminateWorker'],
terminateAllThreads: () => {
#if ASSERTIONS
assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! terminateAllThreads() can only ever be called from main application thread!');
Expand All @@ -194,7 +193,7 @@ var LibraryPThread = {
PThread.runningWorkers = [];
PThread.pthreads = [];
},
returnWorkerToPool: (worker) => {
returnWorkerToPool: (worker, terminate) => {
// We don't want to run main thread queued calls here, since we are doing
// some operations that leave the worker queue in an invalid state until
// we are completely done (it would be bad if free() ends up calling a
Expand All @@ -203,9 +202,13 @@ var LibraryPThread = {
// we are all done.
var pthread_ptr = worker.pthread_ptr;
delete PThread.pthreads[pthread_ptr];
// Note: worker is intentionally not terminated so the pool can
// dynamically grow.
PThread.unusedWorkers.push(worker);
if (terminate) {
worker.terminate();
} else {
// No termination needed? Return it to the worker pool as an
// unused worker so the pool can dynamically grow.
PThread.unusedWorkers.push(worker);
}
PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1);
// Not a running Worker anymore
// Detach the worker from the pthread object, and return it to the
Expand Down Expand Up @@ -272,13 +275,11 @@ var LibraryPThread = {
} else if (cmd === 'spawnThread') {
spawnThread(d);
} else if (cmd === 'cleanupThread') {
cleanupThread(d['thread']);
cleanupThread(d['thread'], d['terminate']);
#if MAIN_MODULE
} else if (cmd === 'markAsFinished') {
markAsFinished(d['thread']);
#endif
} else if (cmd === 'killThread') {
killThread(d['thread']);
} else if (cmd === 'cancelThread') {
cancelThread(d['thread']);
} else if (cmd === 'loaded') {
Expand Down Expand Up @@ -533,25 +534,6 @@ var LibraryPThread = {
};
},

$killThread__deps: ['_emscripten_thread_free_data', '$terminateWorker'],
$killThread: (pthread_ptr) => {
#if PTHREADS_DEBUG
dbg(`killThread ${ptrToString(pthread_ptr)}`);
#endif
#if ASSERTIONS
assert(!ENVIRONMENT_IS_PTHREAD, 'Internal Error! killThread() can only ever be called from main application thread!');
assert(pthread_ptr, 'Internal Error! Null pthread_ptr in killThread!');
#endif
var worker = PThread.pthreads[pthread_ptr];
delete PThread.pthreads[pthread_ptr];
terminateWorker(worker);
__emscripten_thread_free_data(pthread_ptr);
// The worker was completely nuked (not just the pthread execution it was hosting), so remove it from running workers
// but don't put it back to the pool.
PThread.runningWorkers.splice(PThread.runningWorkers.indexOf(worker), 1); // Not a running Worker anymore.
worker.pthread_ptr = 0;
},

_emscripten_thread_cleanup: (thread) => {
// Called when a thread needs to be cleaned up so it can be reused.
// A thread is considered reusable when it either returns from its
Expand All @@ -561,8 +543,8 @@ var LibraryPThread = {
#if PTHREADS_DEBUG
dbg(`_emscripten_thread_cleanup: ${ptrToString(thread)}`)
#endif
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread);
else postMessage({ 'cmd': 'cleanupThread', 'thread': thread });
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread, false);
else postMessage({ 'cmd': 'cleanupThread', 'thread': thread, 'terminate': false });
},

_emscripten_thread_set_strongref: (thread) => {
Expand All @@ -578,7 +560,7 @@ var LibraryPThread = {
#endif
},

$cleanupThread: (pthread_ptr) => {
$cleanupThread: (pthread_ptr, terminate) => {
#if PTHREADS_DEBUG
dbg(`cleanupThread: ${ptrToString(pthread_ptr)}`)
#endif
Expand All @@ -596,7 +578,7 @@ var LibraryPThread = {
#if ASSERTIONS
assert(worker);
#endif
PThread.returnWorkerToPool(worker);
PThread.returnWorkerToPool(worker, terminate);
},

#if MAIN_MODULE
Expand Down Expand Up @@ -923,8 +905,8 @@ var LibraryPThread = {
if (!ENVIRONMENT_IS_PTHREAD) cancelThread(thread);
else postMessage({ 'cmd': 'cancelThread', 'thread': thread });
} else {
if (!ENVIRONMENT_IS_PTHREAD) killThread(thread);
else postMessage({ 'cmd': 'killThread', 'thread': thread });
if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread, true);
else postMessage({ 'cmd': 'cleanupThread', 'thread': thread, 'terminate': true });
}
return 0;
},
Expand Down
16 changes: 8 additions & 8 deletions src/library_syscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ var SyscallsLibrary = {
doStat(func, path, buf) {
var stat = func(path);
{{{ makeSetValue('buf', C_STRUCTS.stat.st_dev, 'stat.dev', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_mode, 'stat.mode', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_nlink, 'stat.nlink', SIZE_TYPE) }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_uid, 'stat.uid', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_gid, 'stat.gid', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_rdev, 'stat.rdev', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_size, 'stat.size', 'i64') }}};
{{{ makeSetValue('buf', C_STRUCTS.stat.st_blksize, '4096', 'i32') }}};
Expand Down Expand Up @@ -808,16 +808,16 @@ var SyscallsLibrary = {
#endif
// NOTE: None of the constants here are true. We're just returning safe and
// sane values.
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_bsize, '4096', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_frsize, '4096', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_bsize, '4096', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_frsize, '4096', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_blocks, '1000000', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_bfree, '500000', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_bavail, '500000', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_files, 'FS.nextInode', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_ffree, '1000000', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_fsid, '42', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_flags, '2', 'i32') }}}; // ST_NOSUID
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_namelen, '255', 'i32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_fsid, '42', 'u32') }}};
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_flags, '2', 'u32') }}}; // ST_NOSUID
{{{ makeSetValue('buf', C_STRUCTS.statfs.f_namelen, '255', 'u32') }}};
return 0;
},
__syscall_fstatfs64__deps: ['__syscall_statfs64'],
Expand Down
8 changes: 4 additions & 4 deletions src/library_wasi.js
Original file line number Diff line number Diff line change
Expand Up @@ -508,13 +508,13 @@ var WasiLibrary = {
var type = stream.tty ? {{{ cDefs.__WASI_FILETYPE_CHARACTER_DEVICE }}} :
FS.isDir(stream.mode) ? {{{ cDefs.__WASI_FILETYPE_DIRECTORY }}} :
FS.isLink(stream.mode) ? {{{ cDefs.__WASI_FILETYPE_SYMBOLIC_LINK }}} :
{{{ cDefs.__WASI_FILETYPE_REGULAR_FILE }}};
FS.isFile(stream.mode) ? {{{ cDefs.__WASI_FILETYPE_REGULAR_FILE }}} :
-1;
if (type === -1) return -{{{ cDefs.EBADF }}};
#else
// Hack to support printf in SYSCALLS_REQUIRE_FILESYSTEM=0. We support at
// least stdin, stdout, stderr in a simple way.
#if ASSERTIONS
assert(fd == 0 || fd == 1 || fd == 2);
#endif
if (fd < 0 || fd > 2) return -{{{ cDefs.EBADF }}};
var type = {{{ cDefs.__WASI_FILETYPE_CHARACTER_DEVICE }}};
if (fd == 0) {
rightsBase = {{{ cDefs.__WASI_RIGHTS_FD_READ }}};
Expand Down
12 changes: 6 additions & 6 deletions src/library_wasmfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,15 @@ FS.init();
statBufToObject(statBuf) {
// i53/u53 are enough for times and ino in practice.
return {
dev: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_dev, "u32") }}},
mode: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_mode, "u32") }}},
nlink: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_nlink, "u32") }}},
dev: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_dev, "i32") }}},
mode: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_mode, "i32") }}},
nlink: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_nlink, SIZE_TYPE) }}},
uid: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_uid, "u32") }}},
gid: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_gid, "u32") }}},
rdev: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_rdev, "u32") }}},
rdev: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_rdev, "i32") }}},
size: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_size, "i53") }}},
blksize: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blksize, "u32") }}},
blocks: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blocks, "u32") }}},
blksize: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blksize, "i32") }}},
blocks: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_blocks, "i32") }}},
atime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_atim.tv_sec, "i53") }}},
mtime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_mtim.tv_sec, "i53") }}},
ctime: {{{ makeGetValue('statBuf', C_STRUCTS.stat.st_ctim.tv_sec, "i53") }}},
Expand Down
3 changes: 0 additions & 3 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,6 @@ function exitRuntime() {
#if STACK_OVERFLOW_CHECK
checkStackCookie();
#endif
#if PTHREADS
if (ENVIRONMENT_IS_PTHREAD) return; // PThreads reuse the runtime from the main thread.
#endif
#if !STANDALONE_WASM
___funcs_on_exit(); // Native atexit() functions
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/struct_info_internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"_a_transferredcanvases"
],
"thread_profiler_block": [
"threadStatus",
"timeSpentInStatus",
"name"
"threadStatus",
"timeSpentInStatus",
"name"
]
},
"defines": [
Expand Down
4 changes: 2 additions & 2 deletions system/include/emscripten/bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#include <emscripten/val.h>
#include <emscripten/wire.h>

#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
#if defined(HAS_LSAN) || __has_feature(address_sanitizer)
#include <sanitizer/lsan_interface.h>
#endif

Expand Down Expand Up @@ -778,7 +778,7 @@ template<typename T>
inline T* getContext(const T& t) {
// not a leak because this is called once per binding
auto* ret = new T(t);
#if __has_feature(leak_sanitizer) || __has_feature(address_sanitizer)
#if defined(HAS_LSAN) || __has_feature(address_sanitizer)
__lsan_ignore_object(ret);
#endif
return ret;
Expand Down
6 changes: 3 additions & 3 deletions system/lib/compiler-rt/lib/asan/asan_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ void InitializePlatformInterceptors();

} // namespace __asan

// There is no general interception at all on Fuchsia.
// There is no general interception at all on Fuchsia and Emscripten.
// Only the functions in asan_interceptors_memintrinsics.h are
// really defined to replace libc functions.
#if !SANITIZER_FUCHSIA
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

// Use macro to describe if specific function should be
// intercepted on a given platform.
Expand Down Expand Up @@ -162,6 +162,6 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
(void) ctx;
#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)

#endif // !SANITIZER_FUCHSIA
#endif // !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

#endif // ASAN_INTERCEPTORS_H
4 changes: 3 additions & 1 deletion system/lib/compiler-rt/lib/lsan/lsan_common_emscripten.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,12 @@ void LockStuffAndStopTheWorld(StopTheWorldCallback callback,
// Finally, we can only obtain the stack pointer for the current thread,
// so we scan the full stack for other threads.
static void ProcessThreadsCallback(ThreadContextBase *tctx, void *arg) {
tid_t os_id = tctx->os_id;
LOG_THREADS("Processing thread %llu\n", os_id);
if (tctx->status != ThreadStatusRunning)
return;

Frontier *frontier = reinterpret_cast<Frontier *>(arg);
tid_t os_id = tctx->os_id;

uptr stack_begin, stack_end, tls_begin, tls_end, cache_begin, cache_end;
DTLS *dtls;
Expand Down Expand Up @@ -154,6 +155,7 @@ static void ProcessThreadsCallback(ThreadContextBase *tctx, void *arg) {
}

ScanRangeForPointers(stack_begin, stack_end, frontier, "STACK", kReachable);
//ForEachExtraStackRange(os_id, ForEachExtraStackRangeCb, frontier);
}

if (flags()->use_tls && tls_begin) {
Expand Down
13 changes: 5 additions & 8 deletions system/lib/compiler-rt/lib/lsan/lsan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,9 +561,8 @@ INTERCEPTOR(void, _exit, int status) {
namespace __lsan {

void InitializeInterceptors() {
// Fuchsia doesn't use interceptors that require any setup.
#if !SANITIZER_FUCHSIA
#if !SANITIZER_EMSCRIPTEN
// Fuchsia and Emscripten doesn't use interceptors that require any setup.
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
InitializeSignalInterceptors();

INTERCEPT_FUNCTION(malloc);
Expand Down Expand Up @@ -596,17 +595,15 @@ void InitializeInterceptors() {
LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK;

LSAN_MAYBE_INTERCEPT_STRERROR;
#endif // !SANITIZER_EMSCRIPTEN
#endif // !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD
#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD && !SANITIZER_FUCHSIA
if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
Report("LeakSanitizer: failed to create thread key.\n");
Die();
}
#endif

#endif // !SANITIZER_FUCHSIA
}

} // namespace __lsan
#endif // SANITIZER_EMSCRIPTEN
#endif // SANITIZER_POSIX
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ extern struct ps_strings *__ps_strings;
# endif

# if SANITIZER_EMSCRIPTEN
// XXX Emscripten this must be defined before including the internal syscall.h header from musl
# define weak __attribute__(__weak__)
# define hidden __attribute__((__visibility__("hidden")))
# include <syscall.h>
Expand Down Expand Up @@ -605,7 +606,7 @@ tid_t GetTid() {
# elif SANITIZER_SOLARIS
return thr_self();
# elif SANITIZER_EMSCRIPTEN
return (tid_t)pthread_self();
return gettid();
# else
return internal_syscall(SYSCALL(gettid));
# endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
#define SANITIZER_INTERCEPT_SENDMMSG SI_LINUX
#define SANITIZER_INTERCEPT_SYSMSG SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_GETPEERNAME SI_POSIX
#define SANITIZER_INTERCEPT_IOCTL SI_POSIX && !SI_EMSCRIPTEN
#define SANITIZER_INTERCEPT_IOCTL SI_POSIX_NOT_EMSCRIPTEN
#define SANITIZER_INTERCEPT_INET_ATON SI_POSIX
#define SANITIZER_INTERCEPT_SYSINFO SI_LINUX
#define SANITIZER_INTERCEPT_READDIR SI_POSIX
Expand Down
3 changes: 1 addition & 2 deletions system/lib/libc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ and use a script (`system/lib/update_musl.py`) to pull in updates.

Some changes have been made to the version that was taken from upstream, including:

* Emscripten-specific changes (from before this readme existed). These should be marked with `XXX EMSCRIPTEN` in the source, or ifdefed with `#if __EMSCRIPTEN__`. They are mostly in pthreads code and hopefully temporary.
* Backporting an operator-precedence warning fix from 6e76e1540fc58a418494bf5eb832b556f9c5763e in the upstream version.
* Emscripten-specific changes (from before this readme existed). These should be marked with `XXX EMSCRIPTEN` in the source, or ifdefed with `#ifdef __EMSCRIPTEN__`. They are mostly in pthreads code and hopefully temporary.
* Switch to using the wasi `fd_write` syscall instead of `writev`.
* Simplify stdout stream handling: do not support seeking, terminal handling, etc., as it just increases code size and Emscripten doesn't have those features anyhow.
* Setting `_POSIX_REALTIME_SIGNALS` and `_POSIX_SPAWN` macros to -1, to exclude unsupported functions.
Expand Down
Loading
Loading