// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <climits>
#include <cstddef>
#include <cstdint>
#ifdef __APPLE__
// TODO(dje): Private copy until available on osx.
#include <garnet/lib/debugger_utils/third_party/musl/include/elf.h>
#else
#include <elf.h>
#endif
#include <memory>
#include <string>

#include "byte_block.h"

namespace debugger_utils {

// 32+64 support, bi-endian, mmap support can come later when needed

#if UINT_MAX == ULONG_MAX

using ElfHeader = Elf32_Ehdr;
using ElfSegmentHeader = Elf32_Phdr;
using ElfSectionHeader = Elf32_Shdr;
using ElfRawSymbol = Elf32_Sym;

#else

using ElfHeader = Elf64_Ehdr;
using ElfSegmentHeader = Elf64_Phdr;
using ElfSectionHeader = Elf64_Shdr;
using ElfRawSymbol = Elf64_Sym;

#endif

enum class ElfError {
  OK = 0,
  IO,
  BADELF,
  NOMEM,
};

const char* ElfErrorName(ElfError er);

class ElfReader;

class ElfSectionContents {
 public:
  ~ElfSectionContents();

  // Return the size in bytes of the section.
  // TODO(dje): 32x64
  size_t GetSize() const { return header_.sh_size; }

  // Return the number of entries in the section, assuming the section is
  // one that has "entries". E.g., symbol sections have entries, text sections
  // do not. For sections that don't have "entries" zero is returned.
  size_t GetNumEntries() const;

  // Fetch symbol |entry_number|.
  // The section must have type SHT_SYMTAB or SHT_DYNSYM.
  // WARNING: Space for the result may be reused for each call.
  // [We don't byteswap today, but when we do that is how this will work.
  // Symbols are generally used to create internal symbol tables and thus
  // are generally discarded immediately after use.]
  const ElfRawSymbol& GetSymbolEntry(size_t entry_number);

  const ElfSectionHeader& header() const { return header_; }

  const void* contents() const { return contents_; }

 private:
  friend class ElfReader;

  // Takes ownership of |contents|.
  // TODO(dje): separate method for mmap
  ElfSectionContents(const ElfSectionHeader& header, void* contents);

  // A copy is made of the header to separate the lifetime of the section's
  // contents from Reader. We could just save the pieces we use/need but
  // this is simple enough and saves us from having to continually add more.
  // Note that while we don't byteswap today, ElfSectionHeader contains the
  // ready-to-use version.
  const ElfSectionHeader header_;
  void* contents_;
};

class ElfReader {
 public:
  static ElfError Create(const std::string& file_name,
                         std::shared_ptr<ByteBlock> byte_block,
                         uint32_t options, uint64_t base,
                         std::unique_ptr<ElfReader>* out);
  ~ElfReader();

  const std::string& file_name() const { return file_name_; }

  // Read the ELF header at offset |base| in |m|.
  // The header is written in to |hdr|.
  static bool ReadHeader(const ByteBlock& m, uint64_t base, ElfHeader* hdr);

  // Return true if |hdr| is a valid ELF header.
  static bool VerifyHeader(const ElfHeader* hdr);

  const ElfHeader& header() { return header_; }

  // Return the number of program segments.
  size_t GetNumSegments() const { return header_.e_phnum; }

  // Read the program segment headers in.
  // This is a no-op if they are already read in.
  // This must be called before any call to GetSegment().
  ElfError ReadSegmentHeaders();

  // Free space allocated by ReadSegmentHeaders();
  void FreeSegmentHeaders();

  // Return the program segment header of |segment_number|.
  // |segment_number| must be valid, and ReadSegmentHeaders() must have
  // already been called.
  const ElfSegmentHeader& GetSegmentHeader(size_t segment_number);

  // Return the number of sections.
  size_t GetNumSections() const { return header_.e_shnum; }

  // Read the section headers in.
  // This is a no-op if they are already read in.
  // This must be called before any call to GetSection().
  ElfError ReadSectionHeaders();

  // Free space allocated by ReadSectionHeaders();
  void FreeSectionHeaders();

  // Return the section header of |section_number|.
  // |section_number| must be valid, and ReadSectionHeaders() must have
  // already been called.
  const ElfSectionHeader& GetSectionHeader(size_t section_number);

  // Return the section header with type |type|, an SHT_* value.
  // Returns nullptr if not found.
  const ElfSectionHeader* GetSectionHeaderByType(unsigned type);

  // Fetch the contents of |sh|.
  // This version malloc's space for the section, reads the contents into
  // the buffer, and assigns it to SectionContents.
  ElfError GetSectionContents(
      const ElfSectionHeader& sh,
      std::unique_ptr<ElfSectionContents>* out_contents);

  // Maximum length in bytes of a build id.
  static constexpr size_t kMaxBuildIdSize = 64;

  // Store the build id, if present, in |buf|.
  // |buf_size| must be at least kMaxBuildIdSize * 2 + 1.
  // If a build id is not found |buf| is "" and OK is returned.
  // TODO(dje): As with other changes deferred for later,
  // one might consider using std::string here. Later.
  ElfError ReadBuildId(char* buf, size_t buf_size);

  // Read |length| bytes at |address| in the ELF object an store in |buffer|.
  // |address| is the offset from the beginning of the ELF object.
  bool Read(uint64_t address, void* buffer, size_t length) const;

 private:
  ElfReader(const std::string& file_name, std::shared_ptr<ByteBlock> byte_block,
            uint64_t base);

  // For debugging/informational purposes only.
  const std::string file_name_;

  // This is the API to read/write from wherever the ELF object lives.
  // It could be in process memory, or in a file, or wherever.
  const std::shared_ptr<ByteBlock> byte_block_;

  // The offset in |byte_block_| of the start of the ELF object.
  const uint64_t base_;

  ElfHeader header_;

  const ElfSegmentHeader* segment_headers_ = nullptr;
  const ElfSectionHeader* section_headers_ = nullptr;
};

}  // namespace debugger_utils
