1//===-- InstrumentationRuntimeASanLibsanitizers.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-exception 6// 7//===----------------------------------------------------------------------===// 8 9#include "InstrumentationRuntimeASanLibsanitizers.h" 10 11#include "lldb/Breakpoint/StoppointCallbackContext.h" 12#include "lldb/Core/Module.h" 13#include "lldb/Core/PluginInterface.h" 14#include "lldb/Core/PluginManager.h" 15#include "lldb/Symbol/Symbol.h" 16#include "lldb/Target/Process.h" 17#include "lldb/Utility/RegularExpression.h" 18 19#include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h" 20 21using namespace lldb; 22using namespace lldb_private; 23 24LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers) 25 26lldb::InstrumentationRuntimeSP 27InstrumentationRuntimeASanLibsanitizers::CreateInstance( 28 const lldb::ProcessSP &process_sp) { 29 return InstrumentationRuntimeSP( 30 new InstrumentationRuntimeASanLibsanitizers(process_sp)); 31} 32 33void InstrumentationRuntimeASanLibsanitizers::Initialize() { 34 PluginManager::RegisterPlugin( 35 GetPluginNameStatic(), 36 "AddressSanitizer instrumentation runtime plugin for Libsanitizers.", 37 CreateInstance, GetTypeStatic); 38} 39 40void InstrumentationRuntimeASanLibsanitizers::Terminate() { 41 PluginManager::UnregisterPlugin(CreateInstance); 42} 43 44lldb::InstrumentationRuntimeType 45InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() { 46 return eInstrumentationRuntimeTypeLibsanitizersAsan; 47} 48 49InstrumentationRuntimeASanLibsanitizers:: 50 ~InstrumentationRuntimeASanLibsanitizers() { 51 Deactivate(); 52} 53 54const RegularExpression & 55InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() { 56 static RegularExpression regex( 57 llvm::StringRef("libsystem_sanitizers\\.dylib")); 58 return regex; 59} 60 61bool InstrumentationRuntimeASanLibsanitizers::CheckIfRuntimeIsValid( 62 const lldb::ModuleSP module_sp) { 63 const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( 64 ConstString("__asan_abi_init"), lldb::eSymbolTypeAny); 65 66 return symbol != nullptr; 67} 68 69bool InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit( 70 void *baton, StoppointCallbackContext *context, user_id_t break_id, 71 user_id_t break_loc_id) { 72 assert(baton && "null baton"); 73 if (!baton) 74 return false; 75 76 InstrumentationRuntimeASanLibsanitizers *const instance = 77 static_cast<InstrumentationRuntimeASanLibsanitizers *>(baton); 78 79 ProcessSP process_sp = instance->GetProcessSP(); 80 81 return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id, 82 break_loc_id); 83} 84 85void InstrumentationRuntimeASanLibsanitizers::Activate() { 86 if (IsActive()) 87 return; 88 89 ProcessSP process_sp = GetProcessSP(); 90 if (!process_sp) 91 return; 92 93 Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint( 94 GetRuntimeModuleSP(), process_sp, 95 ConstString("_Z22raise_sanitizers_error23sanitizer_error_context")); 96 97 if (!breakpoint) 98 return; 99 100 const bool sync = false; 101 102 breakpoint->SetCallback( 103 InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit, this, sync); 104 breakpoint->SetBreakpointKind("address-sanitizer-report"); 105 SetBreakpointID(breakpoint->GetID()); 106 107 SetActive(true); 108} 109 110void InstrumentationRuntimeASanLibsanitizers::Deactivate() { 111 SetActive(false); 112 113 if (GetBreakpointID() == LLDB_INVALID_BREAK_ID) 114 return; 115 116 if (ProcessSP process_sp = GetProcessSP()) { 117 process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID()); 118 SetBreakpointID(LLDB_INVALID_BREAK_ID); 119 } 120} 121