145
|
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 }
|