Skip to content

Commit 1304b34

Browse files
authored
Cherry-picking of changed from emscripten-libs-18 onto llvmorg-19.1.4 (#13)
1 parent aadaa00 commit 1304b34

File tree

64 files changed

+717
-150
lines changed

Some content is hidden

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

64 files changed

+717
-150
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: 33 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+
#include <emscripten/heap.h>
27+
#include "emscripten_internal.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,23 @@ 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 = _emscripten_sanitizer_get_option(name); \
134+
parser.ParseString(options); \
135+
emscripten_builtin_free(options);
136+
137+
MAKE_OPTION_LOAD(asan_parser, "ASAN_OPTIONS");
138+
#if CAN_SANITIZE_LEAKS
139+
MAKE_OPTION_LOAD(lsan_parser, "LSAN_OPTIONS");
140+
#endif
141+
#if CAN_SANITIZE_UB
142+
MAKE_OPTION_LOAD(ubsan_parser, "UBSAN_OPTIONS");
143+
#endif
144+
#else
118145
// Override from command line.
119146
asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
120147
#if CAN_SANITIZE_LEAKS
@@ -123,12 +150,18 @@ void InitializeFlags() {
123150
#if CAN_SANITIZE_UB
124151
ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
125152
#endif
153+
#endif // SANITIZER_EMSCRIPTEN
126154

127155
InitializeCommonFlags();
128156

129157
// TODO(eugenis): dump all flags at verbosity>=2?
130158
if (Verbosity()) ReportUnrecognizedFlags();
131159

160+
#if SANITIZER_EMSCRIPTEN
161+
if (common_flags()->malloc_context_size <= 1)
162+
StackTrace::snapshot_stack = false;
163+
#endif // SANITIZER_EMSCRIPTEN
164+
132165
if (common_flags()->help) {
133166
// TODO(samsonov): print all of the flags (ASan, LSan, common).
134167
asan_parser.PrintFlagDescriptions();

compiler-rt/lib/asan/asan_globals.cpp

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

328+
#if !SANITIZER_EMSCRIPTEN
328329
// Apply __asan_register_globals to all globals found in the same loaded
329330
// executable or shared library as `flag'. The flag tracks whether globals have
330331
// already been registered or not for this image.
@@ -362,6 +363,7 @@ void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop) {
362363
__asan_unregister_globals(globals_start, globals_stop - globals_start);
363364
*flag = 0;
364365
}
366+
#endif
365367

366368
// Register an array of globals.
367369
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
@@ -27,10 +27,10 @@
2727
#include "sanitizer_common/sanitizer_internal_defs.h"
2828
#include "sanitizer_common/sanitizer_libc.h"
2929

30-
// There is no general interception at all on Fuchsia.
30+
// There is no general interception at all on Fuchsia or Emscripten.
3131
// Only the functions in asan_interceptors_memintrinsics.cpp are
3232
// really defined to replace libc functions.
33-
#if !SANITIZER_FUCHSIA
33+
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
3434

3535
# if SANITIZER_POSIX
3636
# include "sanitizer_common/sanitizer_posix.h"
@@ -883,4 +883,4 @@ void InitializeAsanInterceptors() {
883883

884884
} // namespace __asan
885885

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

compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ void *__asan_memmove(void *to, const void *from, uptr size) {
7171
ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
7272
}
7373

74-
#if SANITIZER_FUCHSIA
74+
#if SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN
7575

7676
// Fuchsia doesn't use sanitizer_common_interceptors.inc, but
7777
// the only things there it wants are these three. Just define them
@@ -81,7 +81,7 @@ extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]];
8181
extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]];
8282
extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];
8383

84-
#else // SANITIZER_FUCHSIA
84+
#else // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN
8585

8686
#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
8787
do { \
@@ -103,4 +103,4 @@ extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];
103103

104104
#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"
105105

106-
#endif // SANITIZER_FUCHSIA
106+
#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
@@ -272,6 +272,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
272272

273273
# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
274274
# include "asan_mapping_sparc64.h"
275+
# elif SANITIZER_EMSCRIPTEN
276+
# include "asan_mapping_emscripten.h"
275277
# else
276278
# define MEM_TO_SHADOW(mem) \
277279
(((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
@@ -174,6 +174,15 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) {
174174
if (!size)
175175
return 0;
176176
uptr end = beg + size;
177+
#if SANITIZER_EMSCRIPTEN
178+
// XXX Emscripten hack XXX
179+
// Null pointer handling, since Emscripten does not crash on null pointer,
180+
// ASan must catch null pointer dereference by itself.
181+
// Unfortunately, this function returns 0 to mean the region is not
182+
// poisoned, so we must return 1 instead if we receive a region
183+
// starting at 0.
184+
if (!beg) return 1;
185+
#endif
177186
if (!AddrIsInMem(beg))
178187
return beg;
179188
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: 8 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() {
@@ -324,13 +326,15 @@ static void asan_atexit() {
324326
}
325327

326328
static void InitializeHighMemEnd() {
329+
#if !SANITIZER_EMSCRIPTEN
327330
#if !ASAN_FIXED_MAPPING
328331
kHighMemEnd = GetMaxUserVirtualAddress();
329332
// Increase kHighMemEnd to make sure it's properly
330333
// aligned together with kHighMemBeg:
331334
kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;
332335
#endif // !ASAN_FIXED_MAPPING
333336
CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
337+
#endif // !SANITIZER_EMSCRIPTEN
334338
}
335339

336340
void PrintAddressSpaceLayout() {
@@ -449,12 +453,16 @@ static bool AsanInitInternal() {
449453

450454
ReplaceSystemMalloc();
451455

456+
#if !SANITIZER_EMSCRIPTEN
452457
DisableCoreDumperIfNecessary();
458+
#endif
453459

454460
InitializeShadowMemory();
455461

456462
AsanTSDInit(PlatformTSDDtor);
463+
#if !SANITIZER_EMSCRIPTEN
457464
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
465+
#endif
458466

459467
AllocatorOptions allocator_options;
460468
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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,10 @@ void AsanThread::Destroy() {
133133
if (AsanThread *thread = GetCurrentThread())
134134
CHECK_EQ(this, thread);
135135
malloc_storage().CommitBack();
136+
#if !SANITIZER_EMSCRIPTEN
136137
if (common_flags()->use_sigaltstack)
137138
UnsetAlternateSignalStack();
139+
#endif
138140
FlushToDeadThreadStats(&stats_);
139141
// We also clear the shadow on thread destruction because
140142
// some code may still be executing in later TSD destructors
@@ -288,8 +290,10 @@ void AsanThread::ThreadStart(tid_t os_id) {
288290
Init();
289291
asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);
290292

293+
#if !SANITIZER_EMSCRIPTEN
291294
if (common_flags()->use_sigaltstack)
292295
SetAlternateSignalStack();
296+
#endif
293297
}
294298

295299
AsanThread *CreateMainThread() {
@@ -563,6 +567,12 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) {
563567

564568
} // namespace __lsan
565569

570+
namespace __sanitizer {
571+
ThreadRegistry *GetThreadRegistryLocked() {
572+
return __lsan::GetAsanThreadRegistryLocked();
573+
}
574+
} // namespace __sanitizer
575+
566576
// ---------------------- Interface ---------------- {{{1
567577
using namespace __asan;
568578

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: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

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

@@ -157,6 +157,10 @@ const interpose_substitution substitution_##func_name[] \
157157
extern "C" ret_type func(__VA_ARGS__);
158158
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
159159
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
160+
#elif SANITIZER_EMSCRIPTEN
161+
# define WRAP(x) x
162+
# define INTERCEPTOR_ATTRIBUTE
163+
# define DECLARE_WRAPPER(ret_type, func, ...)
160164
#elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS
161165
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
162166
# if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
@@ -240,6 +244,13 @@ const interpose_substitution substitution_##func_name[] \
240244
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
241245
# define REAL(x) __unsanitized_##x
242246
# define DECLARE_REAL(ret_type, func, ...)
247+
#elif SANITIZER_EMSCRIPTEN
248+
// Sanitizer runtimes on Emscripten just define functions directly to override
249+
// the libc functions. If the real version is really needed, they can be defined
250+
// with the emscripten_builtin_ prefix.
251+
# define REAL(x) emscripten_builtin_##x
252+
# define DECLARE_REAL(ret_type, func, ...) \
253+
extern "C" ret_type REAL(func)(__VA_ARGS__);
243254
#elif !SANITIZER_APPLE
244255
# define PTR_TO_REAL(x) real_##x
245256
# define REAL(x) __interception::PTR_TO_REAL(x)
@@ -278,7 +289,7 @@ const interpose_substitution substitution_##func_name[] \
278289
// macros does its job. In exceptional cases you may need to call REAL(foo)
279290
// without defining INTERCEPTOR(..., foo, ...). For example, if you override
280291
// foo with an interceptor for other function.
281-
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA
292+
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
282293
# define DEFINE_REAL(ret_type, func, ...) \
283294
typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
284295
namespace __interception { \
@@ -344,9 +355,9 @@ const interpose_substitution substitution_##func_name[] \
344355
// INTERCEPT_FUNCTION macro, only its name.
345356
namespace __interception {
346357
#if defined(_WIN64)
347-
typedef unsigned long long uptr;
358+
typedef unsigned long long uptr; // NOLINT
348359
#else
349-
typedef unsigned long uptr;
360+
typedef unsigned long uptr; // NOLINT
350361
#endif // _WIN64
351362

352363
#if defined(__ELF__) && !SANITIZER_FUCHSIA
@@ -365,7 +376,7 @@ inline void DoesNotSupportStaticLinking() {}
365376
#define INCLUDED_FROM_INTERCEPTION_LIB
366377

367378
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
368-
SANITIZER_SOLARIS
379+
SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN
369380

370381
# include "interception_linux.h"
371382
# 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)