summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler-rt/lib/sanitizer_common/sanitizer_posix.cc')
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_posix.cc23
1 files changed, 15 insertions, 8 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc
index 9916f4d3853..3a6b711dbd2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cc
@@ -146,22 +146,29 @@ void UnmapOrDie(void *addr, uptr size) {
}
// We want to map a chunk of address space aligned to 'alignment'.
-// We do it by maping a bit more and then unmaping redundant pieces.
+// We do it by mapping a bit more and then unmapping redundant pieces.
// We probably can do it with fewer syscalls in some OS-dependent way.
-void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type) {
+void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type,
+ uptr* padding_chunk) {
CHECK(IsPowerOfTwo(size));
CHECK(IsPowerOfTwo(alignment));
uptr map_size = size + alignment;
uptr map_res = (uptr)MmapOrDie(map_size, mem_type);
uptr map_end = map_res + map_size;
+ bool is_aligned = IsAligned(map_res, alignment);
+ if (is_aligned && padding_chunk && size == alignment) {
+ *padding_chunk = map_res + size;
+ return (void *)map_res;
+ }
+ if (padding_chunk)
+ *padding_chunk = 0;
uptr res = map_res;
- if (res & (alignment - 1)) // Not aligned.
- res = (map_res + alignment) & ~(alignment - 1);
- uptr end = res + size;
- if (res != map_res)
+ if (!is_aligned) {
+ res = (map_res + alignment - 1) & ~(alignment - 1);
UnmapOrDie((void*)map_res, res - map_res);
- if (end != map_end)
- UnmapOrDie((void*)end, map_end - end);
+ }
+ uptr end = res + size;
+ UnmapOrDie((void*)end, map_end - end);
return (void*)res;
}
OpenPOWER on IntegriCloud