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 21 using namespace lldb; 22 using namespace lldb_private; 23 24 LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers) 25 26 lldb::InstrumentationRuntimeSP 27 InstrumentationRuntimeASanLibsanitizers::CreateInstance( 28 const lldb::ProcessSP &process_sp) { 29 return InstrumentationRuntimeSP( 30 new InstrumentationRuntimeASanLibsanitizers(process_sp)); 31 } 32 33 void InstrumentationRuntimeASanLibsanitizers::Initialize() { 34 PluginManager::RegisterPlugin( 35 GetPluginNameStatic(), 36 "AddressSanitizer instrumentation runtime plugin for Libsanitizers.", 37 CreateInstance, GetTypeStatic); 38 } 39 40 void InstrumentationRuntimeASanLibsanitizers::Terminate() { 41 PluginManager::UnregisterPlugin(CreateInstance); 42 } 43 44 lldb::InstrumentationRuntimeType 45 InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() { 46 return eInstrumentationRuntimeTypeLibsanitizersAsan; 47 } 48 49 InstrumentationRuntimeASanLibsanitizers:: 50 ~InstrumentationRuntimeASanLibsanitizers() { 51 Deactivate(); 52 } 53 54 const RegularExpression & 55 InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() { 56 static RegularExpression regex( 57 llvm::StringRef("libsystem_sanitizers\\.dylib")); 58 return regex; 59 } 60 61 bool 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 69 bool 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 85 void 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 110 void 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