reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
//===-- 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;
}