| //===-- ubsan_monitor.cpp ---------------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Hooks which allow a monitor process to inspect UBSan's diagnostics. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "ubsan_monitor.h" |
| |
| using namespace __ubsan; |
| |
| UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, |
| Location &Loc, |
| InternalScopedString &Msg) |
| : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { |
| // We have the common sanitizer reporting lock, so it's safe to register a |
| // new UB report. |
| RegisterUndefinedBehaviorReport(this); |
| |
| // Make a copy of the diagnostic. |
| Buffer.append("%s", Msg.data()); |
| |
| // Let the monitor know that a report is available. |
| __ubsan_on_report(); |
| } |
| |
| static UndefinedBehaviorReport *CurrentUBR; |
| |
| void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { |
| CurrentUBR = UBR; |
| } |
| |
| SANITIZER_WEAK_DEFAULT_IMPL |
| void __ubsan::__ubsan_on_report(void) {} |
| |
| void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, |
| const char **OutMessage, |
| const char **OutFilename, |
| unsigned *OutLine, |
| unsigned *OutCol, |
| char **OutMemoryAddr) { |
| if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol || |
| !OutMemoryAddr) |
| UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data"); |
| |
| InternalScopedString &Buf = CurrentUBR->Buffer; |
| |
| // Ensure that the first character of the diagnostic text can't start with a |
| // lowercase letter. |
| char FirstChar = Buf.data()[0]; |
| if (FirstChar >= 'a' && FirstChar <= 'z') |
| Buf.data()[0] = FirstChar - 'a' + 'A'; |
| |
| *OutIssueKind = CurrentUBR->IssueKind; |
| *OutMessage = Buf.data(); |
| if (!CurrentUBR->Loc.isSourceLocation()) { |
| *OutFilename = "<unknown>"; |
| *OutLine = *OutCol = 0; |
| } else { |
| SourceLocation SL = CurrentUBR->Loc.getSourceLocation(); |
| *OutFilename = SL.getFilename(); |
| *OutLine = SL.getLine(); |
| *OutCol = SL.getColumn(); |
| } |
| |
| if (CurrentUBR->Loc.isMemoryLocation()) |
| *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation(); |
| else |
| *OutMemoryAddr = nullptr; |
| } |