blob: 1b65256856ccba06019930974d83f0b68875967e [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 "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)
// 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.
__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) \
__WEAK void __asan_set_shadow_##xx(uintptr_t addr, uintptr_t size) { \
__unsanitized_memset((void*)addr, 0x##xx, size); \
}
ASAN_SET_SHADOW_XX(00)
ASAN_SET_SHADOW_XX(f1)
ASAN_SET_SHADOW_XX(f2)
ASAN_SET_SHADOW_XX(f3)
ASAN_SET_SHADOW_XX(f5)
ASAN_SET_SHADOW_XX(f8)
// Everything else is trap stubs. They should never be called.
#define TRAP_STUB(decl) __WEAK decl { __builtin_trap(); }
// 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/asan_rtl.cc,
// 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))
#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id) \
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))
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9)
DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10)
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)