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) { 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 if (Msg.length()) 27 Buffer.Append(Msg.data()); 28 29 // Let the monitor know that a report is available. 30 __ubsan_on_report(); 31 } 32 33 static UndefinedBehaviorReport *CurrentUBR; 34 35 void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { 36 CurrentUBR = UBR; 37 } 38 39 SANITIZER_WEAK_DEFAULT_IMPL 40 void __ubsan::__ubsan_on_report(void) {} 41 42 void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, 43 const char **OutMessage, 44 const char **OutFilename, 45 unsigned *OutLine, 46 unsigned *OutCol, 47 char **OutMemoryAddr) { 48 if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol || 49 !OutMemoryAddr) 50 UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data"); 51 52 InternalScopedString &Buf = CurrentUBR->Buffer; 53 54 // Ensure that the first character of the diagnostic text can't start with a 55 // lowercase letter. 56 char FirstChar = *Buf.data(); 57 if (FirstChar >= 'a' && FirstChar <= 'z') 58 *Buf.data() += 'A' - 'a'; 59 60 *OutIssueKind = CurrentUBR->IssueKind; 61 *OutMessage = Buf.data(); 62 if (!CurrentUBR->Loc.isSourceLocation()) { 63 *OutFilename = "<unknown>"; 64 *OutLine = *OutCol = 0; 65 } else { 66 SourceLocation SL = CurrentUBR->Loc.getSourceLocation(); 67 *OutFilename = SL.getFilename(); 68 *OutLine = SL.getLine(); 69 *OutCol = SL.getColumn(); 70 } 71 72 if (CurrentUBR->Loc.isMemoryLocation()) 73 *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation(); 74 else 75 *OutMemoryAddr = nullptr; 76 } 77