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