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