// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_ELF_H_
#define RUNTIME_VM_ELF_H_

#include "platform/globals.h"

#if defined(DART_PRECOMPILER)
#include "vm/allocation.h"
#include "vm/compiler/runtime_api.h"
#include "vm/datastream.h"
#include "vm/growable_array.h"
#include "vm/zone.h"
#endif

namespace dart {

// The max page size on all supported architectures. Used to determine
// the alignment of load segments, so that they are guaranteed page-aligned,
// and no ELF section or segment should have a larger alignment.
#if defined(DART_TARGET_OS_LINUX) && defined(TARGET_ARCH_ARM64)
// Some Linux distributions on ARM64 select 64 KB page size.
// Follow LLVM (https://reviews.llvm.org/D25079) and set maximum page size
// to 64 KB for ARM64 Linux builds.
static constexpr intptr_t kElfPageSize = 64 * KB;
#else
static constexpr intptr_t kElfPageSize = 16 * KB;
#endif

#if defined(DART_PRECOMPILER)

class Dwarf;
class ProgramTable;
class Section;
class SectionTable;
class SymbolTable;

class Elf : public ZoneAllocated {
 public:
  enum class Type {
    // A snapshot that should include segment contents.
    Snapshot,
    // Separately compiled debugging information that should not include
    // most segment contents.
    DebugInfo,
  };

  Elf(Zone* zone, BaseWriteStream* stream, Type type, Dwarf* dwarf = nullptr);

  static constexpr intptr_t kPageSize = kElfPageSize;

  bool IsStripped() const { return dwarf_ == nullptr; }

  Zone* zone() const { return zone_; }
  const Dwarf* dwarf() const { return dwarf_; }
  Dwarf* dwarf() { return dwarf_; }
  const SymbolTable& symtab() const {
    ASSERT(symtab_ != nullptr);
    return *symtab_;
  }
  const SectionTable& section_table() const { return *section_table_; }

  // Stores the information needed to appropriately generate a
  // relocation from the target to the source at the given section offset.
  struct Relocation {
    size_t size_in_bytes;
    intptr_t section_offset;
    intptr_t source_label;
    intptr_t source_offset;
    intptr_t target_label;
    intptr_t target_offset;

    // Used when the corresponding offset is relative from the location of the
    // relocation itself.
    static constexpr intptr_t kSelfRelative = -1;
    // Used when the corresponding offset is relative to the start of the
    // snapshot.
    static constexpr intptr_t kSnapshotRelative = -2;

    Relocation(size_t size_in_bytes,
               intptr_t section_offset,
               intptr_t source_label,
               intptr_t source_offset,
               intptr_t target_label,
               intptr_t target_offset)
        : size_in_bytes(size_in_bytes),
          section_offset(section_offset),
          source_label(source_label),
          source_offset(source_offset),
          target_label(target_label),
          target_offset(target_offset) {
      // Other than special values, all labels should be positive.
      ASSERT(source_label > 0 || source_label == kSelfRelative ||
             source_label == kSnapshotRelative);
      ASSERT(target_label > 0 || target_label == kSelfRelative ||
             target_label == kSnapshotRelative);
    }
  };

  // Stores the information needed to appropriately generate a symbol
  // during finalization.
  struct SymbolData {
    const char* name;
    intptr_t type;
    intptr_t offset;
    size_t size;
    // A positive unique ID only used internally in the Dart VM, not part of
    // the Elf output.
    intptr_t label;

    SymbolData(const char* name,
               intptr_t type,
               intptr_t offset,
               size_t size,
               intptr_t label)
        : name(name), type(type), offset(offset), size(size), label(label) {
      ASSERT(label > 0);
    }
  };

  // Must be the same value as the values returned by ImageWriter::SectionLabel
  // for the appropriate section and vm values.
  static constexpr intptr_t kVmBssLabel = 5;
  static constexpr intptr_t kIsolateBssLabel = 6;
  static constexpr intptr_t kBuildIdLabel = 7;

  void AddText(const char* name,
               intptr_t label,
               const uint8_t* bytes,
               intptr_t size,
               const ZoneGrowableArray<Relocation>* relocations,
               const ZoneGrowableArray<SymbolData>* symbol);
  void AddROData(const char* name,
                 intptr_t label,
                 const uint8_t* bytes,
                 intptr_t size,
                 const ZoneGrowableArray<Relocation>* relocations,
                 const ZoneGrowableArray<SymbolData>* symbols);

  void Finalize();

 private:
  static constexpr const char kBuildIdNoteName[] = ".note.gnu.build-id";
  static constexpr const char kTextName[] = ".text";
  static constexpr const char kDataName[] = ".rodata";
  static constexpr const char kBssName[] = ".bss";
  static constexpr const char kDynamicTableName[] = ".dynamic";

  void CreateBSS();
  void GenerateBuildId();
  void InitializeSymbolTables();
  void FinalizeDwarfSections();
  void FinalizeEhFrame();
  void ComputeOffsets();

  Zone* const zone_;
  BaseWriteStream* const unwrapped_stream_;
  const Type type_;

  // If nullptr, then the ELF file should be stripped of static information like
  // the static symbol table (and its corresponding string table).
  Dwarf* const dwarf_;

  // Contains all sections that will have entries in the section header table.
  SectionTable* const section_table_;

  // Contains all segments in the program header table. Set after finalizing
  // the section table.
  ProgramTable* program_table_ = nullptr;

  // The static tables are always created for use in relocation calculations,
  // even though they may not end up in the final ELF file.
  SymbolTable* symtab_ = nullptr;

  friend class SectionTable;  // For section name static fields.
};

#endif  // DART_PRECOMPILER

}  // namespace dart

#endif  // RUNTIME_VM_ELF_H_
