brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 30ba812 Raw
106 lines · cpp
1//===-- sanitizer_unwind_win.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9/// Sanitizer unwind Windows specific functions.10//11//===----------------------------------------------------------------------===//12 13#include "sanitizer_platform.h"14#if SANITIZER_WINDOWS15 16#define WIN32_LEAN_AND_MEAN17#define NOGDI18#include <windows.h>19 20#include "sanitizer_dbghelp.h"  // for StackWalk6421#include "sanitizer_stacktrace.h"22#include "sanitizer_symbolizer.h"  // for InitializeDbgHelpIfNeeded23 24using namespace __sanitizer;25 26#if !SANITIZER_GO27void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {28  CHECK_GE(max_depth, 2);29  // FIXME: CaptureStackBackTrace might be too slow for us.30  // FIXME: Compare with StackWalk64.31  // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc32  size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax),33    (void **)&trace_buffer[0], 0);34  if (size == 0)35    return;36 37  // Skip the RTL frames by searching for the PC in the stacktrace.38  uptr pc_location = LocatePcInTrace(pc);39  PopStackFrames(pc_location);40 41  // Replace the first frame with the PC because the frame in the42  // stacktrace might be incorrect.43  trace_buffer[0] = pc;44}45 46#ifdef __clang__47#pragma clang diagnostic push48#pragma clang diagnostic ignored "-Wframe-larger-than="49#endif50void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {51  CHECK(context);52  CHECK_GE(max_depth, 2);53  CONTEXT ctx = *(CONTEXT *)context;54  STACKFRAME64 stack_frame;55  memset(&stack_frame, 0, sizeof(stack_frame));56 57  InitializeDbgHelpIfNeeded();58 59  size = 0;60#    if SANITIZER_WINDOWS6461#      if SANITIZER_ARM6462  int machine_type = IMAGE_FILE_MACHINE_ARM64;63  stack_frame.AddrPC.Offset = ctx.Pc;64  stack_frame.AddrFrame.Offset = ctx.Fp;65  stack_frame.AddrStack.Offset = ctx.Sp;66#      else67  int machine_type = IMAGE_FILE_MACHINE_AMD64;68  stack_frame.AddrPC.Offset = ctx.Rip;69  stack_frame.AddrFrame.Offset = ctx.Rbp;70  stack_frame.AddrStack.Offset = ctx.Rsp;71#      endif72#    else73#      if SANITIZER_ARM74  int machine_type = IMAGE_FILE_MACHINE_ARM;75  stack_frame.AddrPC.Offset = ctx.Pc;76  stack_frame.AddrFrame.Offset = ctx.R11;77  stack_frame.AddrStack.Offset = ctx.Sp;78#      elif SANITIZER_MIPS3279  int machine_type = IMAGE_FILE_MACHINE_R4000;80  stack_frame.AddrPC.Offset = ctx.Fir;81  stack_frame.AddrFrame.Offset = ctx.IntS8;82  stack_frame.AddrStack.Offset = ctx.IntSp;83#      else84  int machine_type = IMAGE_FILE_MACHINE_I386;85  stack_frame.AddrPC.Offset = ctx.Eip;86  stack_frame.AddrFrame.Offset = ctx.Ebp;87  stack_frame.AddrStack.Offset = ctx.Esp;88#      endif89#    endif90  stack_frame.AddrPC.Mode = AddrModeFlat;91  stack_frame.AddrFrame.Mode = AddrModeFlat;92  stack_frame.AddrStack.Mode = AddrModeFlat;93  while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(),94                     &stack_frame, &ctx, NULL, SymFunctionTableAccess64,95                     SymGetModuleBase64, NULL) &&96         size < Min(max_depth, kStackTraceMax)) {97    trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset;98  }99}100#    ifdef __clang__101#      pragma clang diagnostic pop102#    endif103#  endif  // #if !SANITIZER_GO104 105#endif  // SANITIZER_WINDOWS106