blob: de05556c3f497a7276acc6bc44de4b010da010f3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <lib/zircon-internal/unique-backtrace.h>
#include "asan_impl.h"
// In the ASan build, this file provides weak definitions for all the
// same entry points that are defined by the ASan runtime library.
// The definitions here are stubs that are used only during the
// dynamic linker's startup phase before the ASan runtime shared
// library has been loaded. These are required to satisfy the
// references in libc's own code.
// LLVM provides no documentation on the ABI between the compiler and
// the runtime. The set of function signatures here was culled from
// the LLVM sources for the compiler instrumentation and the runtime
// (see llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp and
// compiler-rt/lib/asan/*).
#if __has_feature(address_sanitizer)
// The non-fatal calls here might be made early in startup, before safe-stack
// and/or shadow-call-stack setup is done. None of these use any unsafe stack
// (they take no addresses), and they're all either leaves or could be tail
// calls so they shouldn't need shadow call stack either. But if not fully
// optimized, they might try to use them anyway. So they're all marked with
// __NO_SAFESTACK (which also disables shadow-call-stack).
// This is referenced by generated code to decide whether to call
// __asan_stack_malloc_* instead of doing normal stack allocation.
// Never use stack malloc before the real runtime library is loaded.
__EXPORT __WEAK const int __asan_option_detect_stack_use_after_return = 0;
// This is the one set of things we define for real just as the
// sanitizer runtime does. Generated code calls these. In practice,
// almost certainly nothing in the the startup path needs them, but
// defining them properly is barely more than defining trap stubs.
#define ASAN_SET_SHADOW_XX(xx) \
__EXPORT __WEAK __NO_SAFESTACK void __asan_set_shadow_##xx(uintptr_t addr, uintptr_t size) { \
__unsanitized_memset((void*)addr, 0x##xx, size); \
// Everything else is trap stubs. They should never be called.
#define TRAP_STUB(decl) \
// These are only called when a bug is found. So unless there's
// an actual bug in code that's on the dynamic linker startup path,
// they'll never be called.
// This is the same macro used in compiler-rt/lib/asan/,
// where it makes use of the is_write argument. The list of invocations
// of this macro below is taken verbatim from that file.
#define ASAN_REPORT_ERROR(type, is_write, size) \
TRAP_STUB(void __asan_report_##type##size(uintptr_t addr)) \
TRAP_STUB(void __asan_report_exp_##type##size(uintptr_t addr, uint32_t exp)) \
TRAP_STUB(void __asan_report_##type##size##_noabort(uintptr_t addr))
ASAN_REPORT_ERROR(load, false, 1)
ASAN_REPORT_ERROR(load, false, 2)
ASAN_REPORT_ERROR(load, false, 4)
ASAN_REPORT_ERROR(load, false, 8)
ASAN_REPORT_ERROR(load, false, 16)
ASAN_REPORT_ERROR(store, true, 1)
ASAN_REPORT_ERROR(store, true, 2)
ASAN_REPORT_ERROR(store, true, 4)
ASAN_REPORT_ERROR(store, true, 8)
ASAN_REPORT_ERROR(store, true, 16)
TRAP_STUB(void __asan_report_load_n(uintptr_t addr, size_t size))
TRAP_STUB(void __asan_report_load_n_noabort(uintptr_t addr, size_t size))
TRAP_STUB(void __asan_report_exp_load_n(uintptr_t addr, size_t size, uint32_t exp))
TRAP_STUB(void __asan_report_store_n(uintptr_t addr, size_t size))
TRAP_STUB(void __asan_report_store_n_noabort(uintptr_t addr, size_t size))
TRAP_STUB(void __asan_report_exp_store_n(uintptr_t addr, size_t size, uint32_t exp))
// These are sometimes called in normal operation. But they're never
// called by any of the code on the startup path, so we can get away
// with making them trap stubs.
TRAP_STUB(void __asan_handle_no_return(void))
TRAP_STUB(uintptr_t __asan_stack_malloc_##class_id(uintptr_t size)) \
TRAP_STUB(void __asan_stack_free_##class_id(uintptr_t ptr, size_t size))
TRAP_STUB(void __asan_alloca_poison(uintptr_t addr, uintptr_t size))
TRAP_STUB(void __asan_allocas_unpoison(uintptr_t top, uintptr_t bottom))
// These are called to initialize the sanitizer runtime. These will
// be needed for libc's and the dynamic linker's own code, but they
// won't be called until after the sanitizer runtime is loaded. So
// these trap stubs just satisfy the references in libc's own code
// before other libraries are loaded, and ensure that they really
// don't get called too early.
TRAP_STUB(void __asan_init(void))
TRAP_STUB(void __asan_version_mismatch_check_v8(void))
TRAP_STUB(void __asan_register_globals(uintptr_t globals, size_t n))
TRAP_STUB(void __asan_unregister_globals(uintptr_t globals, size_t n))
TRAP_STUB(void __asan_register_elf_globals(uintptr_t flag, uintptr_t start, uintptr_t stop))
TRAP_STUB(void __asan_unregister_elf_globals(uintptr_t flag, uintptr_t start, uintptr_t stop))
#endif // __has_feature(address_sanitizer)