]>
Commit | Line | Data |
---|---|---|
d2ef4bee | 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 | ||
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 | ||
33 | void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { | |
34 | CurrentUBR = UBR; | |
35 | } | |
36 | ||
37 | SANITIZER_WEAK_DEFAULT_IMPL | |
38 | void __ubsan::__ubsan_on_report(void) {} | |
39 | ||
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 | } |