// elfcpp_file.h -- file access for elfcpp   -*- C++ -*-

// Copyright (C) 2006-2014 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of elfcpp.
   
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License
// as published by the Free Software Foundation; either version 2, or
// (at your option) any later version.

// In addition to the permissions in the GNU Library General Public
// License, the Free Software Foundation gives you unlimited
// permission to link the compiled version of this file into
// combinations with other programs, and to distribute those
// combinations without any restriction coming from the use of this
// file.  (The Library Public License restrictions do apply in other
// respects; for example, they cover modification of the file, and
/// distribution when not linked into a combined executable.)

// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.

// You should have received a copy of the GNU Library General Public
// License along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
// 02110-1301, USA.

// This header file defines the class Elf_file which can be used to
// read useful data from an ELF file.  The functions here are all
// templates which take a file interface object as a parameter.  This
// type must have a subtype View.  This type must support two methods:
//     View view(off_t file_offset, off_t data_size)
// returns a View for the specified part of the file.
//     void error(const char* printf_format, ...)
// prints an error message and does not return.  The subtype View must
// support a method
//     const unsigned char* data()
// which returns a pointer to a buffer containing the requested data.
// This general interface is used to read data from the file.  Objects
// of type View will never survive longer than the elfcpp function.

// Some of these functions must return a reference to part of the
// file.  To use these, the file interface must support a subtype
// Location:
//    Location(off_t file_offset, off_t data_size)
// To use this in conjunction with the accessors types Shdr, etc., the
// file interface should support an overload of view:
//    View view(Location)
// This permits writing
//    elfcpp::Shdr shdr(file, ef.section_header(n));

#ifndef ELFCPP_FILE_H
#define ELFCPP_FILE_H

#include <string>
#include <cstdio>
#include <cstring>

#include "elfcpp.h"

namespace elfcpp
{

// A simple helper class to recognize if a file has an ELF header.

class Elf_recognizer
{
 public:
  // Maximum header size.  The user should try to read this much of
  // the file when using this class.

  static const int max_header_size = Elf_sizes<64>::ehdr_size;

  // Checks if the file contains the ELF magic.  Other header fields
  // are not checked.

  static bool
  is_elf_file(const unsigned char* ehdr_buf, int size);

  // Check if EHDR_BUF/BUFSIZE is a valid header of a 32-bit or
  // 64-bit, little-endian or big-endian ELF file.  Assumes
  // is_elf_file() has been checked to be true.  If the header is not
  // valid, *ERROR contains a human-readable error message.  If is is,
  // *SIZE is set to either 32 or 64, *BIG_ENDIAN is set to indicate
  // whether the file is big-endian.

  static bool
  is_valid_header(const unsigned char* ehdr_buf, off_t bufsize,
                  int* size, bool* big_endian,
                  std::string* error);
};

// This object is used to read an ELF file.
//   SIZE: The size of file, 32 or 64.
//   BIG_ENDIAN: Whether the file is in big-endian format.
//   FILE: A file reading type as described above.

template<int size, bool big_endian, typename File>
class Elf_file
{
 private:
  typedef Elf_file<size, big_endian, File> This;

 public:
  static const int ehdr_size = Elf_sizes<size>::ehdr_size;
  static const int phdr_size = Elf_sizes<size>::phdr_size;
  static const int shdr_size = Elf_sizes<size>::shdr_size;
  static const int sym_size = Elf_sizes<size>::sym_size;
  static const int rel_size = Elf_sizes<size>::rel_size;
  static const int rela_size = Elf_sizes<size>::rela_size;

  typedef Ehdr<size, big_endian> Ef_ehdr;
  typedef Phdr<size, big_endian> Ef_phdr;
  typedef Shdr<size, big_endian> Ef_shdr;
  typedef Sym<size, big_endian> Ef_sym;

  // Construct an Elf_file given an ELF file header.
  Elf_file(File* file, const Ef_ehdr& ehdr)
  { this->construct(file, ehdr); }

  // Construct an ELF file.
  inline
  Elf_file(File* file);

  // Return the file offset to the section headers.
  off_t
  shoff() const
  { return this->shoff_; }

  // Find the first section with an sh_type field equal to TYPE and
  // return its index.  Returns SHN_UNDEF if there is no such section.
  unsigned int
  find_section_by_type(unsigned int type);

  // Return the number of sections.
  unsigned int
  shnum()
  {
    this->initialize_shnum();
    return this->shnum_;
  }

  // Return the section index of the section name string table.
  unsigned int
  shstrndx()
  {
    this->initialize_shnum();
    return this->shstrndx_;
  }

  // Return the value to subtract from section indexes >=
  // SHN_LORESERVE.  See the comment in initialize_shnum.
  int
  large_shndx_offset()
  {
    this->initialize_shnum();
    return this->large_shndx_offset_;
  }

  // Return the location of the header of section SHNDX.
  typename File::Location
  section_header(unsigned int shndx)
  {
    return typename File::Location(this->section_header_offset(shndx),
				   shdr_size);
  }

  // Return the name of section SHNDX.
  std::string
  section_name(unsigned int shndx);

  // Return the location of the contents of section SHNDX.
  typename File::Location
  section_contents(unsigned int shndx);

  // Return the size of section SHNDX.
  typename Elf_types<size>::Elf_WXword
  section_size(unsigned int shndx);

  // Return the flags of section SHNDX.
  typename Elf_types<size>::Elf_WXword
  section_flags(unsigned int shndx);

  // Return the address of section SHNDX.
  typename Elf_types<size>::Elf_Addr
  section_addr(unsigned int shndx);

  // Return the type of section SHNDX.
  Elf_Word
  section_type(unsigned int shndx);

  // Return the link field of section SHNDX.
  Elf_Word
  section_link(unsigned int shndx);

  // Return the info field of section SHNDX.
  Elf_Word
  section_info(unsigned int shndx);

  // Return the addralign field of section SHNDX.
  typename Elf_types<size>::Elf_WXword
  section_addralign(unsigned int shndx);

 private:
  // Shared constructor code.
  void
  construct(File* file, const Ef_ehdr& ehdr);

  // Initialize shnum_ and shstrndx_.
  void
  initialize_shnum();

  // Return the file offset of the header of section SHNDX.
  off_t
  section_header_offset(unsigned int shndx);

  // The file we are reading.
  File* file_;
  // The file offset to the section headers.
  off_t shoff_;
  // The number of sections.
  unsigned int shnum_;
  // The section index of the section name string table.
  unsigned int shstrndx_;
  // Offset to add to sections larger than SHN_LORESERVE.
  int large_shndx_offset_;
};

// A small wrapper around SHT_STRTAB data mapped to memory. It checks that the
// index is not out of bounds and the string is NULL-terminated.

class Elf_strtab
{
 public:
  // Construct an Elf_strtab for a section with contents *P and size SIZE.
  Elf_strtab(const unsigned char* p, size_t size);

  // Return the file offset to the section headers.
  bool
  get_c_string(size_t offset, const char** cstring) const
  {
    if (offset >= this->usable_size_)
      return false;
    *cstring = this->base_ + offset;
    return true;
  }

 private:
  // Contents of the section mapped to memory.
  const char* base_;
  // One larger that the position of the last NULL character in the section.
  // For valid SHT_STRTAB sections, this is the size of the section.
  size_t usable_size_;
};

// Inline function definitions.

// Check for presence of the ELF magic number.

inline bool
Elf_recognizer::is_elf_file(const unsigned char* ehdr_buf, int size)
{
  if (size < 4)
    return false;

  static unsigned char elfmagic[4] =
    {
      elfcpp::ELFMAG0, elfcpp::ELFMAG1,
      elfcpp::ELFMAG2, elfcpp::ELFMAG3
    };
  return memcmp(ehdr_buf, elfmagic, 4) == 0;
}

namespace
{

// Print a number to a string.

inline std::string
internal_printf_int(const char* format, int arg)
{
  char buf[256];
  snprintf(buf, sizeof(buf), format, arg);
  return std::string(buf);
}

}  // End anonymous namespace.

// Check the validity of the ELF header.

inline bool
Elf_recognizer::is_valid_header(
    const unsigned char* ehdr_buf,
    off_t bufsize,
    int* size,
    bool* big_endian,
    std::string* error)
{
  if (bufsize < elfcpp::EI_NIDENT)
    {
      *error = _("ELF file too short");
      return false;
    }

  int v = ehdr_buf[elfcpp::EI_VERSION];
  if (v != elfcpp::EV_CURRENT)
    {
      if (v == elfcpp::EV_NONE)
        *error = _("invalid ELF version 0");
      else
        *error = internal_printf_int(_("unsupported ELF version %d"), v);
      return false;
    }

  int c = ehdr_buf[elfcpp::EI_CLASS];
  if (c == elfcpp::ELFCLASSNONE)
    {
      *error = _("invalid ELF class 0");
      return false;
    }
  else if (c != elfcpp::ELFCLASS32
           && c != elfcpp::ELFCLASS64)
    {
      *error = internal_printf_int(_("unsupported ELF class %d"), c);
      return false;
    }

  int d = ehdr_buf[elfcpp::EI_DATA];
  if (d == elfcpp::ELFDATANONE)
    {
      *error = _("invalid ELF data encoding");
      return false;
    }
  else if (d != elfcpp::ELFDATA2LSB
           && d != elfcpp::ELFDATA2MSB)
    {
      *error = internal_printf_int(_("unsupported ELF data encoding %d"), d);
      return false;
    }

  *big_endian = (d == elfcpp::ELFDATA2MSB);

  if (c == elfcpp::ELFCLASS32)
    {
      if (bufsize < elfcpp::Elf_sizes<32>::ehdr_size)
        {
          *error = _("ELF file too short");
          return false;
        }
      *size = 32;
    }
  else
    {
      if (bufsize < elfcpp::Elf_sizes<64>::ehdr_size)
        {
          *error = _("ELF file too short");
          return false;
        }
      *size = 64;
    }

  return true;
}

// Template function definitions.

// Construct an Elf_file given an ELF file header.

template<int size, bool big_endian, typename File>
void
Elf_file<size, big_endian, File>::construct(File* file, const Ef_ehdr& ehdr)
{
  this->file_ = file;
  this->shoff_ = ehdr.get_e_shoff();
  this->shnum_ = ehdr.get_e_shnum();
  this->shstrndx_ = ehdr.get_e_shstrndx();
  this->large_shndx_offset_ = 0;
  if (ehdr.get_e_ehsize() != This::ehdr_size)
    file->error(_("bad e_ehsize (%d != %d)"),
		ehdr.get_e_ehsize(), This::ehdr_size);
  if (ehdr.get_e_shentsize() != This::shdr_size)
    file->error(_("bad e_shentsize (%d != %d)"),
		ehdr.get_e_shentsize(), This::shdr_size);
}

// Construct an ELF file.

template<int size, bool big_endian, typename File>
inline
Elf_file<size, big_endian, File>::Elf_file(File* file)
{
  typename File::View v(file->view(file_header_offset, This::ehdr_size));
  this->construct(file, Ef_ehdr(v.data()));
}

// Initialize the shnum_ and shstrndx_ fields, handling overflow.

template<int size, bool big_endian, typename File>
void
Elf_file<size, big_endian, File>::initialize_shnum()
{
  if ((this->shnum_ == 0 || this->shstrndx_ == SHN_XINDEX)
      && this->shoff_ != 0)
    {
      typename File::View v(this->file_->view(this->shoff_, This::shdr_size));
      Ef_shdr shdr(v.data());

      if (this->shnum_ == 0)
	this->shnum_ = shdr.get_sh_size();

      if (this->shstrndx_ == SHN_XINDEX)
	{
	  this->shstrndx_ = shdr.get_sh_link();

	  // Versions of the GNU binutils between 2.12 and 2.18 did
	  // not handle objects with more than SHN_LORESERVE sections
	  // correctly.  All large section indexes were offset by
	  // 0x100.  Some information can be found here:
	  // http://sourceware.org/bugzilla/show_bug.cgi?id=5900 .
	  // Fortunately these object files are easy to detect, as the
	  // GNU binutils always put the section header string table
	  // near the end of the list of sections.  Thus if the
	  // section header string table index is larger than the
	  // number of sections, then we know we have to subtract
	  // 0x100 to get the real section index.
	  if (this->shstrndx_ >= this->shnum_)
	    {
	      if (this->shstrndx_ >= elfcpp::SHN_LORESERVE + 0x100)
		{
		  this->large_shndx_offset_ = - 0x100;
		  this->shstrndx_ -= 0x100;
		}
	      if (this->shstrndx_ >= this->shnum_)
		this->file_->error(_("bad shstrndx: %u >= %u"),
				   this->shstrndx_, this->shnum_);
	    }
	}
    }
}

// Find section with sh_type equal to TYPE and return its index.
// Returns SHN_UNDEF if not found.

template<int size, bool big_endian, typename File>
unsigned int
Elf_file<size, big_endian, File>::find_section_by_type(unsigned int type)
{
  unsigned int shnum = this->shnum();
  typename File::View v(this->file_->view(this->shoff_,
					  This::shdr_size * shnum));
  for (unsigned int i = 0; i < shnum; i++)
    {
      Ef_shdr shdr(v.data() + This::shdr_size * i);
      if (shdr.get_sh_type() == type)
        return i;
    }
  return SHN_UNDEF;
}

// Return the file offset of the section header of section SHNDX.

template<int size, bool big_endian, typename File>
off_t
Elf_file<size, big_endian, File>::section_header_offset(unsigned int shndx)
{
  if (shndx >= this->shnum())
    this->file_->error(_("section_header_offset: bad shndx %u >= %u"),
		       shndx, this->shnum());
  return this->shoff_ + This::shdr_size * shndx;
}

// Return the name of section SHNDX.

template<int size, bool big_endian, typename File>
std::string
Elf_file<size, big_endian, File>::section_name(unsigned int shndx)
{
  File* const file = this->file_;

  // Get the section name offset.
  unsigned int sh_name;
  {
    typename File::View v(file->view(this->section_header_offset(shndx),
				     This::shdr_size));
    Ef_shdr shdr(v.data());
    sh_name = shdr.get_sh_name();
  }

  // Get the file offset for the section name string table data.
  off_t shstr_off;
  typename Elf_types<size>::Elf_WXword shstr_size;
  {
    const unsigned int shstrndx = this->shstrndx_;
    typename File::View v(file->view(this->section_header_offset(shstrndx),
				     This::shdr_size));
    Ef_shdr shstr_shdr(v.data());
    shstr_off = shstr_shdr.get_sh_offset();
    shstr_size = shstr_shdr.get_sh_size();
  }

  if (sh_name >= shstr_size)
    file->error(_("bad section name offset for section %u: %u"),
		shndx, sh_name);

  typename File::View v(file->view(shstr_off, shstr_size));

  const unsigned char* datau = v.data();
  const char* data = reinterpret_cast<const char*>(datau);
  const void* p = ::memchr(data + sh_name, '\0', shstr_size - sh_name);
  if (p == NULL)
    file->error(_("missing null terminator for name of section %u"),
		shndx);

  size_t len = static_cast<const char*>(p) - (data + sh_name);

  return std::string(data + sh_name, len);
}

// Return the contents of section SHNDX.

template<int size, bool big_endian, typename File>
typename File::Location
Elf_file<size, big_endian, File>::section_contents(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_contents: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));
  Ef_shdr shdr(v.data());
  return typename File::Location(shdr.get_sh_offset(), shdr.get_sh_size());
}

// Get the size of section SHNDX.

template<int size, bool big_endian, typename File>
typename Elf_types<size>::Elf_WXword
Elf_file<size, big_endian, File>::section_size(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_size: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_size();
}

// Return the section flags of section SHNDX.

template<int size, bool big_endian, typename File>
typename Elf_types<size>::Elf_WXword
Elf_file<size, big_endian, File>::section_flags(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_flags: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_flags();
}

// Return the address of section SHNDX.

template<int size, bool big_endian, typename File>
typename Elf_types<size>::Elf_Addr
Elf_file<size, big_endian, File>::section_addr(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_flags: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_addr();
}

// Return the type of section SHNDX.

template<int size, bool big_endian, typename File>
Elf_Word
Elf_file<size, big_endian, File>::section_type(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_type: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_type();
}

// Return the sh_link field of section SHNDX.

template<int size, bool big_endian, typename File>
Elf_Word
Elf_file<size, big_endian, File>::section_link(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_link: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_link();
}

// Return the sh_info field of section SHNDX.

template<int size, bool big_endian, typename File>
Elf_Word
Elf_file<size, big_endian, File>::section_info(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_info: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_info();
}

// Return the sh_addralign field of section SHNDX.

template<int size, bool big_endian, typename File>
typename Elf_types<size>::Elf_WXword
Elf_file<size, big_endian, File>::section_addralign(unsigned int shndx)
{
  File* const file = this->file_;

  if (shndx >= this->shnum())
    file->error(_("section_addralign: bad shndx %u >= %u"),
		shndx, this->shnum());

  typename File::View v(file->view(this->section_header_offset(shndx),
				   This::shdr_size));

  Ef_shdr shdr(v.data());
  return shdr.get_sh_addralign();
}

inline
Elf_strtab::Elf_strtab(const unsigned char* p, size_t size)
{
  // Check if the section is NUL-terminated. If it isn't, we ignore
  // the last part to make sure we don't return non-NUL-terminated
  // strings.
  while (size > 0 && p[size - 1] != 0)
    size--;
  this->base_ = reinterpret_cast<const char*>(p);
  this->usable_size_ = size;
}

} // End namespace elfcpp.

#endif // !defined(ELFCPP_FILE_H)
