// 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 <zircon/system/public/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 "src/lib/fxl/logging.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()) {
    FXL_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) {
  FXL_LOG(ERROR) << error.message();
  decoder->Destroy();
}

void SyscallDecoder::DisplayHandle(const zx_handle_info_t& handle_info,
                                   const fidl_codec::Colors& colors, std::ostream& os) {
  fidl_codec::DisplayHandle(colors, handle_info, os);
  const fidl_codec::semantic::HandleDescription* known_handle =
      dispatcher_->inference().GetHandleDescription(process_id_, handle_info.handle);
  if (known_handle != nullptr) {
    os << '(';
    known_handle->Display(colors, os);
    os << ')';
  }
}

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);
  FXL_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(thread_id(), 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();
  return true;
}

void SyscallDecoder::DecodeInputs() {
  if (syscall_->fidl_codec_values_ready()) {
    // We are able to create values from the syscall => create the values.
    //
    // The long term goal is that zxdb gives the timestamp. Currently we only create one when we
    // print the syscall.
    int64_t timestamp = time(nullptr);
    const Thread* thread = dispatcher_->SearchThread(thread_id_);
    if (thread == nullptr) {
      const Process* process = dispatcher_->SearchProcess(process_id_);
      if (process == nullptr) {
        process = dispatcher_->CreateProcess(process_name_, process_id_);
      }
      thread = dispatcher_->CreateThread(thread_id_, process);
    }
    invoked_event_ = std::make_unique<InvokedEvent>(timestamp << 32, 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)) {
          FXL_DCHECK(inline_member != syscall_->input_inline_members().end());
          std::unique_ptr<fidl_codec::Value> value = input->GenerateValue(this, Stage::kEntry);
          FXL_DCHECK(value != nullptr);
          invoked_event_->AddInlineField(inline_member->get(), std::move(value));
        }
        ++inline_member;
      } else {
        if (input->ConditionsAreTrue(this, Stage::kEntry)) {
          FXL_DCHECK(outline_member != syscall_->input_outline_members().end());
          std::unique_ptr<fidl_codec::Value> value = input->GenerateValue(this, Stage::kEntry);
          FXL_DCHECK(value != nullptr);
          invoked_event_->AddOutlineField(outline_member->get(), std::move(value));
        }
        ++outline_member;
      }
    }
  }
  UseInputs();
}

void SyscallDecoder::UseInputs() {
  // Eventually calls the code before displaying the input (which may invalidate
  // the display).
  if ((syscall_->inputs_decoded_action() == nullptr) ||
      (dispatcher_->*(syscall_->inputs_decoded_action()))(this)) {
    use_->SyscallInputsDecoded(this);
  }

  if (syscall_->return_type() == SyscallReturnType::kNoReturn) {
    // We don't expect the syscall to return and it doesn't have any output.
    use_->SyscallOutputsDecoded(this);
  }
}

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);
  FXL_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()) {
    // We are able to create values from the syscall => create the values.
    //
    // The long term goal is that zxdb gives the timestamp. Currently we only create one when we
    // print the syscall.
    int64_t timestamp = time(nullptr);
    const Thread* thread = dispatcher_->SearchThread(thread_id_);
    if (thread == nullptr) {
      const Process* process = dispatcher_->SearchProcess(process_id_);
      if (process == nullptr) {
        process = dispatcher_->CreateProcess(process_name_, process_id_);
      }
      thread = dispatcher_->CreateThread(thread_id_, process);
    }
    output_event_ =
        std::make_unique<OutputEvent>(timestamp << 32, thread, syscall_, syscall_return_value_);
    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))) {
          FXL_DCHECK(inline_member != syscall_->output_inline_members().end());
          std::unique_ptr<fidl_codec::Value> value = output->GenerateValue(this, Stage::kExit);
          FXL_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))) {
          FXL_DCHECK(outline_member != syscall_->output_outline_members().end());
          std::unique_ptr<fidl_codec::Value> value = output->GenerateValue(this, Stage::kExit);
          FXL_DCHECK(value != nullptr);
          output_event_->AddOutlineField(outline_member->get(), std::move(value));
        }
        ++outline_member;
      }
    }
  }
  UseOutputs();
}

void SyscallDecoder::UseOutputs() {
  use_->SyscallOutputsDecoded(this);

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

void SyscallDecoder::Destroy() {
  if (pending_request_count_ == 0) {
    if (syscall_->displayed_action() != nullptr) {
      // Calls the action associated with the syscall. This is used to infer semantic about handles.
      (dispatcher_->*(syscall_->displayed_action()))(this);
    }

    dispatcher_->DeleteDecoder(this);
  }
}

void SyscallDisplay::SyscallInputsDecoded(SyscallDecoder* decoder) {
  const fidl_codec::Colors& colors = dispatcher_->colors();
  line_header_ = decoder->process_name() + ' ' + colors.red +
                 std::to_string(decoder->process_id()) + colors.reset + ':' + colors.red +
                 std::to_string(decoder->thread_id()) + colors.reset + ' ';

  if (dispatcher_->with_process_info()) {
    os_ << line_header_ << '\n';
  } else {
    os_ << '\n';
  }

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

  const InvokedEvent* invoked_event = decoder->invoked_event();
  if (invoked_event != nullptr) {
    // We have been able to create values from the syscall => print them.
    const fidl_codec::Colors& colors = dispatcher_->colors();
    std::string line_header = invoked_event->thread()->process()->name() + ' ' + colors.red +
                              std::to_string(invoked_event->thread()->process()->koid()) +
                              colors.reset + ':' + colors.red +
                              std::to_string(invoked_event->thread()->koid()) + colors.reset + ' ';
    FidlcatPrinter printer(decoder, dispatcher_->dump_messages(),
                           dispatcher_->message_decoder_dispatcher().display_options().pretty_print,
                           os_, dispatcher_->colors(), line_header, dispatcher_->columns(),
                           dispatcher_->with_process_info());
    invoked_event->PrettyPrint(printer);

    if (!dispatcher_->with_process_info()) {
      line_header_ = "";
    }
  } else {
    // This code will be deleted when we will be able to have the two step printing for all the
    // syscalls.
    //
    // Displays the header and the inline input arguments.
    os_ << line_header_ << decoder->syscall()->name() << '(';
    const char* separator = "";
    for (const auto& input : decoder->syscall()->inputs()) {
      if (input->ConditionsAreTrue(decoder, Stage::kEntry)) {
        separator = input->DisplayInline(dispatcher_, decoder, Stage::kEntry, separator, os_);
      }
    }
    os_ << ")\n";

    if (!dispatcher_->with_process_info()) {
      line_header_ = "";
    }

    // Displays the outline input arguments.
    for (const auto& input : decoder->syscall()->inputs()) {
      if (input->ConditionsAreTrue(decoder, Stage::kEntry)) {
        input->DisplayOutline(dispatcher_, decoder, Stage::kEntry, line_header_, /*tabs=*/1, os_);
      }
    }
  }
  dispatcher_->set_last_displayed_syscall(this);
}

void SyscallDisplay::SyscallOutputsDecoded(SyscallDecoder* decoder) {
  if (decoder->syscall()->return_type() != SyscallReturnType::kNoReturn) {
    const fidl_codec::Colors& colors = dispatcher_->colors();
    const OutputEvent* output_event = decoder->output_event();
    if (output_event != nullptr) {
      // We have been able to create values from the syscall => print them.
      std::string line_header;
      if (dispatcher_->with_process_info() || (dispatcher_->last_displayed_syscall() != this)) {
        line_header = output_event->thread()->process()->name() + ' ' + colors.red +
                      std::to_string(output_event->thread()->process()->koid()) + colors.reset +
                      ':' + colors.red + std::to_string(output_event->thread()->koid()) +
                      colors.reset + ' ';
      }
      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";
      }
      FidlcatPrinter printer(
          decoder, dispatcher_->dump_messages(),
          dispatcher_->message_decoder_dispatcher().display_options().pretty_print, os_,
          dispatcher_->colors(), line_header, dispatcher_->columns(),
          dispatcher_->with_process_info());
      output_event->PrettyPrint(printer);
    } else {
      // This code will be deleted when we will be able to have the two step printing for all the
      // syscalls.
      //
      // Displays the returned value.
      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";
        // Then always display the process info to be able able to know for which thread
        // we are displaying the output.
        std::string first_line_header = decoder->process_name() + ' ' + colors.red +
                                        std::to_string(decoder->process_id()) + colors.reset + ':' +
                                        colors.red + std::to_string(decoder->thread_id()) +
                                        colors.reset + ' ';
        os_ << first_line_header << "  -> ";
      } else {
        os_ << line_header_ << "  -> ";
      }
      switch (decoder->syscall()->return_type()) {
        case SyscallReturnType::kNoReturn:
        case SyscallReturnType::kVoid:
          break;
        case SyscallReturnType::kStatus:
          StatusName(colors, static_cast<zx_status_t>(decoder->syscall_return_value()), os_);
          break;
        case SyscallReturnType::kTicks:
          os_ << colors.green << "ticks" << colors.reset << ": " << colors.blue
              << static_cast<uint64_t>(decoder->syscall_return_value()) << colors.reset;
          break;
        case SyscallReturnType::kTime:
          os_ << colors.green << "time" << colors.reset << ": "
              << DisplayTime(colors, static_cast<zx_time_t>(decoder->syscall_return_value()));
          break;
        case SyscallReturnType::kUint32:
          os_ << colors.blue << static_cast<uint32_t>(decoder->syscall_return_value())
              << colors.reset;
          break;
        case SyscallReturnType::kUint64:
          os_ << colors.blue << static_cast<uint64_t>(decoder->syscall_return_value())
              << colors.reset;
          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(dispatcher_, decoder, Stage::kExit, separator, os_);
        }
      }
      if (std::string(" (") != separator) {
        os_ << ')';
      }
      os_ << '\n';
      // 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(dispatcher_, decoder, Stage::kExit, line_header_, /*tabs=*/2, os_);
        }
      }
    }

    dispatcher_->set_last_displayed_syscall(this);
  }
}

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->process_name() << ' ' << colors.red << decoder->process_id() << colors.reset
        << ':' << colors.red << decoder->thread_id() << 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->process_name(), decoder->process_id(),
                            decoder->thread_id());
}

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

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

}  // namespace fidlcat
