// 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 "vm/allocation.h"
#include "vm/compiler/runtime_api.h"
#include "vm/datastream.h"
#include "vm/growable_array.h"
#include "vm/zone.h"

namespace dart {

#if defined(DART_PRECOMPILER)

class Dwarf;
class ElfWriteStream;
class Section;
class Segment;
class StringTable;
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 = 16 * KB;
  static constexpr uword kNoSectionStart = 0;

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

  Zone* zone() { return zone_; }
  const Dwarf* dwarf() const { return dwarf_; }
  Dwarf* dwarf() { return dwarf_; }

  // Returns the relocated address for the symbol with the given name or
  // kNoSectionStart if the symbol was not found.
  uword SymbolAddress(const char* name) const;

  // What the next memory offset for an appropriately aligned section would be.
  //
  // Only used by AssemblyImageWriter and BlobImageWriter methods.
  intptr_t NextMemoryOffset(intptr_t alignment) const;
  intptr_t AddText(const char* name, const uint8_t* bytes, intptr_t size);
  intptr_t AddROData(const char* name, const uint8_t* bytes, intptr_t size);
  void AddDebug(const char* name, const uint8_t* bytes, intptr_t size);

  // Adds a local symbol for the given offset and size in the "current" section,
  // that is, the section index for the symbol is for the next added section.
  void AddLocalSymbol(const char* name,
                      intptr_t type,
                      intptr_t offset,
                      intptr_t size);

  void Finalize();

 private:
  static constexpr const char* kBuildIdNoteName = ".note.gnu.build-id";

  static Section* CreateBSS(Zone* zone, Type type, intptr_t size);

  // Adds the section and also creates a PT_LOAD segment for the section if it
  // is an allocated section.
  //
  // For allocated sections, if symbol_name is provided, a symbol for the
  // section will be added to the dynamic table (if allocated) and static
  // table (if not stripped) during finalization.
  //
  // Returns the memory offset if the section is allocated.
  intptr_t AddSection(Section* section,
                      const char* name,
                      const char* symbol_name = nullptr);
  // Replaces [old_section] with [new_section] in all appropriate places. If the
  // section is allocated, the memory size of the section must be the same as
  // the original to ensure any already-calculated memory offsets are unchanged.
  void ReplaceSection(Section* old_section, Section* new_section);

  void AddStaticSymbol(const char* name,
                       intptr_t binding,
                       intptr_t type,
                       intptr_t section_index,
                       intptr_t address,
                       intptr_t size);
  void AddDynamicSymbol(const char* name,
                        intptr_t binding,
                        intptr_t type,
                        intptr_t section_index,
                        intptr_t address,
                        intptr_t size);

  Segment* LastLoadSegment() const;
  const Section* FindSectionForAddress(intptr_t address) const;
  Section* CreateBuildIdNote(const void* description_bytes,
                             intptr_t description_length);
  Section* GenerateFinalBuildId();

  void AddSectionSymbols();
  void FinalizeDwarfSections();
  void FinalizeProgramTable();
  void ComputeFileOffsets();

  void WriteHeader(ElfWriteStream* stream);
  void WriteSectionTable(ElfWriteStream* stream);
  void WriteProgramTable(ElfWriteStream* stream);
  void WriteSections(ElfWriteStream* stream);

  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_;

  // We always create a BSS section for all Elf files, though it may be NOBITS
  // if this is separate debugging information.
  Section* const bss_;

  // All our strings would fit in a single page. However, we use separate
  // .shstrtab and .dynstr to work around a bug in Android's strip utility.
  StringTable* const shstrtab_;
  StringTable* const dynstrtab_;
  SymbolTable* const dynsym_;

  // The static tables are lazily created when static symbols are added.
  StringTable* strtab_ = nullptr;
  SymbolTable* symtab_ = nullptr;

  // We always create a GNU build ID for all Elf files. In order to create
  // the appropriate offset to it in an InstructionsSection object, we create an
  // initial build ID section as a placeholder and then replace that section
  // during finalization once we have the information to calculate the real one.
  Section* build_id_;

  GrowableArray<Section*> sections_;
  GrowableArray<Segment*> segments_;
  intptr_t memory_offset_;
  intptr_t section_table_file_offset_ = -1;
  intptr_t section_table_file_size_ = -1;
  intptr_t program_table_file_offset_ = -1;
  intptr_t program_table_file_size_ = -1;
};

#endif  // DART_PRECOMPILER

}  // namespace dart

#endif  // RUNTIME_VM_ELF_H_
