177edd9b7SUsama Hameed //===-- InstrumentationRuntimeASanLibsanitizers.cpp -----------------------===//
277edd9b7SUsama Hameed //
377edd9b7SUsama Hameed // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
477edd9b7SUsama Hameed // See https://llvm.org/LICENSE.txt for license information.
577edd9b7SUsama Hameed // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
677edd9b7SUsama Hameed //
777edd9b7SUsama Hameed //===----------------------------------------------------------------------===//
877edd9b7SUsama Hameed 
977edd9b7SUsama Hameed #include "InstrumentationRuntimeASanLibsanitizers.h"
1077edd9b7SUsama Hameed 
1177edd9b7SUsama Hameed #include "lldb/Breakpoint/StoppointCallbackContext.h"
1277edd9b7SUsama Hameed #include "lldb/Core/Module.h"
1377edd9b7SUsama Hameed #include "lldb/Core/PluginInterface.h"
1477edd9b7SUsama Hameed #include "lldb/Core/PluginManager.h"
1577edd9b7SUsama Hameed #include "lldb/Symbol/Symbol.h"
1677edd9b7SUsama Hameed #include "lldb/Target/Process.h"
1777edd9b7SUsama Hameed #include "lldb/Utility/RegularExpression.h"
1877edd9b7SUsama Hameed 
1977edd9b7SUsama Hameed #include "Plugins/InstrumentationRuntime/Utility/ReportRetriever.h"
2077edd9b7SUsama Hameed 
2177edd9b7SUsama Hameed using namespace lldb;
2277edd9b7SUsama Hameed using namespace lldb_private;
2377edd9b7SUsama Hameed 
2477edd9b7SUsama Hameed LLDB_PLUGIN_DEFINE(InstrumentationRuntimeASanLibsanitizers)
2577edd9b7SUsama Hameed 
2677edd9b7SUsama Hameed lldb::InstrumentationRuntimeSP
2777edd9b7SUsama Hameed InstrumentationRuntimeASanLibsanitizers::CreateInstance(
2877edd9b7SUsama Hameed     const lldb::ProcessSP &process_sp) {
2977edd9b7SUsama Hameed   return InstrumentationRuntimeSP(
3077edd9b7SUsama Hameed       new InstrumentationRuntimeASanLibsanitizers(process_sp));
3177edd9b7SUsama Hameed }
3277edd9b7SUsama Hameed 
3377edd9b7SUsama Hameed void InstrumentationRuntimeASanLibsanitizers::Initialize() {
3477edd9b7SUsama Hameed   PluginManager::RegisterPlugin(
3577edd9b7SUsama Hameed       GetPluginNameStatic(),
3677edd9b7SUsama Hameed       "AddressSanitizer instrumentation runtime plugin for Libsanitizers.",
3777edd9b7SUsama Hameed       CreateInstance, GetTypeStatic);
3877edd9b7SUsama Hameed }
3977edd9b7SUsama Hameed 
4077edd9b7SUsama Hameed void InstrumentationRuntimeASanLibsanitizers::Terminate() {
4177edd9b7SUsama Hameed   PluginManager::UnregisterPlugin(CreateInstance);
4277edd9b7SUsama Hameed }
4377edd9b7SUsama Hameed 
4477edd9b7SUsama Hameed lldb::InstrumentationRuntimeType
4577edd9b7SUsama Hameed InstrumentationRuntimeASanLibsanitizers::GetTypeStatic() {
4677edd9b7SUsama Hameed   return eInstrumentationRuntimeTypeLibsanitizersAsan;
4777edd9b7SUsama Hameed }
4877edd9b7SUsama Hameed 
4977edd9b7SUsama Hameed InstrumentationRuntimeASanLibsanitizers::
5077edd9b7SUsama Hameed     ~InstrumentationRuntimeASanLibsanitizers() {
5177edd9b7SUsama Hameed   Deactivate();
5277edd9b7SUsama Hameed }
5377edd9b7SUsama Hameed 
5477edd9b7SUsama Hameed const RegularExpression &
5577edd9b7SUsama Hameed InstrumentationRuntimeASanLibsanitizers::GetPatternForRuntimeLibrary() {
5677edd9b7SUsama Hameed   static RegularExpression regex(
5777edd9b7SUsama Hameed       llvm::StringRef("libsystem_sanitizers\\.dylib"));
5877edd9b7SUsama Hameed   return regex;
5977edd9b7SUsama Hameed }
6077edd9b7SUsama Hameed 
6177edd9b7SUsama Hameed bool InstrumentationRuntimeASanLibsanitizers::CheckIfRuntimeIsValid(
6277edd9b7SUsama Hameed     const lldb::ModuleSP module_sp) {
6377edd9b7SUsama Hameed   const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
6477edd9b7SUsama Hameed       ConstString("__asan_abi_init"), lldb::eSymbolTypeAny);
6577edd9b7SUsama Hameed 
6677edd9b7SUsama Hameed   return symbol != nullptr;
6777edd9b7SUsama Hameed }
6877edd9b7SUsama Hameed 
6977edd9b7SUsama Hameed bool InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit(
7077edd9b7SUsama Hameed     void *baton, StoppointCallbackContext *context, user_id_t break_id,
7177edd9b7SUsama Hameed     user_id_t break_loc_id) {
7277edd9b7SUsama Hameed   assert(baton && "null baton");
7377edd9b7SUsama Hameed   if (!baton)
7477edd9b7SUsama Hameed     return false;
7577edd9b7SUsama Hameed 
7677edd9b7SUsama Hameed   InstrumentationRuntimeASanLibsanitizers *const instance =
7777edd9b7SUsama Hameed       static_cast<InstrumentationRuntimeASanLibsanitizers *>(baton);
7877edd9b7SUsama Hameed 
7977edd9b7SUsama Hameed   ProcessSP process_sp = instance->GetProcessSP();
8077edd9b7SUsama Hameed 
8177edd9b7SUsama Hameed   return ReportRetriever::NotifyBreakpointHit(process_sp, context, break_id,
8277edd9b7SUsama Hameed                                               break_loc_id);
8377edd9b7SUsama Hameed }
8477edd9b7SUsama Hameed 
8577edd9b7SUsama Hameed void InstrumentationRuntimeASanLibsanitizers::Activate() {
8677edd9b7SUsama Hameed   if (IsActive())
8777edd9b7SUsama Hameed     return;
8877edd9b7SUsama Hameed 
8977edd9b7SUsama Hameed   ProcessSP process_sp = GetProcessSP();
9077edd9b7SUsama Hameed   if (!process_sp)
9177edd9b7SUsama Hameed     return;
9277edd9b7SUsama Hameed 
9377edd9b7SUsama Hameed   Breakpoint *breakpoint = ReportRetriever::SetupBreakpoint(
94*01e980e7SJulian Lettner       GetRuntimeModuleSP(), process_sp,
95*01e980e7SJulian Lettner       ConstString("sanitizers_address_on_report"));
9677edd9b7SUsama Hameed   if (!breakpoint)
9777edd9b7SUsama Hameed     return;
9877edd9b7SUsama Hameed 
9977edd9b7SUsama Hameed   const bool sync = false;
10077edd9b7SUsama Hameed 
10177edd9b7SUsama Hameed   breakpoint->SetCallback(
10277edd9b7SUsama Hameed       InstrumentationRuntimeASanLibsanitizers::NotifyBreakpointHit, this, sync);
10377edd9b7SUsama Hameed   breakpoint->SetBreakpointKind("address-sanitizer-report");
10477edd9b7SUsama Hameed   SetBreakpointID(breakpoint->GetID());
10577edd9b7SUsama Hameed 
10677edd9b7SUsama Hameed   SetActive(true);
10777edd9b7SUsama Hameed }
10877edd9b7SUsama Hameed 
10977edd9b7SUsama Hameed void InstrumentationRuntimeASanLibsanitizers::Deactivate() {
11077edd9b7SUsama Hameed   SetActive(false);
11177edd9b7SUsama Hameed 
11277edd9b7SUsama Hameed   if (GetBreakpointID() == LLDB_INVALID_BREAK_ID)
11377edd9b7SUsama Hameed     return;
11477edd9b7SUsama Hameed 
11577edd9b7SUsama Hameed   if (ProcessSP process_sp = GetProcessSP()) {
11677edd9b7SUsama Hameed     process_sp->GetTarget().RemoveBreakpointByID(GetBreakpointID());
11777edd9b7SUsama Hameed     SetBreakpointID(LLDB_INVALID_BREAK_ID);
11877edd9b7SUsama Hameed   }
11977edd9b7SUsama Hameed }
120