// 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.

#ifndef V8_DIAGNOSTICS_EH_FRAME_H_
#define V8_DIAGNOSTICS_EH_FRAME_H_

#include "src/base/compiler-specific.h"
#include "src/base/memory.h"
#include "src/codegen/register-arch.h"
#include "src/common/globals.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

class CodeDesc;

class V8_EXPORT_PRIVATE EhFrameConstants final
    : public NON_EXPORTED_BASE(AllStatic) {
 public:
  enum class DwarfOpcodes : byte {
    kNop = 0x00,
    kAdvanceLoc1 = 0x02,
    kAdvanceLoc2 = 0x03,
    kAdvanceLoc4 = 0x04,
    kSameValue = 0x08,
    kDefCfa = 0x0c,
    kDefCfaRegister = 0x0d,
    kDefCfaOffset = 0x0e,
    kOffsetExtendedSf = 0x11,
  };

  enum DwarfEncodingSpecifiers : byte {
    kUData4 = 0x03,
    kSData4 = 0x0b,
    kPcRel = 0x10,
    kDataRel = 0x30,
    kOmit = 0xff,
  };

  static const int kLocationTag = 1;
  static const int kLocationMask = 0x3f;
  static const int kLocationMaskSize = 6;

  static const int kSavedRegisterTag = 2;
  static const int kSavedRegisterMask = 0x3f;
  static const int kSavedRegisterMaskSize = 6;

  static const int kFollowInitialRuleTag = 3;
  static const int kFollowInitialRuleMask = 0x3f;
  static const int kFollowInitialRuleMaskSize = 6;

  static const int kProcedureAddressOffsetInFde = 2 * kInt32Size;
  static const int kProcedureSizeOffsetInFde = 3 * kInt32Size;

  static const int kInitialStateOffsetInCie = 19;
  static const int kEhFrameTerminatorSize = 4;

  // Defined in eh-writer-<arch>.cc
  static const int kCodeAlignmentFactor;
  static const int kDataAlignmentFactor;

  static const int kFdeVersionSize = 1;
  static const int kFdeEncodingSpecifiersSize = 3;

  static const int kEhFrameHdrVersion = 1;
  static const int kEhFrameHdrSize = 20;
};

class V8_EXPORT_PRIVATE EhFrameWriter {
 public:
  explicit EhFrameWriter(Zone* zone);

  // The empty frame is a hack to trigger fp-based unwinding in Linux perf
  // compiled with libunwind support when processing DWARF-based call graphs.
  //
  // It is effectively a valid eh_frame_hdr with an empty look up table.
  //
  static void WriteEmptyEhFrame(std::ostream& stream);  // NOLINT

  // Write the CIE and FDE header. Call it before any other method.
  void Initialize();

  void AdvanceLocation(int pc_offset);

  // The <base_address> is the one to which all <offset>s in SaveRegisterToStack
  // directives are relative. It is given by <base_register> + <base_offset>.
  //
  // The <base_offset> must be positive or 0.
  //
  void SetBaseAddressRegister(Register base_register);
  void SetBaseAddressOffset(int base_offset);
  void IncreaseBaseAddressOffset(int base_delta) {
    SetBaseAddressOffset(base_offset_ + base_delta);
  }
  void SetBaseAddressRegisterAndOffset(Register base_register, int base_offset);

  // Register saved at location <base_address> + <offset>.
  // The <offset> must be a multiple of EhFrameConstants::kDataAlignment.
  void RecordRegisterSavedToStack(Register name, int offset) {
    RecordRegisterSavedToStack(RegisterToDwarfCode(name), offset);
  }

  // The register has not been modified from the previous frame.
  void RecordRegisterNotModified(Register name);

  // The register follows the rule defined in the CIE.
  void RecordRegisterFollowsInitialRule(Register name);

  void Finish(int code_size);

  // Remember to call Finish() before GetEhFrame().
  //
  // The EhFrameWriter instance owns the buffer pointed by
  // CodeDesc::unwinding_info, and must outlive any use of the CodeDesc.
  //
  void GetEhFrame(CodeDesc* desc);

  int last_pc_offset() const { return last_pc_offset_; }
  Register base_register() const { return base_register_; }
  int base_offset() const { return base_offset_; }

 private:
  enum class InternalState { kUndefined, kInitialized, kFinalized };

  static const uint32_t kInt32Placeholder = 0xdeadc0de;

  void WriteSLeb128(int32_t value);
  void WriteULeb128(uint32_t value);

  void WriteByte(byte value) { eh_frame_buffer_.push_back(value); }
  void WriteOpcode(EhFrameConstants::DwarfOpcodes opcode) {
    WriteByte(static_cast<byte>(opcode));
  }
  void WriteBytes(const byte* start, int size) {
    eh_frame_buffer_.insert(eh_frame_buffer_.end(), start, start + size);
  }
  void WriteInt16(uint16_t value) {
    WriteBytes(reinterpret_cast<const byte*>(&value), sizeof(value));
  }
  void WriteInt32(uint32_t value) {
    WriteBytes(reinterpret_cast<const byte*>(&value), sizeof(value));
  }
  void PatchInt32(int base_offset, uint32_t value) {
    DCHECK_EQ(
        base::ReadUnalignedValue<uint32_t>(
            reinterpret_cast<Address>(eh_frame_buffer_.data()) + base_offset),
        kInt32Placeholder);
    DCHECK_LT(base_offset + kInt32Size, eh_frame_offset());
    base::WriteUnalignedValue<uint32_t>(
        reinterpret_cast<Address>(eh_frame_buffer_.data()) + base_offset,
        value);
  }

  // Write the common information entry, which includes encoding specifiers,
  // alignment factors, the return address (pseudo) register code and the
  // directives to construct the initial state of the unwinding table.
  void WriteCie();

  // Write the header of the function data entry, containing a pointer to the
  // correspondent CIE and the position and size of the associated routine.
  void WriteFdeHeader();

  // Write the contents of the .eh_frame_hdr section, including encoding
  // specifiers and the routine => FDE lookup table.
  void WriteEhFrameHdr(int code_size);

  // Write nops until the size reaches a multiple of 8 bytes.
  void WritePaddingToAlignedSize(int unpadded_size);

  // Internal version that directly accepts a DWARF register code, needed for
  // handling pseudo-registers on some platforms.
  void RecordRegisterSavedToStack(int register_code, int offset);

  int GetProcedureAddressOffset() const {
    return fde_offset() + EhFrameConstants::kProcedureAddressOffsetInFde;
  }

  int GetProcedureSizeOffset() const {
    return fde_offset() + EhFrameConstants::kProcedureSizeOffsetInFde;
  }

  int eh_frame_offset() const {
    return static_cast<int>(eh_frame_buffer_.size());
  }

  int fde_offset() const { return cie_size_; }

  // Platform specific functions implemented in eh-frame-<arch>.cc

  static int RegisterToDwarfCode(Register name);

  // Write directives to build the initial state in the CIE.
  void WriteInitialStateInCie();

  // Write the return address (pseudo) register code.
  void WriteReturnAddressRegisterCode();

  int cie_size_;
  int last_pc_offset_;
  InternalState writer_state_;
  Register base_register_;
  int base_offset_;
  ZoneVector<byte> eh_frame_buffer_;

  DISALLOW_COPY_AND_ASSIGN(EhFrameWriter);
};

class V8_EXPORT_PRIVATE EhFrameIterator {
 public:
  EhFrameIterator(const byte* start, const byte* end)
      : start_(start), next_(start), end_(end) {
    DCHECK_LE(start, end);
  }

  void SkipCie() {
    DCHECK_EQ(next_, start_);
    next_ +=
        base::ReadUnalignedValue<uint32_t>(reinterpret_cast<Address>(next_)) +
        kInt32Size;
  }

  void SkipToFdeDirectives() {
    SkipCie();
    // Skip the FDE header.
    Skip(kDirectivesOffsetInFde);
  }

  void Skip(int how_many) {
    DCHECK_GE(how_many, 0);
    next_ += how_many;
    DCHECK_LE(next_, end_);
  }

  uint32_t GetNextUInt32() { return GetNextValue<uint32_t>(); }
  uint16_t GetNextUInt16() { return GetNextValue<uint16_t>(); }
  byte GetNextByte() { return GetNextValue<byte>(); }
  EhFrameConstants::DwarfOpcodes GetNextOpcode() {
    return static_cast<EhFrameConstants::DwarfOpcodes>(GetNextByte());
  }

  uint32_t GetNextULeb128();
  int32_t GetNextSLeb128();

  bool Done() const {
    DCHECK_LE(next_, end_);
    return next_ == end_;
  }

  int GetCurrentOffset() const {
    DCHECK_GE(next_, start_);
    return static_cast<int>(next_ - start_);
  }

  int GetBufferSize() { return static_cast<int>(end_ - start_); }

  const void* current_address() const {
    return reinterpret_cast<const void*>(next_);
  }

 private:
  static const int kDirectivesOffsetInFde = 4 * kInt32Size + 1;

  static uint32_t DecodeULeb128(const byte* encoded, int* encoded_size);
  static int32_t DecodeSLeb128(const byte* encoded, int* encoded_size);

  template <typename T>
  T GetNextValue() {
    T result;
    DCHECK_LE(next_ + sizeof(result), end_);
    result = base::ReadUnalignedValue<T>(reinterpret_cast<Address>(next_));
    next_ += sizeof(result);
    return result;
  }

  const byte* start_;
  const byte* next_;
  const byte* end_;
};

#ifdef ENABLE_DISASSEMBLER

class EhFrameDisassembler final {
 public:
  EhFrameDisassembler(const byte* start, const byte* end)
      : start_(start), end_(end) {
    DCHECK_LT(start, end);
  }

  void DisassembleToStream(std::ostream& stream);  // NOLINT

 private:
  static void DumpDwarfDirectives(std::ostream& stream,  // NOLINT
                                  const byte* start, const byte* end);

  static const char* DwarfRegisterCodeToString(int code);

  const byte* start_;
  const byte* end_;

  DISALLOW_COPY_AND_ASSIGN(EhFrameDisassembler);
};

#endif

}  // namespace internal
}  // namespace v8

#endif  // V8_DIAGNOSTICS_EH_FRAME_H_
