xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/lib/ubsan/ubsan_monitor.cc (revision a7c257b03e4462df2b1020128fb82716512d7856)
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 
UndefinedBehaviorReport(const char * IssueKind,Location & Loc,InternalScopedString & Msg)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 
RegisterUndefinedBehaviorReport(UndefinedBehaviorReport * UBR)35 void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) {
36   CurrentUBR = UBR;
37 }
38 
39 SANITIZER_WEAK_DEFAULT_IMPL
__ubsan_on_report(void)40 void __ubsan::__ubsan_on_report(void) {}
41 
__ubsan_get_current_report_data(const char ** OutIssueKind,const char ** OutMessage,const char ** OutFilename,unsigned * OutLine,unsigned * OutCol,char ** OutMemoryAddr)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