// 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, 0);
  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
