//===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
#define LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H

#include <cstdint>

#include <optional>
#include <vector>

#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/UUID.h"
#include "lldb/lldb-private.h"

#include "ELFHeader.h"

struct ELFNote {
  elf::elf_word n_namesz = 0;
  elf::elf_word n_descsz = 0;
  elf::elf_word n_type = 0;

  std::string n_name;

  ELFNote() = default;

  /// Parse an ELFNote entry from the given DataExtractor starting at position
  /// \p offset.
  ///
  /// \param[in] data
  ///    The DataExtractor to read from.
  ///
  /// \param[in,out] offset
  ///    Pointer to an offset in the data.  On return the offset will be
  ///    advanced by the number of bytes read.
  ///
  /// \return
  ///    True if the ELFRel entry was successfully read and false otherwise.
  bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);

  size_t GetByteSize() const {
    return 12 + llvm::alignTo(n_namesz, 4) + llvm::alignTo(n_descsz, 4);
  }
};

/// \class ObjectFileELF
/// Generic ELF object file reader.
///
/// This class provides a generic ELF (32/64 bit) reader plugin implementing
/// the ObjectFile protocol.
class ObjectFileELF : public lldb_private::ObjectFile {
public:
  // Static Functions
  static void Initialize();

  static void Terminate();

  static llvm::StringRef GetPluginNameStatic() { return "elf"; }

  static llvm::StringRef GetPluginDescriptionStatic() {
    return "ELF object file reader.";
  }

  static lldb_private::ObjectFile *
  CreateInstance(const lldb::ModuleSP &module_sp,
                 lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
                 const lldb_private::FileSpec *file, lldb::offset_t file_offset,
                 lldb::offset_t length);

  static lldb_private::ObjectFile *CreateMemoryInstance(
      const lldb::ModuleSP &module_sp, lldb::WritableDataBufferSP data_sp,
      const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);

  static lldb_private::ModuleSpecList
  GetModuleSpecifications(const lldb_private::FileSpec &file,
                          lldb::DataExtractorSP &extractor_sp,
                          lldb::offset_t file_offset, lldb::offset_t length);

  static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset,
                              lldb::addr_t length);

  // PluginInterface protocol
  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }

  // LLVM RTTI support
  static char ID;
  bool isA(const void *ClassID) const override {
    return ClassID == &ID || ObjectFile::isA(ClassID);
  }
  static bool classof(const ObjectFile *obj) { return obj->isA(&ID); }

  // ObjectFile Protocol.
  bool ParseHeader() override;

  bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value,
                      bool value_is_offset) override;

  lldb::ByteOrder GetByteOrder() const override;

  bool IsExecutable() const override;

  uint32_t GetAddressByteSize() const override;

  lldb_private::AddressClass GetAddressClass(lldb::addr_t file_addr) override;

  void ParseSymtab(lldb_private::Symtab &symtab) override;

  bool IsStripped() override;

  void CreateSections(lldb_private::SectionList &unified_section_list) override;

  void Dump(lldb_private::Stream *s) override;

  lldb_private::ArchSpec GetArchitecture() override;

  lldb_private::UUID GetUUID() override;

  /// Return the contents of the .gnu_debuglink section, if the object file
  /// contains it.
  std::optional<lldb_private::FileSpec> GetDebugLink();

  uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;

  lldb_private::FileSpecList GetReExportedLibraries() override;

  bool ReExportedLibrariesShadowLocalDefinitions() const override {
    return true;
  }

  lldb_private::Address
  GetImageInfoAddress(lldb_private::Target *target) override;

  lldb_private::Address GetEntryPointAddress() override;

  lldb_private::Address GetBaseAddress() override;

  ObjectFile::Type CalculateType() override;

  ObjectFile::Strata CalculateStrata() override;

  size_t ReadSectionData(lldb_private::Section *section,
                         lldb::offset_t section_offset, void *dst,
                         size_t dst_len) override;

  size_t ReadSectionData(lldb_private::Section *section,
                         lldb_private::DataExtractor &section_data) override;

  llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders();
  lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H);

  llvm::StringRef
  StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;

  void RelocateSection(lldb_private::Section *section) override;

protected:

  std::vector<LoadableData>
  GetLoadableData(lldb_private::Target &target) override;

  static lldb::WritableDataBufferSP
  MapFileDataWritable(const lldb_private::FileSpec &file, uint64_t Size,
                      uint64_t Offset);

private:
  ObjectFileELF(const lldb::ModuleSP &module_sp,
                lldb::DataExtractorSP extractor_sp, lldb::offset_t data_offset,
                const lldb_private::FileSpec *file, lldb::offset_t offset,
                lldb::offset_t length);

  ObjectFileELF(const lldb::ModuleSP &module_sp,
                lldb::DataBufferSP header_data_sp,
                const lldb::ProcessSP &process_sp, lldb::addr_t header_addr);

  typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;

  struct ELFSectionHeaderInfo : public elf::ELFSectionHeader {
    std::string section_name;
  };

  typedef std::vector<ELFSectionHeaderInfo> SectionHeaderColl;
  typedef SectionHeaderColl::iterator SectionHeaderCollIter;
  typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;

  struct ELFDynamicWithName {
    elf::ELFDynamic symbol;
    std::string name;
  };
  typedef std::vector<ELFDynamicWithName> DynamicSymbolColl;
  typedef DynamicSymbolColl::iterator DynamicSymbolCollIter;
  typedef DynamicSymbolColl::const_iterator DynamicSymbolCollConstIter;

  /// An ordered map of file address to address class. Used on architectures
  /// like Arm where there is an alternative ISA mode like Thumb. The container
  /// is ordered so that it can be binary searched.
  typedef std::map<lldb::addr_t, lldb_private::AddressClass>
      FileAddressToAddressClassMap;

  /// Version of this reader common to all plugins based on this class.
  static const uint32_t m_plugin_version = 1;
  static const uint32_t g_core_uuid_magic;

  /// ELF file header.
  elf::ELFHeader m_header;

  /// ELF build ID.
  lldb_private::UUID m_uuid;

  /// ELF .gnu_debuglink file and crc data if available.
  std::string m_gnu_debuglink_file;
  uint32_t m_gnu_debuglink_crc = 0;

  /// Collection of program headers.
  ProgramHeaderColl m_program_headers;

  /// Collection of section headers.
  SectionHeaderColl m_section_headers;

  /// The file address of the .dynamic section. This can be found in the p_vaddr
  /// of the PT_DYNAMIC program header.
  lldb::addr_t m_dynamic_base_addr = LLDB_INVALID_ADDRESS;

  /// Collection of symbols from the dynamic table.
  DynamicSymbolColl m_dynamic_symbols;

  /// Object file parsed from .gnu_debugdata section (\sa
  /// GetGnuDebugDataObjectFile())
  std::shared_ptr<ObjectFileELF> m_gnu_debug_data_object_file;

  /// List of file specifications corresponding to the modules (shared
  /// libraries) on which this object file depends.
  mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up;

  /// Cached value of the entry point for this module.
  lldb_private::Address m_entry_point_address;

  /// The architecture detected from parsing elf file contents.
  lldb_private::ArchSpec m_arch_spec;

  /// The address class for each symbol in the elf file
  FileAddressToAddressClassMap m_address_class_map;

  /// Returns the index of the given section header.
  size_t SectionIndex(const SectionHeaderCollIter &I);

  /// Returns the index of the given section header.
  size_t SectionIndex(const SectionHeaderCollConstIter &I) const;

  // Parses the ELF program headers.
  static size_t GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
                                     lldb_private::DataExtractor &object_data,
                                     const elf::ELFHeader &header);

  // Finds PT_NOTE segments and calculates their crc sum.
  static uint32_t
  CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl &program_headers,
                                 lldb_private::DataExtractor &data);

  /// Parses all section headers present in this object file and populates
  /// m_program_headers.  This method will compute the header list only once.
  /// Returns true iff the headers have been successfully parsed.
  bool ParseProgramHeaders();

  /// Parses all section headers present in this object file and populates
  /// m_section_headers.  This method will compute the header list only once.
  /// Returns the number of headers parsed.
  size_t ParseSectionHeaders();

  lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const;

  static void ParseARMAttributes(lldb_private::DataExtractor &data,
                                 uint64_t length,
                                 lldb_private::ArchSpec &arch_spec);

  static void ParseRISCVAttributes(const lldb_private::DataExtractor &data,
                                   uint64_t length,
                                   lldb_private::ArchSpec &arch_spec);

  /// Parses the elf section headers and returns the uuid, debug link name,
  /// crc, archspec.
  static size_t GetSectionHeaderInfo(SectionHeaderColl &section_headers,
                                     lldb_private::DataExtractor &object_data,
                                     const elf::ELFHeader &header,
                                     lldb_private::UUID &uuid,
                                     std::string &gnu_debuglink_file,
                                     uint32_t &gnu_debuglink_crc,
                                     lldb_private::ArchSpec &arch_spec);

  /// Scans the dynamic section and locates all dependent modules (shared
  /// libraries) populating m_filespec_up.  This method will compute the
  /// dependent module list only once.  Returns the number of dependent
  /// modules parsed.
  size_t ParseDependentModules();

  /// Parses the dynamic symbol table and populates m_dynamic_symbols.  The
  /// vector retains the order as found in the object file.  Returns the
  /// number of dynamic symbols parsed.
  size_t ParseDynamicSymbols();

  /// Populates the symbol table with all non-dynamic linker symbols.  This
  /// method will parse the symbols only once.  Returns the number of symbols
  /// parsed and a map of address types (used by targets like Arm that have
  /// an alternative ISA mode like Thumb).
  std::pair<unsigned, FileAddressToAddressClassMap>
  ParseSymbolTable(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,
                   lldb_private::Section *symtab);

  /// Helper routine for ParseSymbolTable().
  std::pair<unsigned, FileAddressToAddressClassMap>
  ParseSymbols(lldb_private::Symtab *symbol_table, lldb::user_id_t start_id,
               lldb_private::SectionList *section_list,
               const size_t num_symbols,
               const lldb_private::DataExtractor &symtab_data,
               const lldb_private::DataExtractor &strtab_data);

  /// Scans the relocation entries and adds a set of artificial symbols to the
  /// given symbol table for each PLT slot.  Returns the number of symbols
  /// added.
  unsigned ParseTrampolineSymbols(lldb_private::Symtab *symbol_table,
                                  lldb::user_id_t start_id,
                                  const ELFSectionHeaderInfo *rela_hdr,
                                  lldb::user_id_t section_id);

  void ParseUnwindSymbols(lldb_private::Symtab *symbol_table,
                          lldb_private::DWARFCallFrameInfo *eh_frame);

  /// Relocates debug sections
  unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr,
                                 lldb::user_id_t rel_id,
                                 lldb_private::Symtab *thetab);

  unsigned ApplyRelocations(lldb_private::Symtab *symtab,
                            const elf::ELFHeader *hdr,
                            const elf::ELFSectionHeader *rel_hdr,
                            const elf::ELFSectionHeader *symtab_hdr,
                            const elf::ELFSectionHeader *debug_hdr,
                            lldb_private::DataExtractor &rel_data,
                            lldb_private::DataExtractor &symtab_data,
                            lldb_private::DataExtractor &debug_data,
                            lldb_private::Section *rel_section);

  /// Loads the section name string table into m_shstr_data.  Returns the
  /// number of bytes constituting the table.
  size_t GetSectionHeaderStringTable();

  /// Utility method for looking up a section given its name.  Returns the
  /// index of the corresponding section or zero if no section with the given
  /// name can be found (note that section indices are always 1 based, and so
  /// section index 0 is never valid).
  lldb::user_id_t GetSectionIndexByName(llvm::StringRef name);

  /// Returns the section header with the given id or NULL.
  const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id);

  /// \name  ELF header dump routines
  //@{
  static void DumpELFHeader(lldb_private::Stream *s,
                            const elf::ELFHeader &header);

  static void DumpELFHeader_e_ident_EI_DATA(lldb_private::Stream *s,
                                            unsigned char ei_data);

  static void DumpELFHeader_e_type(lldb_private::Stream *s,
                                   elf::elf_half e_type);
  //@}

  /// \name ELF program header dump routines
  //@{
  void DumpELFProgramHeaders(lldb_private::Stream *s);

  static void DumpELFProgramHeader(lldb_private::Stream *s,
                                   const elf::ELFProgramHeader &ph);

  static void DumpELFProgramHeader_p_type(lldb_private::Stream *s,
                                          elf::elf_word p_type);

  static void DumpELFProgramHeader_p_flags(lldb_private::Stream *s,
                                           elf::elf_word p_flags);
  //@}

  /// \name ELF section header dump routines
  //@{
  void DumpELFSectionHeaders(lldb_private::Stream *s);

  static void DumpELFSectionHeader(lldb_private::Stream *s,
                                   const ELFSectionHeaderInfo &sh);

  static void DumpELFSectionHeader_sh_type(lldb_private::Stream *s,
                                           elf::elf_word sh_type);

  static void DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
                                            elf::elf_xword sh_flags);
  //@}

  /// ELF dependent module dump routine.
  void DumpDependentModules(lldb_private::Stream *s);

  /// ELF dump the .dynamic section
  void DumpELFDynamic(lldb_private::Stream *s);

  const elf::ELFDynamic *FindDynamicSymbol(unsigned tag);

  unsigned PLTRelocationType();

  static lldb_private::Status
  RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
                              lldb_private::ArchSpec &arch_spec,
                              lldb_private::UUID &uuid);

  bool AnySegmentHasPhysicalAddress();

  /// Takes the .gnu_debugdata and returns the decompressed object file that is
  /// stored within that section.
  ///
  /// \returns either the decompressed object file stored within the
  /// .gnu_debugdata section or \c nullptr if an error occurred or if there's no
  /// section with that name.
  std::shared_ptr<ObjectFileELF> GetGnuDebugDataObjectFile();

  /// Get the bytes that represent the .dynamic section.
  ///
  /// This function will fetch the data for the .dynamic section in an ELF file.
  /// The PT_DYNAMIC program header will be used to extract the data and this
  /// function will fall back to using the section headers if PT_DYNAMIC isn't
  /// found.
  ///
  /// \return The bytes that represent the string table data or \c std::nullopt
  ///         if an error occurred.
  std::optional<lldb_private::DataExtractor> GetDynamicData();

  /// Get the bytes that represent the dynamic string table data.
  ///
  /// This function will fetch the data for the string table in an ELF file. If
  /// the ELF file is loaded from a file on disk, it will use the section
  /// headers to extract the data and fall back to using the DT_STRTAB and
  /// DT_STRSZ .dynamic entries.
  ///
  /// \return The bytes that represent the string table data or \c std::nullopt
  ///         if an error occurred.
  std::optional<lldb_private::DataExtractor> GetDynstrData();

  /// Read the bytes pointed to by the \a dyn dynamic entry.
  ///
  /// ELFDynamic::d_ptr values contain file addresses if we load the ELF file
  /// form a file on disk, or they contain load addresses if they were read
  /// from memory. This function will correctly extract the data in both cases
  /// if it is available.
  ///
  /// \param[in] dyn The dynamic entry to use to fetch the data from.
  ///
  /// \param[in] length The number of bytes to read.
  ///
  /// \param[in] offset The number of bytes to skip after the d_ptr value
  ///                   before reading data.
  ///
  /// \return The bytes that represent the dynanic entries data or
  ///         \c std::nullopt if an error occurred or the data is not available.
  std::optional<lldb_private::DataExtractor>
  ReadDataFromDynamic(const elf::ELFDynamic *dyn, uint64_t length,
                      uint64_t offset = 0);

  /// Get the bytes that represent the dynamic symbol table from the .dynamic
  /// section from process memory.
  ///
  /// This functon uses the DT_SYMTAB value from the .dynamic section to read
  /// the symbols table data from process memory. The number of symbols in the
  /// symbol table is calculated by looking at the DT_HASH or DT_GNU_HASH
  /// values as the symbol count isn't stored in the .dynamic section.
  ///
  /// \return The bytes that represent the symbol table data from the .dynamic
  ///         section or section headers or \c std::nullopt if an error
  ///         occurred or if there is no dynamic symbol data available.
  std::optional<lldb_private::DataExtractor>
  GetDynsymDataFromDynamic(uint32_t &num_symbols);

  /// Get the number of symbols from the DT_HASH dynamic entry.
  std::optional<uint32_t> GetNumSymbolsFromDynamicHash();

  /// Get the number of symbols from the DT_GNU_HASH dynamic entry.
  std::optional<uint32_t> GetNumSymbolsFromDynamicGnuHash();
};

#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_ELF_OBJECTFILEELF_H
