//===-- InstrumentationRuntimeUBSan.cpp -----------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "InstrumentationRuntimeUBSan.h"

#include "Plugins/Process/Utility/HistoryThread.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/InstrumentationRuntimeStopInfo.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
#include <cctype>

#include <memory>

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(InstrumentationRuntimeUBSan)

InstrumentationRuntimeUBSan::~InstrumentationRuntimeUBSan() { Deactivate(); }

lldb::InstrumentationRuntimeSP
InstrumentationRuntimeUBSan::CreateInstance(const lldb::ProcessSP &process_sp) {
  return InstrumentationRuntimeSP(new InstrumentationRuntimeUBSan(process_sp));
}

void InstrumentationRuntimeUBSan::Initialize() {
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(),
      "UndefinedBehaviorSanitizer instrumentation runtime plugin.",
      CreateInstance, GetTypeStatic);
}

void InstrumentationRuntimeUBSan::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}

lldb::InstrumentationRuntimeType InstrumentationRuntimeUBSan::GetTypeStatic() {
  return eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer;
}

static const char *ub_sanitizer_retrieve_report_data_prefix = R"(
extern "C" {
void
__ubsan_get_current_report_data(const char **OutIssueKind,
    const char **OutMessage, const char **OutFilename, unsigned *OutLine,
    unsigned *OutCol, char **OutMemoryAddr);
}

struct data {
  const char *issue_kind;
  const char *message;
  const char *filename;
  unsigned line;
  unsigned col;
  char *memory_addr;
};
)";

static const char *ub_sanitizer_retrieve_report_data_command = R"(
data t;
__ubsan_get_current_report_data(&t.issue_kind, &t.message, &t.filename, &t.line,
                                &t.col, &t.memory_addr);
t;
)";

static addr_t RetrieveUnsigned(ValueObjectSP return_value_sp,
                               ProcessSP process_sp,
                               const std::string &expression_path) {
  return return_value_sp->GetValueForExpressionPath(expression_path.c_str())
      ->GetValueAsUnsigned(0);
}

static std::string RetrieveString(ValueObjectSP return_value_sp,
                                  ProcessSP process_sp,
                                  const std::string &expression_path) {
  addr_t ptr = RetrieveUnsigned(return_value_sp, process_sp, expression_path);
  std::string str;
  Status error;
  process_sp->ReadCStringFromMemory(ptr, str, error);
  return str;
}

StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData(
    ExecutionContextRef exe_ctx_ref) {
  ProcessSP process_sp = GetProcessSP();
  if (!process_sp)
    return StructuredData::ObjectSP();

  ThreadSP thread_sp = exe_ctx_ref.GetThreadSP();
  StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
  ModuleSP runtime_module_sp = GetRuntimeModuleSP();
  Target &target = process_sp->GetTarget();

  if (!frame_sp)
    return StructuredData::ObjectSP();

  StreamFileSP Stream = target.GetDebugger().GetOutputStreamSP();

  EvaluateExpressionOptions options;
  options.SetUnwindOnError(true);
  options.SetTryAllThreads(true);
  options.SetStopOthers(true);
  options.SetIgnoreBreakpoints(true);
  options.SetTimeout(process_sp->GetUtilityExpressionTimeout());
  options.SetPrefix(ub_sanitizer_retrieve_report_data_prefix);
  options.SetAutoApplyFixIts(false);
  options.SetLanguage(eLanguageTypeObjC_plus_plus);

  ValueObjectSP main_value;
  ExecutionContext exe_ctx;
  Status eval_error;
  frame_sp->CalculateExecutionContext(exe_ctx);
  ExpressionResults result = UserExpression::Evaluate(
      exe_ctx, options, ub_sanitizer_retrieve_report_data_command, "",
      main_value, eval_error);
  if (result != eExpressionCompleted) {
    target.GetDebugger().GetAsyncOutputStream()->Printf(
        "Warning: Cannot evaluate UndefinedBehaviorSanitizer expression:\n%s\n",
        eval_error.AsCString());
    return StructuredData::ObjectSP();
  }

  // Gather the PCs of the user frames in the backtrace.
  StructuredData::Array *trace = new StructuredData::Array();
  auto trace_sp = StructuredData::ObjectSP(trace);
  for (unsigned I = 0; I < thread_sp->GetStackFrameCount(); ++I) {
    const Address FCA = thread_sp->GetStackFrameAtIndex(I)
                            ->GetFrameCodeAddressForSymbolication();
    if (FCA.GetModule() == runtime_module_sp) // Skip PCs from the runtime.
      continue;

    lldb::addr_t PC = FCA.GetLoadAddress(&target);
    trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC)));
  }

  std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind");
  std::string ErrMessage = RetrieveString(main_value, process_sp, ".message");
  std::string Filename = RetrieveString(main_value, process_sp, ".filename");
  unsigned Line = RetrieveUnsigned(main_value, process_sp, ".line");
  unsigned Col = RetrieveUnsigned(main_value, process_sp, ".col");
  uintptr_t MemoryAddr =
      RetrieveUnsigned(main_value, process_sp, ".memory_addr");

  auto *d = new StructuredData::Dictionary();
  auto dict_sp = StructuredData::ObjectSP(d);
  d->AddStringItem("instrumentation_class", "UndefinedBehaviorSanitizer");
  d->AddStringItem("description", IssueKind);
  d->AddStringItem("summary", ErrMessage);
  d->AddStringItem("filename", Filename);
  d->AddIntegerItem("line", Line);
  d->AddIntegerItem("col", Col);
  d->AddIntegerItem("memory_address", MemoryAddr);
  d->AddIntegerItem("tid", thread_sp->GetID());
  d->AddItem("trace", trace_sp);
  return dict_sp;
}

static std::string GetStopReasonDescription(StructuredData::ObjectSP report) {
  llvm::StringRef stop_reason_description_ref;
  report->GetAsDictionary()->GetValueForKeyAsString(
      "description", stop_reason_description_ref);
  std::string stop_reason_description =
      std::string(stop_reason_description_ref);

  if (!stop_reason_description.size()) {
    stop_reason_description = "Undefined behavior detected";
  } else {
    stop_reason_description[0] = toupper(stop_reason_description[0]);
    for (unsigned I = 1; I < stop_reason_description.size(); ++I)
      if (stop_reason_description[I] == '-')
        stop_reason_description[I] = ' ';
  }
  return stop_reason_description;
}

bool InstrumentationRuntimeUBSan::NotifyBreakpointHit(
    void *baton, StoppointCallbackContext *context, user_id_t break_id,
    user_id_t break_loc_id) {
  assert(baton && "null baton");
  if (!baton)
    return false; ///< false => resume execution.

  InstrumentationRuntimeUBSan *const instance =
      static_cast<InstrumentationRuntimeUBSan *>(baton);

  ProcessSP process_sp = instance->GetProcessSP();
  ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
  if (!process_sp || !thread_sp ||
      process_sp != context->exe_ctx_ref.GetProcessSP())
    return false;

  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
    return false;

  StructuredData::ObjectSP report =
      instance->RetrieveReportData(context->exe_ctx_ref);

  if (report) {
    thread_sp->SetStopInfo(
        InstrumentationRuntimeStopInfo::CreateStopReasonWithInstrumentationData(
            *thread_sp, GetStopReasonDescription(report), report));
    return true;
  }

  return false;
}

const RegularExpression &
InstrumentationRuntimeUBSan::GetPatternForRuntimeLibrary() {
  static RegularExpression regex(llvm::StringRef("libclang_rt\\.(a|t|ub)san_"));
  return regex;
}

bool InstrumentationRuntimeUBSan::CheckIfRuntimeIsValid(
    const lldb::ModuleSP module_sp) {
  static ConstString ubsan_test_sym("__ubsan_on_report");
  const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(
      ubsan_test_sym, lldb::eSymbolTypeAny);
  return symbol != nullptr;
}

// FIXME: Factor out all the logic we have in common with the {a,t}san plugins.
void InstrumentationRuntimeUBSan::Activate() {
  if (IsActive())
    return;

  ProcessSP process_sp = GetProcessSP();
  if (!process_sp)
    return;

  ModuleSP runtime_module_sp = GetRuntimeModuleSP();

  ConstString symbol_name("__ubsan_on_report");
  const Symbol *symbol = runtime_module_sp->FindFirstSymbolWithNameAndType(
      symbol_name, eSymbolTypeCode);

  if (symbol == nullptr)
    return;

  if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
    return;

  Target &target = process_sp->GetTarget();
  addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);

  if (symbol_address == LLDB_INVALID_ADDRESS)
    return;

  Breakpoint *breakpoint =
      process_sp->GetTarget()
          .CreateBreakpoint(symbol_address, /*internal=*/true,
                            /*hardware=*/false)
          .get();
  breakpoint->SetCallback(InstrumentationRuntimeUBSan::NotifyBreakpointHit,
                          this, true);
  breakpoint->SetBreakpointKind("undefined-behavior-sanitizer-report");
  SetBreakpointID(breakpoint->GetID());

  SetActive(true);
}

void InstrumentationRuntimeUBSan::Deactivate() {
  SetActive(false);

  auto BID = GetBreakpointID();
  if (BID == LLDB_INVALID_BREAK_ID)
    return;

  if (ProcessSP process_sp = GetProcessSP()) {
    process_sp->GetTarget().RemoveBreakpointByID(BID);
    SetBreakpointID(LLDB_INVALID_BREAK_ID);
  }
}

lldb::ThreadCollectionSP
InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
    StructuredData::ObjectSP info) {
  ThreadCollectionSP threads;
  threads = std::make_shared<ThreadCollection>();

  ProcessSP process_sp = GetProcessSP();

  if (info->GetObjectForDotSeparatedPath("instrumentation_class")
          ->GetStringValue() != "UndefinedBehaviorSanitizer")
    return threads;

  std::vector<lldb::addr_t> PCs;
  auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray();
  trace->ForEach([&PCs](StructuredData::Object *PC) -> bool {
    PCs.push_back(PC->GetAsInteger()->GetValue());
    return true;
  });

  if (PCs.empty())
    return threads;

  StructuredData::ObjectSP thread_id_obj =
      info->GetObjectForDotSeparatedPath("tid");
  tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0;

  // We gather symbolication addresses above, so no need for HistoryThread to
  // try to infer the call addresses.
  bool pcs_are_call_addresses = true;
  ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
      *process_sp, tid, PCs, pcs_are_call_addresses);
  std::string stop_reason_description = GetStopReasonDescription(info);
  new_thread_sp->SetName(stop_reason_description.c_str());

  // Save this in the Process' ExtendedThreadList so a strong pointer retains
  // the object
  process_sp->GetExtendedThreadList().AddThread(new_thread_sp);
  threads->AddThread(new_thread_sp);

  return threads;
}
