15f757f3fSDimitry Andric //===-- InstrumentationRuntimeASanLibsanitizers.cpp -----------------------===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric 95f757f3fSDimitry Andric #include "InstrumentationRuntimeASanLibsanitizers.h" 105f757f3fSDimitry Andric 115f757f3fSDimitry Andric #include "lldb/Breakpoint/StoppointCallbackContext.h" 125f757f3fSDimitry Andric #include "lldb/Core/Module.h" 135f757f3fSDimitry Andric #include "lldb/Core/PluginInterface.h" 145f757f3fSDimitry Andric #include "lldb/Core/PluginManager.h" 155f757f3fSDimitry Andric #include "lldb/Symbol/Symbol.h" 165f757f3fSDimitry Andric #include "lldb/Target/Process.h" 175f757f3fSDimitry Andric #include "lldb/Utility/RegularExpression.h" 185f757f3fSDimitry Andric 195f757f3fSDimitry Andric #include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h" 205f757f3fSDimitry Andric 215f757f3fSDimitry Andric using namespace lldb; 225f757f3fSDimitry Andric using namespace lldb_private; 235f757f3fSDimitry Andric 245f757f3fSDimitry Andric LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers) 255f757f3fSDimitry Andric 265f757f3fSDimitry Andric lldb::InstrumentationRuntimeSP 275f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers::CreateInstance( 285f757f3fSDimitry Andric const lldb::ProcessSP &process_sp) { 295f757f3fSDimitry Andric return InstrumentationRuntimeSP( 305f757f3fSDimitry Andric new InstrumentationRuntimeASanLibsanitizers(process_sp)); 315f757f3fSDimitry Andric } 325f757f3fSDimitry Andric 335f757f3fSDimitry Andric void InstrumentationRuntimeASanLibsanitizers::Initialize() { 345f757f3fSDimitry Andric PluginManager::RegisterPlugin( 355f757f3fSDimitry Andric GetPluginNameStatic(), 365f757f3fSDimitry Andric "AddressSanitizer instrumentation runtime plugin for Libsanitizers.", 375f757f3fSDimitry Andric CreateInstance, GetTypeStatic); 385f757f3fSDimitry Andric } 395f757f3fSDimitry Andric 405f757f3fSDimitry Andric void InstrumentationRuntimeASanLibsanitizers::Terminate() { 415f757f3fSDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 425f757f3fSDimitry Andric } 435f757f3fSDimitry Andric 445f757f3fSDimitry Andric lldb::InstrumentationRuntimeType 455f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() { 465f757f3fSDimitry Andric return eInstrumentationRuntimeTypeLibsanitizersAsan; 475f757f3fSDimitry Andric } 485f757f3fSDimitry Andric 495f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers:: 505f757f3fSDimitry Andric ~InstrumentationRuntimeASanLibsanitizers() { 515f757f3fSDimitry Andric Deactivate(); 525f757f3fSDimitry Andric } 535f757f3fSDimitry Andric 545f757f3fSDimitry Andric const RegularExpression & 555f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() { 565f757f3fSDimitry Andric static RegularExpression regex( 575f757f3fSDimitry Andric llvm::StringRef("libsystem_sanitizers\\.dylib")); 585f757f3fSDimitry Andric return regex; 595f757f3fSDimitry Andric } 605f757f3fSDimitry Andric 615f757f3fSDimitry Andric bool InstrumentationRuntimeASanLibsanitizers::CheckIfRuntimeIsValid( 625f757f3fSDimitry Andric const lldb::ModuleSP module_sp) { 635f757f3fSDimitry Andric const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType( 645f757f3fSDimitry Andric ConstString("__asan_abi_init"), lldb::eSymbolTypeAny); 655f757f3fSDimitry Andric 665f757f3fSDimitry Andric return symbol != nullptr; 675f757f3fSDimitry Andric } 685f757f3fSDimitry Andric 695f757f3fSDimitry Andric bool InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit( 705f757f3fSDimitry Andric void *baton, StoppointCallbackContext *context, user_id_t break_id, 715f757f3fSDimitry Andric user_id_t break_loc_id) { 725f757f3fSDimitry Andric assert(baton && "null baton"); 735f757f3fSDimitry Andric if (!baton) 745f757f3fSDimitry Andric return false; 755f757f3fSDimitry Andric 765f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers *const instance = 775f757f3fSDimitry Andric static_cast<InstrumentationRuntimeASanLibsanitizers *>(baton); 785f757f3fSDimitry Andric 795f757f3fSDimitry Andric ProcessSP process_sp = instance->GetProcessSP(); 805f757f3fSDimitry Andric 815f757f3fSDimitry Andric return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id, 825f757f3fSDimitry Andric break_loc_id); 835f757f3fSDimitry Andric } 845f757f3fSDimitry Andric 855f757f3fSDimitry Andric void InstrumentationRuntimeASanLibsanitizers::Activate() { 865f757f3fSDimitry Andric if (IsActive()) 875f757f3fSDimitry Andric return; 885f757f3fSDimitry Andric 895f757f3fSDimitry Andric ProcessSP process_sp = GetProcessSP(); 905f757f3fSDimitry Andric if (!process_sp) 915f757f3fSDimitry Andric return; 925f757f3fSDimitry Andric 93*0fca6ea1SDimitry Andric lldb::ModuleSP module_sp = GetRuntimeModuleSP(); 94*0fca6ea1SDimitry Andric 955f757f3fSDimitry Andric Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint( 96*0fca6ea1SDimitry Andric module_sp, process_sp, ConstString("sanitizers_address_on_report")); 97*0fca6ea1SDimitry Andric 98*0fca6ea1SDimitry Andric if (!breakpoint) { 99*0fca6ea1SDimitry Andric breakpoint = ReportRetriever::SetupBreakpoint( 100*0fca6ea1SDimitry Andric module_sp, process_sp, 1015f757f3fSDimitry Andric ConstString("_Z22raise_sanitizers_error23sanitizer_error_context")); 102*0fca6ea1SDimitry Andric } 1035f757f3fSDimitry Andric 1045f757f3fSDimitry Andric if (!breakpoint) 1055f757f3fSDimitry Andric return; 1065f757f3fSDimitry Andric 1075f757f3fSDimitry Andric const bool sync = false; 1085f757f3fSDimitry Andric 1095f757f3fSDimitry Andric breakpoint->SetCallback( 1105f757f3fSDimitry Andric InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit, this, sync); 1115f757f3fSDimitry Andric breakpoint->SetBreakpointKind("address-sanitizer-report"); 1125f757f3fSDimitry Andric SetBreakpointID(breakpoint->GetID()); 1135f757f3fSDimitry Andric 1145f757f3fSDimitry Andric SetActive(true); 1155f757f3fSDimitry Andric } 1165f757f3fSDimitry Andric 1175f757f3fSDimitry Andric void InstrumentationRuntimeASanLibsanitizers::Deactivate() { 1185f757f3fSDimitry Andric SetActive(false); 1195f757f3fSDimitry Andric 1205f757f3fSDimitry Andric if (GetBreakpointID() == LLDB_INVALID_BREAK_ID) 1215f757f3fSDimitry Andric return; 1225f757f3fSDimitry Andric 1235f757f3fSDimitry Andric if (ProcessSP process_sp = GetProcessSP()) { 1245f757f3fSDimitry Andric process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID()); 1255f757f3fSDimitry Andric SetBreakpointID(LLDB_INVALID_BREAK_ID); 1265f757f3fSDimitry Andric } 1275f757f3fSDimitry Andric } 128