Home | History | Annotate | Line # | Download | only in ubsan
      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 
     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 
     35 void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) {
     36   CurrentUBR = UBR;
     37 }
     38 
     39 SANITIZER_WEAK_DEFAULT_IMPL
     40 void __ubsan::__ubsan_on_report(void) {}
     41 
     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