Skip to content

Commit 929cfaa

Browse files
committed
Rebase of changed from emscripten-libs-15.0.0 onto llvmorg-16.0.4
1 parent ae42196 commit 929cfaa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+706
-160
lines changed

compiler-rt/lib/asan/asan_errors.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,17 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
500500
scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
501501
if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
502502
}
503+
#if SANITIZER_EMSCRIPTEN
504+
// If address is in the first page (64 KB), then it is likely that the
505+
// access is a result of a null pointer dereference.
506+
else if (addr < 65536) {
507+
bug_descr = "null-pointer-dereference";
508+
scariness.Scare(25, bug_descr);
509+
} else if (AddrIsInShadow(addr)) {
510+
bug_descr = "shadow-access";
511+
scariness.Scare(25, bug_descr);
512+
}
513+
#endif
503514
}
504515
}
505516

compiler-rt/lib/asan/asan_flags.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
#include "ubsan/ubsan_flags.h"
2323
#include "ubsan/ubsan_platform.h"
2424

25+
#if SANITIZER_EMSCRIPTEN
26+
extern "C" void emscripten_builtin_free(void *);
27+
#include <emscripten/em_asm.h>
28+
#endif
29+
30+
2531
namespace __asan {
2632

2733
Flags asan_flags_dont_use_directly; // use via flags().
@@ -54,7 +60,11 @@ void InitializeFlags() {
5460
CommonFlags cf;
5561
cf.CopyFrom(*common_flags());
5662
cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
63+
#if !SANITIZER_EMSCRIPTEN
64+
// getenv on emscripten uses malloc, which we can't when using LSan.
65+
// You can't run external symbolizer executables anyway.
5766
cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
67+
#endif
5868
cf.malloc_context_size = kDefaultMallocContextSize;
5969
cf.intercept_tls_get_addr = true;
6070
cf.exitcode = 1;
@@ -115,6 +125,27 @@ void InitializeFlags() {
115125
lsan_parser.ParseString(lsan_default_options);
116126
#endif
117127

128+
#if SANITIZER_EMSCRIPTEN
129+
char *options;
130+
// Override from Emscripten Module.
131+
// TODO: add EM_ASM_I64 and avoid using a double for a 64-bit pointer.
132+
#define MAKE_OPTION_LOAD(parser, name) \
133+
options = (char*)(long)EM_ASM_DOUBLE({ \
134+
return withBuiltinMalloc(function () { \
135+
return stringToNewUTF8(Module[name] || ""); \
136+
}); \
137+
}); \
138+
parser.ParseString(options); \
139+
emscripten_builtin_free(options);
140+
141+
MAKE_OPTION_LOAD(asan_parser, 'ASAN_OPTIONS');
142+
#if CAN_SANITIZE_LEAKS
143+
MAKE_OPTION_LOAD(lsan_parser, 'LSAN_OPTIONS');
144+
#endif
145+
#if CAN_SANITIZE_UB
146+
MAKE_OPTION_LOAD(ubsan_parser, 'UBSAN_OPTIONS');
147+
#endif
148+
#else
118149
// Override from command line.
119150
asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
120151
#if CAN_SANITIZE_LEAKS
@@ -123,12 +154,18 @@ void InitializeFlags() {
123154
#if CAN_SANITIZE_UB
124155
ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
125156
#endif
157+
#endif // SANITIZER_EMSCRIPTEN
126158

127159
InitializeCommonFlags();
128160

129161
// TODO(eugenis): dump all flags at verbosity>=2?
130162
if (Verbosity()) ReportUnrecognizedFlags();
131163

164+
#if SANITIZER_EMSCRIPTEN
165+
if (common_flags()->malloc_context_size <= 1)
166+
StackTrace::snapshot_stack = false;
167+
#endif // SANITIZER_EMSCRIPTEN
168+
132169
if (common_flags()->help) {
133170
// TODO(samsonov): print all of the flags (ASan, LSan, common).
134171
asan_parser.PrintFlagDescriptions();

compiler-rt/lib/asan/asan_globals.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) {
312312
// ---------------------- Interface ---------------- {{{1
313313
using namespace __asan;
314314

315+
#if !SANITIZER_EMSCRIPTEN
315316
// Apply __asan_register_globals to all globals found in the same loaded
316317
// executable or shared library as `flag'. The flag tracks whether globals have
317318
// already been registered or not for this image.
@@ -349,6 +350,7 @@ void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop) {
349350
__asan_unregister_globals(globals_start, globals_stop - globals_start);
350351
*flag = 0;
351352
}
353+
#endif
352354

353355
// Register an array of globals.
354356
void __asan_register_globals(__asan_global *globals, uptr n) {

compiler-rt/lib/asan/asan_interceptors.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
#include "lsan/lsan_common.h"
2424
#include "sanitizer_common/sanitizer_libc.h"
2525

26-
// There is no general interception at all on Fuchsia.
26+
// There is no general interception at all on Fuchsia or Emscripten.
2727
// Only the functions in asan_interceptors_memintrinsics.cpp are
2828
// really defined to replace libc functions.
29-
#if !SANITIZER_FUCHSIA
29+
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
3030

3131
# if SANITIZER_POSIX
3232
# include "sanitizer_common/sanitizer_posix.h"
@@ -744,4 +744,4 @@ void InitializeAsanInterceptors() {
744744

745745
} // namespace __asan
746746

747-
#endif // !SANITIZER_FUCHSIA
747+
#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_EMSCRIPTEN

compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void *__asan_memmove(void *to, const void *from, uptr size) {
3030
ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
3131
}
3232

33-
#if SANITIZER_FUCHSIA
33+
#if SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN
3434

3535
// Fuchsia doesn't use sanitizer_common_interceptors.inc, but
3636
// the only things there it wants are these three. Just define them
@@ -40,4 +40,4 @@ extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]];
4040
extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]];
4141
extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];
4242

43-
#endif // SANITIZER_FUCHSIA
43+
#endif // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN

compiler-rt/lib/asan/asan_malloc_linux.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "sanitizer_common/sanitizer_platform.h"
1717
#if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
18-
SANITIZER_NETBSD || SANITIZER_SOLARIS
18+
SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN
1919

2020
# include "asan_allocator.h"
2121
# include "asan_interceptors.h"

compiler-rt/lib/asan/asan_mapping.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
269269

270270
# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
271271
# include "asan_mapping_sparc64.h"
272+
# elif SANITIZER_EMSCRIPTEN
273+
# include "asan_mapping_emscripten.h"
272274
# else
273275
# define MEM_TO_SHADOW(mem) \
274276
(((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))

compiler-rt/lib/asan/asan_poisoning.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) {
178178
if (!size)
179179
return 0;
180180
uptr end = beg + size;
181+
#if SANITIZER_EMSCRIPTEN
182+
// XXX Emscripten hack XXX
183+
// Null pointer handling, since Emscripten does not crash on null pointer,
184+
// ASan must catch null pointer dereference by itself.
185+
// Unfortunately, this function returns 0 to mean the region is not
186+
// poisoned, so we must return 1 instead if we receive a region
187+
// starting at 0.
188+
if (!beg) return 1;
189+
#endif
181190
if (!AddrIsInMem(beg))
182191
return beg;
183192
if (!AddrIsInMem(end))

compiler-rt/lib/asan/asan_poisoning.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
5151
// probably provide higher-level interface for these operations.
5252
// For now, just memset on Windows.
5353
if (value || SANITIZER_WINDOWS == 1 ||
54+
// Emscripten doesn't have a nice way to zero whole pages.
55+
// The bulk memory proposal will allow memset to be optimized, but
56+
// even then, we still must use memset.
57+
SANITIZER_EMSCRIPTEN == 1 ||
5458
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
5559
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
5660
} else {

compiler-rt/lib/asan/asan_posix.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
4141
}
4242

4343
bool PlatformUnpoisonStacks() {
44+
#if SANITIZER_EMSCRIPTEN
45+
return false;
46+
#else
4447
stack_t signal_stack;
4548
CHECK_EQ(0, sigaltstack(nullptr, &signal_stack));
4649
uptr sigalt_bottom = (uptr)signal_stack.ss_sp;
@@ -64,6 +67,7 @@ bool PlatformUnpoisonStacks() {
6467
&tls_size);
6568
UnpoisonStack(default_bottom, default_bottom + stack_size, "default");
6669
return true;
70+
#endif
6771
}
6872

6973
// ---------------------- TSD ---------------- {{{1

compiler-rt/lib/asan/asan_rtl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static void AsanDie() {
5454

5555
WaitForDebugger(flags()->sleep_before_dying, "before dying");
5656

57+
#if !SANITIZER_EMSCRIPTEN
5758
if (flags()->unmap_shadow_on_exit) {
5859
if (kMidMemBeg) {
5960
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
@@ -63,6 +64,7 @@ static void AsanDie() {
6364
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
6465
}
6566
}
67+
#endif
6668
}
6769

6870
static void CheckUnwind() {
@@ -315,13 +317,15 @@ static void asan_atexit() {
315317
}
316318

317319
static void InitializeHighMemEnd() {
320+
#if !SANITIZER_EMSCRIPTEN
318321
#if !ASAN_FIXED_MAPPING
319322
kHighMemEnd = GetMaxUserVirtualAddress();
320323
// Increase kHighMemEnd to make sure it's properly
321324
// aligned together with kHighMemBeg:
322325
kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;
323326
#endif // !ASAN_FIXED_MAPPING
324327
CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
328+
#endif // !SANITIZER_EMSCRIPTEN
325329
}
326330

327331
void PrintAddressSpaceLayout() {
@@ -448,7 +452,9 @@ static void AsanInitInternal() {
448452
InitializeShadowMemory();
449453

450454
AsanTSDInit(PlatformTSDDtor);
455+
#if !SANITIZER_EMSCRIPTEN
451456
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
457+
#endif
452458

453459
AllocatorOptions allocator_options;
454460
allocator_options.SetFrom(flags(), common_flags());

compiler-rt/lib/asan/asan_shadow_setup.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313

1414
#include "sanitizer_common/sanitizer_platform.h"
1515

16-
// asan_fuchsia.cpp has their own InitializeShadowMemory implementation.
17-
#if !SANITIZER_FUCHSIA
16+
// asan_fuchsia.cpp and asan_emscripten.cc have have their own
17+
// InitializeShadowMemory implementation.
18+
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
1819

1920
# include "asan_internal.h"
2021
# include "asan_mapping.h"

compiler-rt/lib/asan/asan_thread.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ void AsanThread::Destroy() {
105105
if (AsanThread *thread = GetCurrentThread())
106106
CHECK_EQ(this, thread);
107107
malloc_storage().CommitBack();
108+
#if !SANITIZER_EMSCRIPTEN
108109
if (common_flags()->use_sigaltstack)
109110
UnsetAlternateSignalStack();
111+
#endif
110112
FlushToDeadThreadStats(&stats_);
111113
// We also clear the shadow on thread destruction because
112114
// some code may still be executing in later TSD destructors
@@ -264,7 +266,9 @@ thread_return_t AsanThread::ThreadStart(tid_t os_id) {
264266
Init();
265267
asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);
266268

269+
#if !SANITIZER_EMSCRIPTEN
267270
if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
271+
#endif
268272

269273
if (!start_routine_) {
270274
// start_routine_ == 0 if we're on the main thread or on one of the

compiler-rt/lib/builtins/fp_compare_impl.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// functions. We need to ensure that the return value is sign-extended in the
1313
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
1414
// returns true for finite 128-bit floating-point numbers).
15-
#ifdef __aarch64__
15+
#if defined(__aarch64__) || defined(__wasm__)
1616
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
1717
typedef int CMP_RESULT;
1818
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4

compiler-rt/lib/interception/interception.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \
2020
!SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
21-
!SANITIZER_SOLARIS
21+
!SANITIZER_SOLARIS && !SANITIZER_EMSCRIPTEN
2222
# error "Interception doesn't work on this operating system."
2323
#endif
2424

@@ -130,6 +130,11 @@ const interpose_substitution substitution_##func_name[] \
130130
extern "C" ret_type func(__VA_ARGS__);
131131
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
132132
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
133+
#elif SANITIZER_EMSCRIPTEN
134+
# define WRAP(x) x
135+
# define WRAPPER_NAME(x) #x
136+
# define INTERCEPTOR_ATTRIBUTE
137+
# define DECLARE_WRAPPER(ret_type, func, ...)
133138
#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
134139
# define WRAP(x) __interceptor_ ## x
135140
# define WRAPPER_NAME(x) "__interceptor_" #x
@@ -157,6 +162,13 @@ const interpose_substitution substitution_##func_name[] \
157162
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
158163
# define REAL(x) __unsanitized_##x
159164
# define DECLARE_REAL(ret_type, func, ...)
165+
#elif SANITIZER_EMSCRIPTEN
166+
// Sanitizer runtimes on Emscripten just define functions directly to override
167+
// the libc functions. If the real version is really needed, they can be defined
168+
// with the emscripten_builtin_ prefix.
169+
# define REAL(x) emscripten_builtin_##x
170+
# define DECLARE_REAL(ret_type, func, ...) \
171+
extern "C" ret_type REAL(func)(__VA_ARGS__);
160172
#elif !SANITIZER_APPLE
161173
# define PTR_TO_REAL(x) real_##x
162174
# define REAL(x) __interception::PTR_TO_REAL(x)
@@ -193,7 +205,7 @@ const interpose_substitution substitution_##func_name[] \
193205
// macros does its job. In exceptional cases you may need to call REAL(foo)
194206
// without defining INTERCEPTOR(..., foo, ...). For example, if you override
195207
// foo with an interceptor for other function.
196-
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA
208+
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
197209
# define DEFINE_REAL(ret_type, func, ...) \
198210
typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
199211
namespace __interception { \
@@ -263,16 +275,16 @@ const interpose_substitution substitution_##func_name[] \
263275
// INTERCEPT_FUNCTION macro, only its name.
264276
namespace __interception {
265277
#if defined(_WIN64)
266-
typedef unsigned long long uptr;
278+
typedef unsigned long long uptr; // NOLINT
267279
#else
268-
typedef unsigned long uptr;
280+
typedef unsigned long uptr; // NOLINT
269281
#endif // _WIN64
270282
} // namespace __interception
271283

272284
#define INCLUDED_FROM_INTERCEPTION_LIB
273285

274286
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
275-
SANITIZER_SOLARIS
287+
SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN
276288

277289
# include "interception_linux.h"
278290
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)

compiler-rt/lib/interception/interception_linux.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
15-
SANITIZER_SOLARIS
15+
SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN
1616

1717
#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
1818
# error "interception_linux.h should be included from interception library only"

0 commit comments

Comments
 (0)