1 //===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Hooks which allow a monitor process to inspect UBSan's diagnostics. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ubsan_monitor.h" 15 16 using namespace __ubsan; 17 18 UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, 19 Location &Loc, 20 InternalScopedString &Msg) 21 : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { 22 // We have the common sanitizer reporting lock, so it's safe to register a 23 // new UB report. 24 RegisterUndefinedBehaviorReport(this); 25 26 // Make a copy of the diagnostic. 27 Buffer.append("%s", 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()[0]; 57 if (FirstChar >= 'a' && FirstChar <= 'z') 58 Buf.data()[0] = FirstChar - '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