// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "tools/fidlcat/lib/syscall_decoder.h"

#include <lib/syslog/cpp/macros.h>
#include <sys/time.h>
#include <zircon/types.h>

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <vector>

#include "src/developer/debug/zxdb/client/breakpoint.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/memory_dump.h"
#include "src/developer/debug/zxdb/client/process.h"
#include "src/developer/debug/zxdb/client/step_thread_controller.h"
#include "src/developer/debug/zxdb/client/thread.h"
#include "src/developer/debug/zxdb/symbols/symbol.h"
#include "tools/fidlcat/lib/interception_workflow.h"
#include "tools/fidlcat/lib/type_decoder.h"

namespace fidlcat {

constexpr int kBitsPerByte = 8;

// Helper function to convert a vector of bytes to a T.
template <typename T>
T GetValueFromBytes(const std::vector<uint8_t>& bytes, size_t offset) {
  T ret = 0;
  for (size_t i = 0; (i < sizeof(ret)) && (offset < bytes.size()); i++) {
    ret |= static_cast<uint64_t>(bytes[offset++]) << (i * kBitsPerByte);
  }
  return ret;
}

uint64_t GetRegisterValue(const std::vector<debug_ipc::Register>& general_registers,
                          const debug_ipc::RegisterID register_id) {
  for (const auto& reg : general_registers) {
    if (reg.id == register_id) {
      return GetValueFromBytes<uint64_t>(reg.data, 0);
    }
  }
  return 0;
}

void MemoryDumpToVector(const zxdb::MemoryDump& dump, std::vector<uint8_t>* output_vector) {
  output_vector->reserve(dump.size());
  for (const debug_ipc::MemoryBlock& block : dump.blocks()) {
    FX_DCHECK(block.valid);
    for (size_t offset = 0; offset < block.size; ++offset) {
      output_vector->push_back(block.data[offset]);
    }
  }
}

void SyscallUse::SyscallInputsDecoded(SyscallDecoder* decoder) {}

void SyscallUse::SyscallOutputsDecoded(SyscallDecoder* decoder) {}

void SyscallUse::SyscallDecodingError(const DecoderError& error, SyscallDecoder* decoder) {
  FX_LOGS(ERROR) << error.message();
  decoder->Destroy();
}

SyscallDecoder::SyscallDecoder(SyscallDecoderDispatcher* dispatcher,
                               InterceptingThreadObserver* thread_observer, zxdb::Thread* thread,
                               const Syscall* syscall, std::unique_ptr<SyscallUse> use,
                               int64_t timestamp)
    : dispatcher_(dispatcher),
      thread_observer_(thread_observer),
      weak_thread_(thread->GetWeakPtr()),
      arch_(thread->session()->arch()),
      syscall_(syscall),
      use_(std::move(use)),
      timestamp_(timestamp) {
  fidlcat_thread_ = dispatcher_->SearchThread(thread->GetKoid());
  if (fidlcat_thread_ == nullptr) {
    Process* fidlcat_process = dispatcher_->SearchProcess(thread->GetProcess()->GetKoid());
    if (fidlcat_process == nullptr) {
      fidlcat_process = dispatcher_->CreateProcess(thread->GetProcess()->GetName(),
                                                   thread->GetProcess()->GetKoid(),
                                                   thread->GetProcess()->GetWeakPtr());
    }
    fidlcat_thread_ = dispatcher_->CreateThread(thread->GetKoid(), fidlcat_process);
  }
}

void SyscallDecoder::LoadMemory(uint64_t address, size_t size, std::vector<uint8_t>* destination) {
  if (address == 0) {
    // Null pointer => don't load anything.
    return;
  }
  zxdb::Thread* thread = get_thread();
  if (thread == nullptr) {
    aborted_ = true;
    Destroy();
  }
  ++pending_request_count_;
  thread->GetProcess()->ReadMemory(
      address, size,
      [this, address, size, destination](const zxdb::Err& err, zxdb::MemoryDump dump) {
        --pending_request_count_;
        if (aborted()) {
          Destroy();
        } else {
          if (!err.ok()) {
            Error(DecoderError::Type::kCantReadMemory)
                << "Can't load memory at " << address << ": " << err.msg();
          } else if ((dump.size() != size) || !dump.AllValid()) {
            Error(DecoderError::Type::kCantReadMemory)
                << "Can't load memory at " << address << ": not enough data";
          } else {
            MemoryDumpToVector(dump, destination);
          }
          if (input_arguments_loaded_) {
            LoadOutputs();
          } else {
            LoadInputs();
          }
        }
      });
}

void SyscallDecoder::LoadArgument(Stage stage, int argument_index, size_t size) {
  if (decoded_arguments_[argument_index].loading(stage)) {
    return;
  }
  decoded_arguments_[argument_index].set_loading(stage);
  LoadMemory(ArgumentValue(argument_index), size,
             &decoded_arguments_[argument_index].loaded_values(stage));
}

void SyscallDecoder::LoadBuffer(Stage stage, uint64_t address, size_t size) {
  if (address == 0) {
    return;
  }
  SyscallDecoderBuffer& buffer = buffers_[std::make_pair(stage, address)];
  if (buffer.loading()) {
    return;
  }
  buffer.set_loading();
  LoadMemory(address, size, &buffer.loaded_values());
}

void SyscallDecoder::Decode() {
  zxdb::Thread* thread = weak_thread_.get();
  if (aborted_ || (thread == nullptr) || (thread->GetStack().size() == 0)) {
    aborted_ = true;
    Destroy();
    return;
  }
  if (dispatcher_->decode_options().stack_level >= kFullStack) {
    thread->GetStack().SyncFrames([this](const zxdb::Err& /*err*/) { DoDecode(); });
  } else {
    DoDecode();
  }
}

void SyscallDecoder::DoDecode() {
  zxdb::Thread* thread = weak_thread_.get();
  if (aborted_ || (thread == nullptr) || (thread->GetStack().size() == 0)) {
    aborted_ = true;
    Destroy();
    return;
  }
  const zxdb::Stack& stack = thread->GetStack();
  // Don't keep the inner frame which is the syscall and is not useful.
  for (size_t i = stack.size() - 1; i > 0; --i) {
    const zxdb::Frame* caller = stack[i];
    caller_locations_.push_back(caller->GetLocation());
  }
  const std::vector<debug_ipc::Register>* general_registers =
      thread->GetStack()[0]->GetRegisterCategorySync(debug_ipc::RegisterCategory::kGeneral);
  FX_DCHECK(general_registers);  // General registers should always be available synchronously.

  // The order of parameters in the System V AMD64 ABI we use, according to
  // Wikipedia:
  static std::vector<debug_ipc::RegisterID> amd64_abi = {
      debug_ipc::RegisterID::kX64_rdi, debug_ipc::RegisterID::kX64_rsi,
      debug_ipc::RegisterID::kX64_rdx, debug_ipc::RegisterID::kX64_rcx,
      debug_ipc::RegisterID::kX64_r8,  debug_ipc::RegisterID::kX64_r9};

  // The order of parameters in the System V AArch64 ABI we use, according to
  // Wikipedia:
  static std::vector<debug_ipc::RegisterID> aarch64_abi = {
      debug_ipc::RegisterID::kARMv8_x0, debug_ipc::RegisterID::kARMv8_x1,
      debug_ipc::RegisterID::kARMv8_x2, debug_ipc::RegisterID::kARMv8_x3,
      debug_ipc::RegisterID::kARMv8_x4, debug_ipc::RegisterID::kARMv8_x5,
      debug_ipc::RegisterID::kARMv8_x6, debug_ipc::RegisterID::kARMv8_x7};

  const std::vector<debug_ipc::RegisterID>* abi;
  if (arch_ == debug_ipc::Arch::kX64) {
    abi = &amd64_abi;
    entry_sp_ = GetRegisterValue(*general_registers, debug_ipc::RegisterID::kX64_rsp);
  } else if (arch_ == debug_ipc::Arch::kArm64) {
    abi = &aarch64_abi;
    entry_sp_ = GetRegisterValue(*general_registers, debug_ipc::RegisterID::kARMv8_sp);
    return_address_ = GetRegisterValue(*general_registers, debug_ipc::RegisterID::kARMv8_lr);
  } else {
    Error(DecoderError::Type::kUnknownArchitecture) << "Unknown architecture";
    if (pending_request_count_ == 0) {
      use_->SyscallDecodingError(error_, this);
    }
    return;
  }

  size_t argument_count = syscall_->arguments().size();
  decoded_arguments_.reserve(argument_count);
  size_t register_count = std::min(argument_count, abi->size());
  for (size_t i = 0; i < register_count; i++) {
    decoded_arguments_.emplace_back(GetRegisterValue(*general_registers, (*abi)[i]));
  }

  LoadStack();
}

void SyscallDecoder::LoadStack() {
  zxdb::Thread* thread = weak_thread_.get();
  if (aborted_ || (thread == nullptr) || (thread->GetStack().size() == 0)) {
    aborted_ = true;
    Destroy();
    return;
  }
  size_t stack_size = (syscall_->arguments().size() - decoded_arguments_.size()) * sizeof(uint64_t);
  if (arch_ == debug_ipc::Arch::kX64) {
    stack_size += sizeof(uint64_t);
  }
  if (stack_size == 0) {
    LoadInputs();
    return;
  }
  uint64_t address = entry_sp_;
  ++pending_request_count_;
  thread->GetProcess()->ReadMemory(
      address, stack_size,
      [this, address, stack_size](const zxdb::Err& err, zxdb::MemoryDump dump) {
        --pending_request_count_;
        if (aborted()) {
          Destroy();
        } else {
          if (!err.ok()) {
            Error(DecoderError::Type::kCantReadMemory)
                << "Can't load stack at " << address << '/' << stack_size << ": " << err.msg();
          } else if ((dump.size() != stack_size) || !dump.AllValid()) {
            Error(DecoderError::Type::kCantReadMemory)
                << "Can't load stack at " << address << '/' << stack_size << ": not enough data";
          } else {
            std::vector<uint8_t> data;
            MemoryDumpToVector(dump, &data);
            size_t offset = 0;
            if (arch_ == debug_ipc::Arch::kX64) {
              return_address_ = GetValueFromBytes<uint64_t>(data, 0);
              offset += sizeof(uint64_t);
            }
            while (offset < data.size()) {
              decoded_arguments_.emplace_back(GetValueFromBytes<uint64_t>(data, offset));
              offset += sizeof(uint64_t);
            }
          }
          LoadInputs();
        }
      });
}

void SyscallDecoder::LoadInputs() {
  if (error_.type() != DecoderError::Type::kNone) {
    if (pending_request_count_ == 0) {
      use_->SyscallDecodingError(error_, this);
    }
    return;
  }
  for (const auto& input : syscall_->inputs()) {
    if (input->ConditionsAreTrue(this, Stage::kEntry)) {
      input->Load(this, Stage::kEntry);
    }
  }
  if (pending_request_count_ > 0) {
    return;
  }
  input_arguments_loaded_ = true;
  if (error_.type() != DecoderError::Type::kNone) {
    use_->SyscallDecodingError(error_, this);
  } else {
    if (StepToReturnAddress()) {
      DecodeInputs();
    }
  }
}

bool SyscallDecoder::StepToReturnAddress() {
  zxdb::Thread* thread = weak_thread_.get();
  if (aborted_ || (thread == nullptr) || (thread->GetStack().size() == 0)) {
    aborted_ = true;
    Destroy();
    return false;
  }

  if (syscall_->return_type() != SyscallReturnType::kNoReturn) {
    thread_observer_->Register(fidlcat_thread()->koid(), this);
    thread_observer_->AddExitBreakpoint(thread, syscall_->name(), return_address_);
  }

  // Restarts the stopped thread. When the breakpoint will be reached (at the
  // end of the syscall), LoadSyscallReturnValue will be called.
  thread->Continue(false);
  return true;
}

void SyscallDecoder::DecodeInputs() {
  if (syscall_->fidl_codec_values_ready()) {
    // We are able to create values from the syscall => create the values.
    //
    invoked_event_ = std::make_shared<InvokedEvent>(timestamp(), fidlcat_thread_, syscall_);
    auto inline_member = syscall_->input_inline_members().begin();
    auto outline_member = syscall_->input_outline_members().begin();
    for (const auto& input : syscall_->inputs()) {
      if (input->InlineValue()) {
        if (input->ConditionsAreTrue(this, Stage::kEntry)) {
          FX_DCHECK(inline_member != syscall_->input_inline_members().end());
          std::unique_ptr<fidl_codec::Value> value = input->GenerateValue(this, Stage::kEntry);
          FX_DCHECK(value != nullptr);
          invoked_event_->AddInlineField(inline_member->get(), std::move(value));
        }
        ++inline_member;
      } else {
        if (input->ConditionsAreTrue(this, Stage::kEntry)) {
          FX_DCHECK(outline_member != syscall_->input_outline_members().end());
          std::unique_ptr<fidl_codec::Value> value = input->GenerateValue(this, Stage::kEntry);
          FX_DCHECK(value != nullptr);
          invoked_event_->AddOutlineField(outline_member->get(), std::move(value));
        }
        ++outline_member;
      }
    }
    if (dispatcher_->needs_stack_frame()) {
      CopyStackFrame(caller_locations(), &invoked_event_->stack_frame());
    }
    if (invoked_event_->NeedsToLoadHandleInfo(&dispatcher_->inference())) {
      fidlcat_thread_->process()->LoadHandleInfo(&dispatcher_->inference());
    }
  }
  // Eventually calls the code before displaying the input (which may invalidate
  // the display).
  if ((syscall_->inputs_decoded_action() == nullptr) ||
      (dispatcher_->*(syscall_->inputs_decoded_action()))(timestamp(), this)) {
    if (invoked_event_ != nullptr) {
      // If we have been able to generate an invoked event, directly call the dispatcher.
      dispatcher_->AddInvokedEvent(invoked_event_);
    } else {
      // Invoked event is not yet available for this syscall.
      use_->SyscallInputsDecoded(this);
    }
  }

  if (syscall_->return_type() == SyscallReturnType::kNoReturn) {
    // We already called Continue in StepToReturnAddress. We don't want to call it twice. We set
    // aborted_ to avoid that.
    aborted_ = true;
    // We don't expect the syscall to return and it doesn't have any output. We can now destroy
    // the decoder.
    Destroy();
  }
}

void SyscallDecoder::LoadSyscallReturnValue() {
  zxdb::Thread* thread = weak_thread_.get();
  if (aborted_ || (thread == nullptr) || (thread->GetStack().size() == 0)) {
    aborted_ = true;
    Destroy();
    return;
  }
  const std::vector<debug_ipc::Register>* general_registers =
      thread->GetStack()[0]->GetRegisterCategorySync(debug_ipc::RegisterCategory::kGeneral);
  FX_DCHECK(general_registers);  // General registers should always be available synchronously.

  debug_ipc::RegisterID result_register = (arch_ == debug_ipc::Arch::kX64)
                                              ? debug_ipc::RegisterID::kX64_rax
                                              : debug_ipc::RegisterID::kARMv8_x0;
  syscall_return_value_ = GetRegisterValue(*general_registers, result_register);

  LoadOutputs();
}

void SyscallDecoder::LoadOutputs() {
  if (error_.type() != DecoderError::Type::kNone) {
    if (pending_request_count_ == 0) {
      use_->SyscallDecodingError(error_, this);
    }
    return;
  }
  for (const auto& output : syscall_->outputs()) {
    if ((output->error_code() == static_cast<zx_status_t>(syscall_return_value_)) &&
        output->ConditionsAreTrue(this, Stage::kExit)) {
      output->Load(this, Stage::kExit);
    }
  }
  if (pending_request_count_ > 0) {
    return;
  }
  if (error_.type() != DecoderError::Type::kNone) {
    use_->SyscallDecodingError(error_, this);
  } else {
    DecodeOutputs();
  }
}

void SyscallDecoder::DecodeOutputs() {
  if (pending_request_count_ > 0) {
    return;
  }
  if (syscall_->fidl_codec_values_ready()) {
    output_event_ = std::make_shared<OutputEvent>(timestamp(), fidlcat_thread_, syscall_,
                                                  syscall_return_value_, invoked_event_);
    auto inline_member = syscall_->output_inline_members().begin();
    auto outline_member = syscall_->output_outline_members().begin();
    for (const auto& output : syscall_->outputs()) {
      if (output->InlineValue()) {
        if ((output->error_code() == static_cast<zx_status_t>(syscall_return_value_)) &&
            (output->ConditionsAreTrue(this, Stage::kExit))) {
          FX_DCHECK(inline_member != syscall_->output_inline_members().end());
          std::unique_ptr<fidl_codec::Value> value = output->GenerateValue(this, Stage::kExit);
          FX_DCHECK(value != nullptr);
          output_event_->AddInlineField(inline_member->get(), std::move(value));
        }
        ++inline_member;
      } else {
        if ((output->error_code() == static_cast<zx_status_t>(syscall_return_value_)) &&
            (output->ConditionsAreTrue(this, Stage::kExit))) {
          FX_DCHECK(outline_member != syscall_->output_outline_members().end());
          std::unique_ptr<fidl_codec::Value> value = output->GenerateValue(this, Stage::kExit);
          FX_DCHECK(value != nullptr);
          output_event_->AddOutlineField(outline_member->get(), std::move(value));
        }
        ++outline_member;
      }
    }
    if (output_event_->NeedsToLoadHandleInfo(&dispatcher_->inference())) {
      fidlcat_thread_->process()->LoadHandleInfo(&dispatcher_->inference());
    }
  }
  if (output_event_ != nullptr) {
    if (syscall_->inference() != nullptr) {
      // Executes the inference associated with the syscall.
      // This is used to infer semantic about handles.
      (dispatcher_->*(syscall_->inference()))(output_event_.get(), semantic());
    }

    // If we have been able to generate an invoked event, directly call the dispatcher.
    dispatcher_->AddOutputEvent(output_event_);
  } else {
    // Output event is not yet available for this syscall.
    use_->SyscallOutputsDecoded(this);
  }

  // Now our job is done, we can destroy the object.
  Destroy();
}

void SyscallDecoder::Destroy() {
  if (pending_request_count_ == 0) {
    dispatcher_->DeleteDecoder(this);
  }
}

void SyscallDisplay::SyscallInputsDecoded(SyscallDecoder* decoder) {
  if (!dispatcher_->display_started()) {
    // The display is not started. Only events can trigger it. We don't have an event so, we have
    // nothing to display.
    return;
  }
  displayed_ = true;
  if (dispatcher_->decode_options().output_mode == OutputMode::kStandard) {
    DisplayInputs(decoder);
  }
}

void SyscallDisplay::DisplayInputs(SyscallDecoder* decoder) {
  // This code will be deleted when we will be able to generate events for all the syscalls.
  const fidl_codec::Colors& colors = dispatcher_->colors();
  std::string line_header =
      colors.green + std::to_string(dispatcher_->GetTime(decoder->timestamp())) + colors.reset +
      ' ' + decoder->fidlcat_thread()->process()->name() + ' ' + colors.red +
      std::to_string(decoder->fidlcat_thread()->process()->koid()) + colors.reset + ':' +
      colors.red + std::to_string(decoder->fidlcat_thread()->koid()) + colors.reset + ' ';
  if (dispatcher_->with_process_info()) {
    os_ << line_header;
  }
  os_ << '\n';

  FidlcatPrinter printer(dispatcher_, decoder->fidlcat_thread()->process(), os_, line_header);

  if (dispatcher_->decode_options().stack_level != kNoStack) {
    // Display caller locations.
    DisplayStackFrame(decoder->caller_locations(), printer);
  }

  // Displays the header and the inline input arguments.
  printer << decoder->syscall()->name() << '(';
  const char* separator = "";
  for (const auto& input : decoder->syscall()->inputs()) {
    if (input->ConditionsAreTrue(decoder, Stage::kEntry)) {
      separator = input->DisplayInline(decoder, Stage::kEntry, separator, printer);
    }
  }
  printer << ")\n";

  {
    // Displays the outline input arguments.
    for (const auto& input : decoder->syscall()->inputs()) {
      if (input->ConditionsAreTrue(decoder, Stage::kEntry)) {
        input->DisplayOutline(decoder, Stage::kEntry, printer);
      }
    }
  }
  dispatcher_->set_last_displayed_syscall(this);
  dispatcher_->clear_last_displayed_event();
}

void SyscallDisplay::SyscallOutputsDecoded(SyscallDecoder* decoder) {
  // This code will be deleted when we will be able to generate events for all the syscalls.
  if (!displayed_ || (dispatcher_->decode_options().output_mode != OutputMode::kStandard)) {
    return;
  }
  if (decoder->syscall()->return_type() != SyscallReturnType::kNoReturn) {
    if (dispatcher_->last_displayed_syscall() != this) {
      // Add a blank line to tell the user that this display is not linked to the
      // previous displayed lines.
      os_ << "\n";
    }
    std::string line_header;
    const fidl_codec::Colors& colors = dispatcher_->colors();
    if (dispatcher_->with_process_info() || (dispatcher_->last_displayed_syscall() != this)) {
      line_header = colors.green + std::to_string(dispatcher_->GetTime(decoder->timestamp())) +
                    colors.reset + ' ' + decoder->fidlcat_thread()->process()->name() + ' ' +
                    colors.red + std::to_string(decoder->fidlcat_thread()->process()->koid()) +
                    colors.reset + ':' + colors.red +
                    std::to_string(decoder->fidlcat_thread()->koid()) + colors.reset + ' ';
    } else {
      line_header = colors.green + std::to_string(dispatcher_->GetTime(decoder->timestamp())) +
                    colors.reset + ' ';
    }
    FidlcatPrinter printer(dispatcher_, decoder->fidlcat_thread()->process(), os_, line_header);
    // Displays the returned value.
    printer << "  -> ";
    switch (decoder->syscall()->return_type()) {
      case SyscallReturnType::kNoReturn:
      case SyscallReturnType::kVoid:
        break;
      case SyscallReturnType::kStatus:
        printer.DisplayStatus(static_cast<zx_status_t>(decoder->syscall_return_value()));
        break;
      case SyscallReturnType::kTicks:
        printer << fidl_codec::Green << "ticks" << fidl_codec::ResetColor << ": "
                << fidl_codec::Blue << static_cast<uint64_t>(decoder->syscall_return_value())
                << fidl_codec::ResetColor;
        break;
      case SyscallReturnType::kTime:
        printer << fidl_codec::Green << "time" << fidl_codec::ResetColor << ": "
                << DisplayTime(static_cast<zx_time_t>(decoder->syscall_return_value()));
        break;
      case SyscallReturnType::kUint32:
        printer << fidl_codec::Blue << static_cast<uint32_t>(decoder->syscall_return_value())
                << fidl_codec::ResetColor;
        break;
      case SyscallReturnType::kUint64:
        printer << fidl_codec::Blue << static_cast<uint64_t>(decoder->syscall_return_value())
                << fidl_codec::ResetColor;
        break;
    }
    // And the inline output arguments (if any).
    const char* separator = " (";
    for (const auto& output : decoder->syscall()->outputs()) {
      if ((output->error_code() == static_cast<zx_status_t>(decoder->syscall_return_value())) &&
          output->ConditionsAreTrue(decoder, Stage::kExit)) {
        separator = output->DisplayInline(decoder, Stage::kExit, separator, printer);
      }
    }
    if (std::string(" (") != separator) {
      printer << ')';
    }
    printer << '\n';
    {
      fidl_codec::Indent indent(printer);
      // Displays the outline output arguments.
      for (const auto& output : decoder->syscall()->outputs()) {
        if ((output->error_code() == static_cast<zx_status_t>(decoder->syscall_return_value())) &&
            output->ConditionsAreTrue(decoder, Stage::kExit)) {
          output->DisplayOutline(decoder, Stage::kExit, printer);
        }
      }
    }

    dispatcher_->set_last_displayed_syscall(this);
    dispatcher_->clear_last_displayed_event();
  }
}

void SyscallDisplay::SyscallDecodingError(const DecoderError& error, SyscallDecoder* decoder) {
  std::string message = error.message();
  size_t pos = 0;
  for (;;) {
    size_t end = message.find('\n', pos);
    const fidl_codec::Colors& colors = dispatcher_->colors();
    os_ << decoder->fidlcat_thread()->process()->name() << ' ' << colors.red
        << decoder->fidlcat_thread()->process()->koid() << colors.reset << ':' << colors.red
        << decoder->fidlcat_thread()->koid() << colors.reset << ' ' << decoder->syscall()->name()
        << ": " << colors.red << error.message().substr(pos, end) << colors.reset << '\n';
    if (end == std::string::npos) {
      break;
    }
    pos = end + 1;
  }
  os_ << '\n';
  decoder->Destroy();
}

void SyscallCompare::SyscallInputsDecoded(SyscallDecoder* decoder) {
  os_.clear();
  os_.str("");
  SyscallDisplay::SyscallInputsDecoded(decoder);
  comparator_->CompareInput(os_.str(), decoder->fidlcat_thread()->process()->name(),
                            decoder->fidlcat_thread()->process()->koid(),
                            decoder->fidlcat_thread()->koid());
}

void SyscallCompare::SyscallOutputsDecoded(SyscallDecoder* decoder) {
  os_.clear();
  os_.str("");
  SyscallDisplay::SyscallOutputsDecoded(decoder);
  if (decoder->syscall()->return_type() != SyscallReturnType::kNoReturn) {
    comparator_->CompareOutput(os_.str(), decoder->fidlcat_thread()->process()->name(),
                               decoder->fidlcat_thread()->process()->koid(),
                               decoder->fidlcat_thread()->koid());
  }
}

void SyscallCompare::SyscallDecodingError(const DecoderError& error, SyscallDecoder* decoder) {
  os_.clear();
  os_.str("");
  SyscallDisplay::SyscallDecodingError(error, decoder);
  comparator_->DecodingError(os_.str());
}

}  // namespace fidlcat
