// Copyright 2016 the V8 project 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 "src/eh-frame.h"

#include <iomanip>
#include <ostream>

#if !defined(V8_TARGET_ARCH_X64) && !defined(V8_TARGET_ARCH_ARM) && \
    !defined(V8_TARGET_ARCH_ARM64)

// Placeholders for unsupported architectures.

namespace v8 {
namespace internal {

const int EhFrameConstants::kCodeAlignmentFactor = 1;
const int EhFrameConstants::kDataAlignmentFactor = 1;

void EhFrameWriter::WriteReturnAddressRegisterCode() { UNIMPLEMENTED(); }

void EhFrameWriter::WriteInitialStateInCie() { UNIMPLEMENTED(); }

int EhFrameWriter::RegisterToDwarfCode(Register) {
  UNIMPLEMENTED();
  return -1;
}

#ifdef ENABLE_DISASSEMBLER

const char* EhFrameDisassembler::DwarfRegisterCodeToString(int) {
  UNIMPLEMENTED();
  return nullptr;
}

#endif

}  // namespace internal
}  // namespace v8

#endif

namespace v8 {
namespace internal {

STATIC_CONST_MEMBER_DEFINITION const int
    EhFrameConstants::kEhFrameTerminatorSize;
STATIC_CONST_MEMBER_DEFINITION const int EhFrameConstants::kEhFrameHdrVersion;
STATIC_CONST_MEMBER_DEFINITION const int EhFrameConstants::kEhFrameHdrSize;

STATIC_CONST_MEMBER_DEFINITION const uint32_t EhFrameWriter::kInt32Placeholder;

// static
void EhFrameWriter::WriteEmptyEhFrame(std::ostream& stream) {  // NOLINT
  stream.put(EhFrameConstants::kEhFrameHdrVersion);

  // .eh_frame pointer encoding specifier.
  stream.put(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel);

  // Lookup table size encoding.
  stream.put(EhFrameConstants::kUData4);

  // Lookup table entries encoding.
  stream.put(EhFrameConstants::kSData4 | EhFrameConstants::kDataRel);

  // Dummy pointers and 0 entries in the lookup table.
  char dummy_data[EhFrameConstants::kEhFrameHdrSize - 4] = {0};
  stream.write(&dummy_data[0], sizeof(dummy_data));
}

EhFrameWriter::EhFrameWriter(Zone* zone)
    : cie_size_(0),
      last_pc_offset_(0),
      writer_state_(InternalState::kUndefined),
      base_register_(no_reg),
      base_offset_(0),
      eh_frame_buffer_(zone) {}

void EhFrameWriter::Initialize() {
  DCHECK(writer_state_ == InternalState::kUndefined);
  eh_frame_buffer_.reserve(128);
  writer_state_ = InternalState::kInitialized;
  WriteCie();
  WriteFdeHeader();
}

void EhFrameWriter::WriteCie() {
  static const int kCIEIdentifier = 0;
  static const int kCIEVersion = 3;
  static const int kAugmentationDataSize = 2;
  static const byte kAugmentationString[] = {'z', 'L', 'R', 0};

  // Placeholder for the size of the CIE.
  int size_offset = eh_frame_offset();
  WriteInt32(kInt32Placeholder);

  // CIE identifier and version.
  int record_start_offset = eh_frame_offset();
  WriteInt32(kCIEIdentifier);
  WriteByte(kCIEVersion);

  // Augmentation data contents descriptor: LSDA and FDE encoding.
  WriteBytes(&kAugmentationString[0], sizeof(kAugmentationString));

  // Alignment factors.
  WriteSLeb128(EhFrameConstants::kCodeAlignmentFactor);
  WriteSLeb128(EhFrameConstants::kDataAlignmentFactor);

  WriteReturnAddressRegisterCode();

  // Augmentation data.
  WriteULeb128(kAugmentationDataSize);
  // No language-specific data area (LSDA).
  WriteByte(EhFrameConstants::kOmit);
  // FDE pointers encoding.
  WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel);

  // Write directives to build the initial state of the unwinding table.
  DCHECK_EQ(eh_frame_offset() - size_offset,
            EhFrameConstants::kInitialStateOffsetInCie);
  WriteInitialStateInCie();

  WritePaddingToAlignedSize(eh_frame_offset() - record_start_offset);

  int record_end_offset = eh_frame_offset();
  int encoded_cie_size = record_end_offset - record_start_offset;
  cie_size_ = record_end_offset - size_offset;

  // Patch the size of the CIE now that we know it.
  PatchInt32(size_offset, encoded_cie_size);
}

void EhFrameWriter::WriteFdeHeader() {
  DCHECK_NE(cie_size_, 0);

  // Placeholder for size of the FDE. Will be filled in Finish().
  DCHECK_EQ(eh_frame_offset(), fde_offset());
  WriteInt32(kInt32Placeholder);

  // Backwards offset to the CIE.
  WriteInt32(cie_size_ + kInt32Size);

  // Placeholder for pointer to procedure. Will be filled in Finish().
  DCHECK_EQ(eh_frame_offset(), GetProcedureAddressOffset());
  WriteInt32(kInt32Placeholder);

  // Placeholder for size of the procedure. Will be filled in Finish().
  DCHECK_EQ(eh_frame_offset(), GetProcedureSizeOffset());
  WriteInt32(kInt32Placeholder);

  // No augmentation data.
  WriteByte(0);
}

void EhFrameWriter::WriteEhFrameHdr(int code_size) {
  DCHECK(writer_state_ == InternalState::kInitialized);

  //
  // In order to calculate offsets in the .eh_frame_hdr, we must know the layout
  // of the DSO generated by perf inject, which is assumed to be the following:
  //
  //  |      ...      |                        |
  //  +---------------+ <-- (F) ---            |  Larger offsets in file
  //  |               |           ^            |
  //  |  Instructions |           | .text      v
  //  |               |           v
  //  +---------------+ <-- (E) ---
  //  |///////////////|
  //  |////Padding////|
  //  |///////////////|
  //  +---------------+ <-- (D) ---
  //  |               |           ^
  //  |      CIE      |           |
  //  |               |           |
  //  +---------------+ <-- (C)   |
  //  |               |           | .eh_frame
  //  |      FDE      |           |
  //  |               |           |
  //  +---------------+           |
  //  |   terminator  |           v
  //  +---------------+ <-- (B) ---
  //  |    version    |           ^
  //  +---------------+           |
  //  |   encoding    |           |
  //  |  specifiers   |           |
  //  +---------------+ <---(A)   | .eh_frame_hdr
  //  |   offset to   |           |
  //  |   .eh_frame   |           |
  //  +---------------+           |
  //  |      ...      |          ...
  //
  // (F) is aligned to a 16-byte boundary.
  // (D) is aligned to a  8-byte boundary.
  // (B) is aligned to a  4-byte boundary.
  // (C), (E) and (A) have no alignment requirements.
  //
  // The distance between (A) and (B) is 4 bytes.
  //
  // The size of the FDE is required to be a multiple of the pointer size, which
  // means that (B) will be naturally aligned to a 4-byte boundary on all the
  // architectures we support.
  //
  // Because (E) has no alignment requirements, there is padding between (E) and
  // (D). (F) is aligned at a 16-byte boundary, thus to a 8-byte one as well.
  //

  int eh_frame_size = eh_frame_offset();

  WriteByte(EhFrameConstants::kEhFrameHdrVersion);

  // .eh_frame pointer encoding specifier.
  WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kPcRel);
  // Lookup table size encoding specifier.
  WriteByte(EhFrameConstants::kUData4);
  // Lookup table entries encoding specifier.
  WriteByte(EhFrameConstants::kSData4 | EhFrameConstants::kDataRel);

  // Pointer to .eh_frame, relative to this offset (A -> D in the diagram).
  WriteInt32(-(eh_frame_size + EhFrameConstants::kFdeVersionSize +
               EhFrameConstants::kFdeEncodingSpecifiersSize));

  // Number of entries in the LUT, one for the only routine.
  WriteInt32(1);

  // Pointer to the start of the routine, relative to the beginning of the
  // .eh_frame_hdr (B -> F in the diagram).
  WriteInt32(-(RoundUp(code_size, 8) + eh_frame_size));

  // Pointer to the start of the associated FDE, relative to the start of the
  // .eh_frame_hdr (B -> C  in the diagram).
  WriteInt32(-(eh_frame_size - cie_size_));

  DCHECK_EQ(eh_frame_offset() - eh_frame_size,
            EhFrameConstants::kEhFrameHdrSize);
}

void EhFrameWriter::WritePaddingToAlignedSize(int unpadded_size) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_GE(unpadded_size, 0);

  int padding_size = RoundUp(unpadded_size, kPointerSize) - unpadded_size;

  byte nop = static_cast<byte>(EhFrameConstants::DwarfOpcodes::kNop);
  static const byte kPadding[] = {nop, nop, nop, nop, nop, nop, nop, nop};
  DCHECK_LE(padding_size, static_cast<int>(sizeof(kPadding)));
  WriteBytes(&kPadding[0], padding_size);
}

void EhFrameWriter::AdvanceLocation(int pc_offset) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_GE(pc_offset, last_pc_offset_);
  uint32_t delta = pc_offset - last_pc_offset_;

  DCHECK_EQ(delta % EhFrameConstants::kCodeAlignmentFactor, 0u);
  uint32_t factored_delta = delta / EhFrameConstants::kCodeAlignmentFactor;

  if (factored_delta <= EhFrameConstants::kLocationMask) {
    WriteByte((EhFrameConstants::kLocationTag
               << EhFrameConstants::kLocationMaskSize) |
              (factored_delta & EhFrameConstants::kLocationMask));
  } else if (factored_delta <= kMaxUInt8) {
    WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc1);
    WriteByte(factored_delta);
  } else if (factored_delta <= kMaxUInt16) {
    WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc2);
    WriteInt16(factored_delta);
  } else {
    WriteOpcode(EhFrameConstants::DwarfOpcodes::kAdvanceLoc4);
    WriteInt32(factored_delta);
  }

  last_pc_offset_ = pc_offset;
}

void EhFrameWriter::SetBaseAddressOffset(int base_offset) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_GE(base_offset, 0);
  WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfaOffset);
  WriteULeb128(base_offset);
  base_offset_ = base_offset;
}

void EhFrameWriter::SetBaseAddressRegister(Register base_register) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  int code = RegisterToDwarfCode(base_register);
  WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfaRegister);
  WriteULeb128(code);
  base_register_ = base_register;
}

void EhFrameWriter::SetBaseAddressRegisterAndOffset(Register base_register,
                                                    int base_offset) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_GE(base_offset, 0);
  int code = RegisterToDwarfCode(base_register);
  WriteOpcode(EhFrameConstants::DwarfOpcodes::kDefCfa);
  WriteULeb128(code);
  WriteULeb128(base_offset);
  base_offset_ = base_offset;
  base_register_ = base_register;
}

void EhFrameWriter::RecordRegisterSavedToStack(int register_code, int offset) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_EQ(offset % EhFrameConstants::kDataAlignmentFactor, 0);
  int factored_offset = offset / EhFrameConstants::kDataAlignmentFactor;
  if (factored_offset >= 0) {
    DCHECK_LE(register_code, EhFrameConstants::kSavedRegisterMask);
    WriteByte((EhFrameConstants::kSavedRegisterTag
               << EhFrameConstants::kSavedRegisterMaskSize) |
              (register_code & EhFrameConstants::kSavedRegisterMask));
    WriteULeb128(factored_offset);
  } else {
    WriteOpcode(EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf);
    WriteULeb128(register_code);
    WriteSLeb128(factored_offset);
  }
}

void EhFrameWriter::RecordRegisterNotModified(Register name) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  WriteOpcode(EhFrameConstants::DwarfOpcodes::kSameValue);
  WriteULeb128(RegisterToDwarfCode(name));
}

void EhFrameWriter::RecordRegisterFollowsInitialRule(Register name) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  int code = RegisterToDwarfCode(name);
  DCHECK_LE(code, EhFrameConstants::kFollowInitialRuleMask);
  WriteByte((EhFrameConstants::kFollowInitialRuleTag
             << EhFrameConstants::kFollowInitialRuleMaskSize) |
            (code & EhFrameConstants::kFollowInitialRuleMask));
}

void EhFrameWriter::Finish(int code_size) {
  DCHECK(writer_state_ == InternalState::kInitialized);
  DCHECK_GE(eh_frame_offset(), cie_size_);

  DCHECK_GE(eh_frame_offset(), fde_offset() + kInt32Size);
  WritePaddingToAlignedSize(eh_frame_offset() - fde_offset() - kInt32Size);

  // Write the size of the FDE now that we know it.
  // The encoded size does not include the size field itself.
  int encoded_fde_size = eh_frame_offset() - fde_offset() - kInt32Size;
  PatchInt32(fde_offset(), encoded_fde_size);

  // Write size and offset to procedure.
  PatchInt32(GetProcedureAddressOffset(),
             -(RoundUp(code_size, 8) + GetProcedureAddressOffset()));
  PatchInt32(GetProcedureSizeOffset(), code_size);

  // Terminate the .eh_frame.
  static const byte kTerminator[EhFrameConstants::kEhFrameTerminatorSize] = {0};
  WriteBytes(&kTerminator[0], EhFrameConstants::kEhFrameTerminatorSize);

  WriteEhFrameHdr(code_size);

  writer_state_ = InternalState::kFinalized;
}

void EhFrameWriter::GetEhFrame(CodeDesc* desc) {
  DCHECK(writer_state_ == InternalState::kFinalized);
  desc->unwinding_info_size = static_cast<int>(eh_frame_buffer_.size());
  desc->unwinding_info = eh_frame_buffer_.data();
}

void EhFrameWriter::WriteULeb128(uint32_t value) {
  do {
    byte chunk = value & 0x7f;
    value >>= 7;
    if (value != 0) chunk |= 0x80;
    WriteByte(chunk);
  } while (value != 0);
}

void EhFrameWriter::WriteSLeb128(int32_t value) {
  static const int kSignBitMask = 0x40;
  bool done;
  do {
    byte chunk = value & 0x7f;
    value >>= 7;
    done = ((value == 0) && ((chunk & kSignBitMask) == 0)) ||
           ((value == -1) && ((chunk & kSignBitMask) != 0));
    if (!done) chunk |= 0x80;
    WriteByte(chunk);
  } while (!done);
}

uint32_t EhFrameIterator::GetNextULeb128() {
  int size = 0;
  uint32_t result = DecodeULeb128(next_, &size);
  DCHECK_LE(next_ + size, end_);
  next_ += size;
  return result;
}

int32_t EhFrameIterator::GetNextSLeb128() {
  int size = 0;
  int32_t result = DecodeSLeb128(next_, &size);
  DCHECK_LE(next_ + size, end_);
  next_ += size;
  return result;
}

// static
uint32_t EhFrameIterator::DecodeULeb128(const byte* encoded,
                                        int* encoded_size) {
  const byte* current = encoded;
  uint32_t result = 0;
  int shift = 0;

  do {
    DCHECK_LT(shift, 8 * static_cast<int>(sizeof(result)));
    result |= (*current & 0x7f) << shift;
    shift += 7;
  } while (*current++ >= 128);

  DCHECK_NOT_NULL(encoded_size);
  *encoded_size = static_cast<int>(current - encoded);

  return result;
}

// static
int32_t EhFrameIterator::DecodeSLeb128(const byte* encoded, int* encoded_size) {
  static const byte kSignBitMask = 0x40;

  const byte* current = encoded;
  int32_t result = 0;
  int shift = 0;
  byte chunk;

  do {
    chunk = *current++;
    DCHECK_LT(shift, 8 * static_cast<int>(sizeof(result)));
    result |= (chunk & 0x7f) << shift;
    shift += 7;
  } while (chunk >= 128);

  // Sign extend the result if the last chunk has the sign bit set.
  if (chunk & kSignBitMask) result |= (~0ull) << shift;

  DCHECK_NOT_NULL(encoded_size);
  *encoded_size = static_cast<int>(current - encoded);

  return result;
}

#ifdef ENABLE_DISASSEMBLER

namespace {

class StreamModifiersScope final {
 public:
  explicit StreamModifiersScope(std::ostream* stream)
      : stream_(stream), flags_(stream->flags()) {}
  ~StreamModifiersScope() { stream_->flags(flags_); }

 private:
  std::ostream* stream_;
  std::ios::fmtflags flags_;
};

}  // namespace

// static
void EhFrameDisassembler::DumpDwarfDirectives(std::ostream& stream,  // NOLINT
                                              const byte* start,
                                              const byte* end) {
  StreamModifiersScope modifiers_scope(&stream);

  EhFrameIterator eh_frame_iterator(start, end);
  uint32_t offset_in_procedure = 0;

  while (!eh_frame_iterator.Done()) {
    stream << eh_frame_iterator.current_address() << "  ";

    byte bytecode = eh_frame_iterator.GetNextByte();

    if (((bytecode >> EhFrameConstants::kLocationMaskSize) & 0xff) ==
        EhFrameConstants::kLocationTag) {
      int value = (bytecode & EhFrameConstants::kLocationMask) *
                  EhFrameConstants::kCodeAlignmentFactor;
      offset_in_procedure += value;
      stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value
             << ")\n";
      continue;
    }

    if (((bytecode >> EhFrameConstants::kSavedRegisterMaskSize) & 0xff) ==
        EhFrameConstants::kSavedRegisterTag) {
      int32_t decoded_offset = eh_frame_iterator.GetNextULeb128();
      stream << "| " << DwarfRegisterCodeToString(
                            bytecode & EhFrameConstants::kLocationMask)
             << " saved at base" << std::showpos
             << decoded_offset * EhFrameConstants::kDataAlignmentFactor
             << std::noshowpos << '\n';
      continue;
    }

    if (((bytecode >> EhFrameConstants::kFollowInitialRuleMaskSize) & 0xff) ==
        EhFrameConstants::kFollowInitialRuleTag) {
      stream << "| " << DwarfRegisterCodeToString(
                            bytecode & EhFrameConstants::kLocationMask)
             << " follows rule in CIE\n";
      continue;
    }

    switch (static_cast<EhFrameConstants::DwarfOpcodes>(bytecode)) {
      case EhFrameConstants::DwarfOpcodes::kOffsetExtendedSf: {
        stream << "| "
               << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128());
        int32_t decoded_offset = eh_frame_iterator.GetNextSLeb128();
        stream << " saved at base" << std::showpos
               << decoded_offset * EhFrameConstants::kDataAlignmentFactor
               << std::noshowpos << '\n';
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kAdvanceLoc1: {
        int value = eh_frame_iterator.GetNextByte() *
                    EhFrameConstants::kCodeAlignmentFactor;
        offset_in_procedure += value;
        stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value
               << ")\n";
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kAdvanceLoc2: {
        int value = eh_frame_iterator.GetNextUInt16() *
                    EhFrameConstants::kCodeAlignmentFactor;
        offset_in_procedure += value;
        stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value
               << ")\n";
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kAdvanceLoc4: {
        int value = eh_frame_iterator.GetNextUInt32() *
                    EhFrameConstants::kCodeAlignmentFactor;
        offset_in_procedure += value;
        stream << "| pc_offset=" << offset_in_procedure << " (delta=" << value
               << ")\n";
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kDefCfa: {
        uint32_t base_register = eh_frame_iterator.GetNextULeb128();
        uint32_t base_offset = eh_frame_iterator.GetNextULeb128();
        stream << "| base_register=" << DwarfRegisterCodeToString(base_register)
               << ", base_offset=" << base_offset << '\n';
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kDefCfaOffset: {
        stream << "| base_offset=" << eh_frame_iterator.GetNextULeb128()
               << '\n';
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kDefCfaRegister: {
        stream << "| base_register="
               << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128())
               << '\n';
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kSameValue: {
        stream << "| "
               << DwarfRegisterCodeToString(eh_frame_iterator.GetNextULeb128())
               << " not modified from previous frame\n";
        break;
      }
      case EhFrameConstants::DwarfOpcodes::kNop:
        stream << "| nop\n";
        break;
      default:
        UNREACHABLE();
        return;
    }
  }
}

void EhFrameDisassembler::DisassembleToStream(std::ostream& stream) {  // NOLINT
  // The encoded CIE size does not include the size field itself.
  const int cie_size = ReadUnalignedUInt32(start_) + kInt32Size;
  const int fde_offset = cie_size;

  const byte* cie_directives_start =
      start_ + EhFrameConstants::kInitialStateOffsetInCie;
  const byte* cie_directives_end = start_ + cie_size;
  DCHECK_LE(cie_directives_start, cie_directives_end);

  stream << reinterpret_cast<const void*>(start_) << "  .eh_frame: CIE\n";
  DumpDwarfDirectives(stream, cie_directives_start, cie_directives_end);

  const byte* procedure_offset_address =
      start_ + fde_offset + EhFrameConstants::kProcedureAddressOffsetInFde;
  int32_t procedure_offset =
      ReadUnalignedValue<int32_t>(procedure_offset_address);

  const byte* procedure_size_address =
      start_ + fde_offset + EhFrameConstants::kProcedureSizeOffsetInFde;
  uint32_t procedure_size = ReadUnalignedUInt32(procedure_size_address);

  const byte* fde_start = start_ + fde_offset;
  stream << reinterpret_cast<const void*>(fde_start) << "  .eh_frame: FDE\n"
         << reinterpret_cast<const void*>(procedure_offset_address)
         << "  | procedure_offset=" << procedure_offset << '\n'
         << reinterpret_cast<const void*>(procedure_size_address)
         << "  | procedure_size=" << procedure_size << '\n';

  const int fde_directives_offset = fde_offset + 4 * kInt32Size + 1;

  const byte* fde_directives_start = start_ + fde_directives_offset;
  const byte* fde_directives_end = end_ - EhFrameConstants::kEhFrameHdrSize -
                                   EhFrameConstants::kEhFrameTerminatorSize;
  DCHECK_LE(fde_directives_start, fde_directives_end);

  DumpDwarfDirectives(stream, fde_directives_start, fde_directives_end);

  const byte* fde_terminator_start = fde_directives_end;
  stream << reinterpret_cast<const void*>(fde_terminator_start)
         << "  .eh_frame: terminator\n";

  const byte* eh_frame_hdr_start =
      fde_terminator_start + EhFrameConstants::kEhFrameTerminatorSize;
  stream << reinterpret_cast<const void*>(eh_frame_hdr_start)
         << "  .eh_frame_hdr\n";
}

#endif

}  // namespace internal
}  // namespace v8
