10b57cec5SDimitry Andric //===-- hwasan_malloc_bisect.h ----------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is a part of HWAddressSanitizer.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_hash.h"
140b57cec5SDimitry Andric #include "hwasan.h"
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric namespace __hwasan {
170b57cec5SDimitry Andric
malloc_hash(StackTrace * stack,uptr orig_size)180b57cec5SDimitry Andric static u32 malloc_hash(StackTrace *stack, uptr orig_size) {
190b57cec5SDimitry Andric uptr len = Min(stack->size, (unsigned)7);
200b57cec5SDimitry Andric MurMur2HashBuilder H(len);
210b57cec5SDimitry Andric H.add(orig_size);
220b57cec5SDimitry Andric // Start with frame #1 to skip __sanitizer_malloc frame, which is
230b57cec5SDimitry Andric // (a) almost always the same (well, could be operator new or new[])
240b57cec5SDimitry Andric // (b) can change hashes when compiler-rt is rebuilt, invalidating previous
250b57cec5SDimitry Andric // bisection results.
260b57cec5SDimitry Andric // Because of ASLR, use only offset inside the page.
270b57cec5SDimitry Andric for (uptr i = 1; i < len; ++i) H.add(((u32)stack->trace[i]) & 0xFFF);
280b57cec5SDimitry Andric return H.get();
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric
malloc_bisect(StackTrace * stack,uptr orig_size)31*e8d8bef9SDimitry Andric static inline bool malloc_bisect(StackTrace *stack, uptr orig_size) {
320b57cec5SDimitry Andric uptr left = flags()->malloc_bisect_left;
330b57cec5SDimitry Andric uptr right = flags()->malloc_bisect_right;
340b57cec5SDimitry Andric if (LIKELY(left == 0 && right == 0))
350b57cec5SDimitry Andric return true;
360b57cec5SDimitry Andric if (!stack)
370b57cec5SDimitry Andric return true;
380b57cec5SDimitry Andric // Allow malloc_bisect_right > (u32)(-1) to avoid spelling the latter in
390b57cec5SDimitry Andric // decimal.
400b57cec5SDimitry Andric uptr h = (uptr)malloc_hash(stack, orig_size);
410b57cec5SDimitry Andric if (h < left || h > right)
420b57cec5SDimitry Andric return false;
430b57cec5SDimitry Andric if (flags()->malloc_bisect_dump) {
440b57cec5SDimitry Andric Printf("[alloc] %u %zu\n", h, orig_size);
450b57cec5SDimitry Andric stack->Print();
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric return true;
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric
500b57cec5SDimitry Andric } // namespace __hwasan
51