]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_monitor.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / ubsan / ubsan_monitor.cpp
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 }