1 //===-- asan_premap_shadow.cc ---------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // Reserve shadow memory with an ifunc resolver.
11 //===----------------------------------------------------------------------===//
13 #include "asan_mapping.h"
15 #if ASAN_PREMAP_SHADOW
17 #include "asan_premap_shadow.h"
18 #include "sanitizer_common/sanitizer_posix.h"
22 // The code in this file needs to run in an unrelocated binary. It may not
23 // access any external symbol, including its own non-hidden globals.
25 // Conservative upper limit.
26 uptr
PremapShadowSize() {
27 uptr granularity
= GetMmapGranularity();
28 return RoundUpTo(GetMaxVirtualAddress() >> SHADOW_SCALE
, granularity
);
31 // Returns an address aligned to 8 pages, such that one page on the left and
32 // PremapShadowSize() bytes on the right of it are mapped r/o.
34 uptr granularity
= GetMmapGranularity();
35 uptr alignment
= granularity
* 8;
36 uptr left_padding
= granularity
;
37 uptr shadow_size
= PremapShadowSize();
38 uptr map_size
= shadow_size
+ left_padding
+ alignment
;
40 uptr map_start
= (uptr
)MmapNoAccess(map_size
);
41 CHECK_NE(map_start
, ~(uptr
)0);
43 uptr shadow_start
= RoundUpTo(map_start
+ left_padding
, alignment
);
44 uptr shadow_end
= shadow_start
+ shadow_size
;
45 internal_munmap(reinterpret_cast<void *>(map_start
),
46 shadow_start
- left_padding
- map_start
);
47 internal_munmap(reinterpret_cast<void *>(shadow_end
),
48 map_start
+ map_size
- shadow_end
);
52 bool PremapShadowFailed() {
53 uptr shadow
= reinterpret_cast<uptr
>(&__asan_shadow
);
54 uptr resolver
= reinterpret_cast<uptr
>(&__asan_premap_shadow
);
55 // shadow == resolver is how Android KitKat and older handles ifunc.
56 // shadow == 0 just in case.
57 if (shadow
== 0 || shadow
== resolver
)
64 decltype(__asan_shadow
)* __asan_premap_shadow() {
65 // The resolver may be called multiple times. Map the shadow just once.
66 static uptr premapped_shadow
= 0;
67 if (!premapped_shadow
) premapped_shadow
= __asan::PremapShadow();
68 return reinterpret_cast<decltype(__asan_shadow
)*>(premapped_shadow
);
71 // __asan_shadow is a "function" that has the same address as the first byte of
72 // the shadow mapping.
73 INTERFACE_ATTRIBUTE
__attribute__((ifunc("__asan_premap_shadow"))) void
77 #endif // ASAN_PREMAP_SHADOW