xref: /freebsd/contrib/llvm-project/compiler-rt/lib/hwasan/hwasan_malloc_bisect.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
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