1 //===-- ubsan_monitor.cpp ---------------------------------------*- C++ -*-===// 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 // Hooks which allow a monitor process to inspect UBSan's diagnostics. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ubsan_monitor.h" 14 15 using namespace __ubsan; 16 17 UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, 18 Location &Loc, 19 InternalScopedString &Msg) 20 : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { 21 // We have the common sanitizer reporting lock, so it's safe to register a 22 // new UB report. 23 RegisterUndefinedBehaviorReport(this); 24 25 // Make a copy of the diagnostic. 26 Buffer.append("%s", Msg.data()); 27 28 // Let the monitor know that a report is available. 29 __ubsan_on_report(); 30 } 31 32 static UndefinedBehaviorReport *CurrentUBR; 33 34 void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { 35 CurrentUBR = UBR; 36 } 37 38 SANITIZER_WEAK_DEFAULT_IMPL 39 void __ubsan::__ubsan_on_report(void) {} 40 41 void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, 42 const char **OutMessage, 43 const char **OutFilename, 44 unsigned *OutLine, 45 unsigned *OutCol, 46 char **OutMemoryAddr) { 47 if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol || 48 !OutMemoryAddr) 49 UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data"); 50 51 InternalScopedString &Buf = CurrentUBR->Buffer; 52 53 // Ensure that the first character of the diagnostic text can't start with a 54 // lowercase letter. 55 char FirstChar = Buf.data()[0]; 56 if (FirstChar >= 'a' && FirstChar <= 'z') 57 Buf.data()[0] = FirstChar - 'a' + 'A'; 58 59 *OutIssueKind = CurrentUBR->IssueKind; 60 *OutMessage = Buf.data(); 61 if (!CurrentUBR->Loc.isSourceLocation()) { 62 *OutFilename = "<unknown>"; 63 *OutLine = *OutCol = 0; 64 } else { 65 SourceLocation SL = CurrentUBR->Loc.getSourceLocation(); 66 *OutFilename = SL.getFilename(); 67 *OutLine = SL.getLine(); 68 *OutCol = SL.getColumn(); 69 } 70 71 if (CurrentUBR->Loc.isMemoryLocation()) 72 *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation(); 73 else 74 *OutMemoryAddr = nullptr; 75 } 76