// 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_EH_FRAME_H_
#define V8_EH_FRAME_H_

#include "src/base/compiler-specific.h"
#include "src/globals.h"
#include "src/macro-assembler.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {

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(ReadUnalignedUInt32(eh_frame_buffer_.data() + base_offset),
              kInt32Placeholder);
    DCHECK_LT(base_offset + kInt32Size, eh_frame_offset());
    WriteUnalignedUInt32(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_ += ReadUnalignedUInt32(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 = ReadUnalignedValue<T>(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
