1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "asan_impl.h"
6
7// In the ASan build, this file provides weak definitions for all the
8// same entry points that are defined by the ASan runtime library.
9// The definitions here are stubs that are used only during the
10// dynamic linker's startup phase before the ASan runtime shared
11// library has been loaded.  These are required to satisfy the
12// references in libc's own code.
13//
14// LLVM provides no documentation on the ABI between the compiler and
15// the runtime.  The set of function signatures here was culled from
16// the LLVM sources for the compiler instrumentation and the runtime
17// (see llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp and
18// compiler-rt/lib/asan/*).
19
20#if __has_feature(address_sanitizer)
21
22// This is referenced by generated code to decide whether to call
23// __asan_stack_malloc_* instead of doing normal stack allocation.
24// Never use stack malloc before the real runtime library is loaded.
25__WEAK const int __asan_option_detect_stack_use_after_return = 0;
26
27// This is the one set of things we define for real just as the
28// sanitizer runtime does.  Generated code calls these.  In practice,
29// almost certainly nothing in the the startup path needs them, but
30// defining them properly is barely more than defining trap stubs.
31#define ASAN_SET_SHADOW_XX(xx)                                          \
32    __WEAK void __asan_set_shadow_##xx(uintptr_t addr, uintptr_t size) { \
33        __unsanitized_memset((void*)addr, 0x##xx, size);                \
34    }
35
36ASAN_SET_SHADOW_XX(00)
37ASAN_SET_SHADOW_XX(f1)
38ASAN_SET_SHADOW_XX(f2)
39ASAN_SET_SHADOW_XX(f3)
40ASAN_SET_SHADOW_XX(f5)
41ASAN_SET_SHADOW_XX(f8)
42
43// Everything else is trap stubs.  They should never be called.
44
45#define TRAP_STUB(decl) __WEAK decl { __builtin_trap(); }
46
47// These are only called when a bug is found.  So unless there's
48// an actual bug in code that's on the dynamic linker startup path,
49// they'll never be called.
50
51// This is the same macro used in compiler-rt/lib/asan/asan_rtl.cc,
52// where it makes use of the is_write argument.  The list of invocations
53// of this macro below is taken verbatim from that file.
54#define ASAN_REPORT_ERROR(type, is_write, size)                         \
55    TRAP_STUB(void __asan_report_##type##size(uintptr_t addr))          \
56    TRAP_STUB(void __asan_report_exp_##type##size(uintptr_t addr,       \
57                                                  uint32_t exp))        \
58    TRAP_STUB(void __asan_report_##type##size##_noabort(uintptr_t addr))
59
60ASAN_REPORT_ERROR(load, false, 1)
61ASAN_REPORT_ERROR(load, false, 2)
62ASAN_REPORT_ERROR(load, false, 4)
63ASAN_REPORT_ERROR(load, false, 8)
64ASAN_REPORT_ERROR(load, false, 16)
65ASAN_REPORT_ERROR(store, true, 1)
66ASAN_REPORT_ERROR(store, true, 2)
67ASAN_REPORT_ERROR(store, true, 4)
68ASAN_REPORT_ERROR(store, true, 8)
69ASAN_REPORT_ERROR(store, true, 16)
70
71TRAP_STUB(void __asan_report_load_n(uintptr_t addr, size_t size))
72TRAP_STUB(void __asan_report_load_n_noabort(uintptr_t addr, size_t size))
73TRAP_STUB(void __asan_report_exp_load_n(uintptr_t addr, size_t size,
74                                        uint32_t exp))
75
76TRAP_STUB(void __asan_report_store_n(uintptr_t addr, size_t size))
77TRAP_STUB(void __asan_report_store_n_noabort(uintptr_t addr, size_t size))
78TRAP_STUB(void __asan_report_exp_store_n(uintptr_t addr, size_t size,
79                                         uint32_t exp))
80
81// These are sometimes called in normal operation.  But they're never
82// called by any of the code on the startup path, so we can get away
83// with making them trap stubs.
84
85TRAP_STUB(void __asan_handle_no_return(void))
86
87#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id)                \
88    TRAP_STUB(uintptr_t __asan_stack_malloc_##class_id(uintptr_t size)) \
89    TRAP_STUB(void __asan_stack_free_##class_id(uintptr_t ptr, size_t size))
90
91DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0)
92DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1)
93DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2)
94DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3)
95DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4)
96DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5)
97DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6)
98DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7)
99DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8)
100DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9)
101DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10)
102
103TRAP_STUB(void __asan_alloca_poison(uintptr_t addr, uintptr_t size))
104TRAP_STUB(void __asan_allocas_unpoison(uintptr_t top, uintptr_t bottom))
105
106// These are called to initialize the sanitizer runtime.  These will
107// be needed for libc's and the dynamic linker's own code, but they
108// won't be called until after the sanitizer runtime is loaded.  So
109// these trap stubs just satisfy the references in libc's own code
110// before other libraries are loaded, and ensure that they really
111// don't get called too early.
112
113TRAP_STUB(void __asan_init(void))
114TRAP_STUB(void __asan_version_mismatch_check_v8(void))
115
116TRAP_STUB(void __asan_register_globals(uintptr_t globals, size_t n))
117TRAP_STUB(void __asan_unregister_globals(uintptr_t globals, size_t n))
118TRAP_STUB(void __asan_register_elf_globals(uintptr_t flag,
119                                           uintptr_t start, uintptr_t stop))
120TRAP_STUB(void __asan_unregister_elf_globals(uintptr_t flag,
121                                             uintptr_t start, uintptr_t stop))
122
123
124#endif // __has_feature(address_sanitizer)
125