Skip to content

Cherry-picking of changed from emscripten-libs-18 onto llvmorg-19.1.4 #13

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

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions compiler-rt/lib/asan/asan_errors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,17 @@ ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
}
#if SANITIZER_EMSCRIPTEN
// If address is in the first page (64 KB), then it is likely that the
// access is a result of a null pointer dereference.
else if (addr < 65536) {
bug_descr = "null-pointer-dereference";
scariness.Scare(25, bug_descr);
} else if (AddrIsInShadow(addr)) {
bug_descr = "shadow-access";
scariness.Scare(25, bug_descr);
}
#endif
}
}

Expand Down
33 changes: 33 additions & 0 deletions compiler-rt/lib/asan/asan_flags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_platform.h"

#if SANITIZER_EMSCRIPTEN
#include <emscripten/heap.h>
#include "emscripten_internal.h"
#endif


namespace __asan {

Flags asan_flags_dont_use_directly; // use via flags().
Expand Down Expand Up @@ -54,7 +60,11 @@ void InitializeFlags() {
CommonFlags cf;
cf.CopyFrom(*common_flags());
cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
#if !SANITIZER_EMSCRIPTEN
// getenv on emscripten uses malloc, which we can't when using LSan.
// You can't run external symbolizer executables anyway.
cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
#endif
cf.malloc_context_size = kDefaultMallocContextSize;
cf.intercept_tls_get_addr = true;
cf.exitcode = 1;
Expand Down Expand Up @@ -115,6 +125,23 @@ void InitializeFlags() {
lsan_parser.ParseString(lsan_default_options);
#endif

#if SANITIZER_EMSCRIPTEN
char *options;
// Override from Emscripten Module.
// TODO: add EM_ASM_I64 and avoid using a double for a 64-bit pointer.
#define MAKE_OPTION_LOAD(parser, name) \
options = _emscripten_sanitizer_get_option(name); \
parser.ParseString(options); \
emscripten_builtin_free(options);

MAKE_OPTION_LOAD(asan_parser, "ASAN_OPTIONS");
#if CAN_SANITIZE_LEAKS
MAKE_OPTION_LOAD(lsan_parser, "LSAN_OPTIONS");
#endif
#if CAN_SANITIZE_UB
MAKE_OPTION_LOAD(ubsan_parser, "UBSAN_OPTIONS");
#endif
#else
// Override from command line.
asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
#if CAN_SANITIZE_LEAKS
Expand All @@ -123,12 +150,18 @@ void InitializeFlags() {
#if CAN_SANITIZE_UB
ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
#endif
#endif // SANITIZER_EMSCRIPTEN

InitializeCommonFlags();

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

#if SANITIZER_EMSCRIPTEN
if (common_flags()->malloc_context_size <= 1)
StackTrace::snapshot_stack = false;
#endif // SANITIZER_EMSCRIPTEN

if (common_flags()->help) {
// TODO(samsonov): print all of the flags (ASan, LSan, common).
asan_parser.PrintFlagDescriptions();
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_globals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g,
// ---------------------- Interface ---------------- {{{1
using namespace __asan;

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

// Register an array of globals.
void __asan_register_globals(__asan_global *globals, uptr n) {
Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_libc.h"

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

# if SANITIZER_POSIX
# include "sanitizer_common/sanitizer_posix.h"
Expand Down Expand Up @@ -883,4 +883,4 @@ void InitializeAsanInterceptors() {

} // namespace __asan

#endif // !SANITIZER_FUCHSIA
#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_EMSCRIPTEN
6 changes: 3 additions & 3 deletions compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void *__asan_memmove(void *to, const void *from, uptr size) {
ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
}

#if SANITIZER_FUCHSIA
#if SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN

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

#else // SANITIZER_FUCHSIA
#else // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN

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

#include "sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc"

#endif // SANITIZER_FUCHSIA
#endif // SANITIZER_FUCHSIA || SANITIZER_EMSCRIPTEN
2 changes: 1 addition & 1 deletion compiler-rt/lib/asan/asan_malloc_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
SANITIZER_NETBSD || SANITIZER_SOLARIS
SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN

# include "asan_allocator.h"
# include "asan_interceptors.h"
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/asan/asan_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.

# if defined(__sparc__) && SANITIZER_WORDSIZE == 64
# include "asan_mapping_sparc64.h"
# elif SANITIZER_EMSCRIPTEN
# include "asan_mapping_emscripten.h"
# else
# define MEM_TO_SHADOW(mem) \
(((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
Expand Down
9 changes: 9 additions & 0 deletions compiler-rt/lib/asan/asan_poisoning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,15 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) {
if (!size)
return 0;
uptr end = beg + size;
#if SANITIZER_EMSCRIPTEN
// XXX Emscripten hack XXX
// Null pointer handling, since Emscripten does not crash on null pointer,
// ASan must catch null pointer dereference by itself.
// Unfortunately, this function returns 0 to mean the region is not
// poisoned, so we must return 1 instead if we receive a region
// starting at 0.
if (!beg) return 1;
#endif
if (!AddrIsInMem(beg))
return beg;
if (!AddrIsInMem(end))
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_poisoning.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// probably provide higher-level interface for these operations.
// For now, just memset on Windows.
if (value || SANITIZER_WINDOWS == 1 ||
// Emscripten doesn't have a nice way to zero whole pages.
// The bulk memory proposal will allow memset to be optimized, but
// even then, we still must use memset.
SANITIZER_EMSCRIPTEN == 1 ||
shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler-rt/lib/asan/asan_posix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
}

bool PlatformUnpoisonStacks() {
#if SANITIZER_EMSCRIPTEN
return false;
#else
stack_t signal_stack;
CHECK_EQ(0, sigaltstack(nullptr, &signal_stack));
uptr sigalt_bottom = (uptr)signal_stack.ss_sp;
Expand All @@ -64,6 +67,7 @@ bool PlatformUnpoisonStacks() {
&tls_size);
UnpoisonStack(default_bottom, default_bottom + stack_size, "default");
return true;
#endif
}

// ---------------------- TSD ---------------- {{{1
Expand Down
8 changes: 8 additions & 0 deletions compiler-rt/lib/asan/asan_rtl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static void AsanDie() {

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

#if !SANITIZER_EMSCRIPTEN
if (flags()->unmap_shadow_on_exit) {
if (kMidMemBeg) {
UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
Expand All @@ -63,6 +64,7 @@ static void AsanDie() {
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
}
}
#endif
}

static void CheckUnwind() {
Expand Down Expand Up @@ -324,13 +326,15 @@ static void asan_atexit() {
}

static void InitializeHighMemEnd() {
#if !SANITIZER_EMSCRIPTEN
#if !ASAN_FIXED_MAPPING
kHighMemEnd = GetMaxUserVirtualAddress();
// Increase kHighMemEnd to make sure it's properly
// aligned together with kHighMemBeg:
kHighMemEnd |= (GetMmapGranularity() << ASAN_SHADOW_SCALE) - 1;
#endif // !ASAN_FIXED_MAPPING
CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
#endif // !SANITIZER_EMSCRIPTEN
}

void PrintAddressSpaceLayout() {
Expand Down Expand Up @@ -449,12 +453,16 @@ static bool AsanInitInternal() {

ReplaceSystemMalloc();

#if !SANITIZER_EMSCRIPTEN
DisableCoreDumperIfNecessary();
#endif

InitializeShadowMemory();

AsanTSDInit(PlatformTSDDtor);
#if !SANITIZER_EMSCRIPTEN
InstallDeadlySignalHandlers(AsanOnDeadlySignal);
#endif

AllocatorOptions allocator_options;
allocator_options.SetFrom(flags(), common_flags());
Expand Down
5 changes: 3 additions & 2 deletions compiler-rt/lib/asan/asan_shadow_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@

#include "sanitizer_common/sanitizer_platform.h"

// asan_fuchsia.cpp has their own InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA
// asan_fuchsia.cpp and asan_emscripten.cc have have their own
// InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN

# include "asan_internal.h"
# include "asan_mapping.h"
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/lib/asan/asan_thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ void AsanThread::Destroy() {
if (AsanThread *thread = GetCurrentThread())
CHECK_EQ(this, thread);
malloc_storage().CommitBack();
#if !SANITIZER_EMSCRIPTEN
if (common_flags()->use_sigaltstack)
UnsetAlternateSignalStack();
#endif
FlushToDeadThreadStats(&stats_);
// We also clear the shadow on thread destruction because
// some code may still be executing in later TSD destructors
Expand Down Expand Up @@ -288,8 +290,10 @@ void AsanThread::ThreadStart(tid_t os_id) {
Init();
asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);

#if !SANITIZER_EMSCRIPTEN
if (common_flags()->use_sigaltstack)
SetAlternateSignalStack();
#endif
}

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

} // namespace __lsan

namespace __sanitizer {
ThreadRegistry *GetThreadRegistryLocked() {
return __lsan::GetAsanThreadRegistryLocked();
}
} // namespace __sanitizer

// ---------------------- Interface ---------------- {{{1
using namespace __asan;

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/builtins/fp_compare_impl.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// functions. We need to ensure that the return value is sign-extended in the
// same way as GCC expects (since otherwise GCC-generated __builtin_isinf
// returns true for finite 128-bit floating-point numbers).
#ifdef __aarch64__
#if defined(__aarch64__) || defined(__wasm__)
// AArch64 GCC overrides libgcc_cmp_return to use int instead of long.
typedef int CMP_RESULT;
#elif __SIZEOF_POINTER__ == 8 && __SIZEOF_LONG__ == 4
Expand Down
21 changes: 16 additions & 5 deletions compiler-rt/lib/interception/interception.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \
!SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
!SANITIZER_SOLARIS
!SANITIZER_SOLARIS && !SANITIZER_EMSCRIPTEN
# error "Interception doesn't work on this operating system."
#endif

Expand Down Expand Up @@ -157,6 +157,10 @@ const interpose_substitution substitution_##func_name[] \
extern "C" ret_type func(__VA_ARGS__);
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
#elif SANITIZER_EMSCRIPTEN
# define WRAP(x) x
# define INTERCEPTOR_ATTRIBUTE
# define DECLARE_WRAPPER(ret_type, func, ...)
#elif !SANITIZER_FUCHSIA // LINUX, FREEBSD, NETBSD, SOLARIS
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
# if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
Expand Down Expand Up @@ -240,6 +244,13 @@ const interpose_substitution substitution_##func_name[] \
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
# define REAL(x) __unsanitized_##x
# define DECLARE_REAL(ret_type, func, ...)
#elif SANITIZER_EMSCRIPTEN
// Sanitizer runtimes on Emscripten just define functions directly to override
// the libc functions. If the real version is really needed, they can be defined
// with the emscripten_builtin_ prefix.
# define REAL(x) emscripten_builtin_##x
# define DECLARE_REAL(ret_type, func, ...) \
extern "C" ret_type REAL(func)(__VA_ARGS__);
#elif !SANITIZER_APPLE
# define PTR_TO_REAL(x) real_##x
# define REAL(x) __interception::PTR_TO_REAL(x)
Expand Down Expand Up @@ -278,7 +289,7 @@ const interpose_substitution substitution_##func_name[] \
// macros does its job. In exceptional cases you may need to call REAL(foo)
// without defining INTERCEPTOR(..., foo, ...). For example, if you override
// foo with an interceptor for other function.
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA
#if !SANITIZER_APPLE && !SANITIZER_FUCHSIA && !SANITIZER_EMSCRIPTEN
# define DEFINE_REAL(ret_type, func, ...) \
typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
namespace __interception { \
Expand Down Expand Up @@ -344,9 +355,9 @@ const interpose_substitution substitution_##func_name[] \
// INTERCEPT_FUNCTION macro, only its name.
namespace __interception {
#if defined(_WIN64)
typedef unsigned long long uptr;
typedef unsigned long long uptr; // NOLINT
#else
typedef unsigned long uptr;
typedef unsigned long uptr; // NOLINT
#endif // _WIN64

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

#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN

# include "interception_linux.h"
# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/interception/interception_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//

#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
SANITIZER_SOLARIS || SANITIZER_EMSCRIPTEN

#if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
# error interception_linux.h should be included from interception library only
Expand Down
Loading
Loading