// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Copyright (C) 2020-2024 Google, Inc.

/// @file
///
/// This contains the definitions of the ELF utilities for the dwarf reader.
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <elfutils/libdwfl.h>
#include <sstream>
#include "abg-elf-helpers.h"
#include "abg-tools-utils.h"

namespace abigail
{

namespace elf_helpers
{

/// Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE
/// macros) into an elf_symbol::type value.
///
/// Note that this function aborts when given an unexpected value.
///
/// @param the symbol type value to convert.
///
/// @return the converted value.
elf_symbol::type
stt_to_elf_symbol_type(unsigned char stt)
{
  switch (stt)
    {
    case STT_NOTYPE:
      return elf_symbol::NOTYPE_TYPE;
    case STT_OBJECT:
      return elf_symbol::OBJECT_TYPE;
    case STT_FUNC:
      return elf_symbol::FUNC_TYPE;
    case STT_SECTION:
      return elf_symbol::SECTION_TYPE;
    case STT_FILE:
      return elf_symbol::FILE_TYPE;
    case STT_COMMON:
      return elf_symbol::COMMON_TYPE;
    case STT_TLS:
      return elf_symbol::TLS_TYPE;
    case STT_GNU_IFUNC:
      return elf_symbol::GNU_IFUNC_TYPE;
    default:
      // An unknown value that probably ought to be supported?  Let's
      // abort right here rather than yielding garbage.
      ABG_ASSERT_NOT_REACHED;
    }
}

/// Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND
/// macros) into an elf_symbol::binding value.
///
/// Note that this function aborts when given an unexpected value.
///
/// @param the symbol binding value to convert.
///
/// @return the converted value.
elf_symbol::binding
stb_to_elf_symbol_binding(unsigned char stb)
{
  switch (stb)
    {
    case STB_LOCAL:
      return elf_symbol::LOCAL_BINDING;
    case STB_GLOBAL:
      return elf_symbol::GLOBAL_BINDING;
    case STB_WEAK:
      return elf_symbol::WEAK_BINDING;
    case STB_GNU_UNIQUE:
      return elf_symbol::GNU_UNIQUE_BINDING;
    default:
      ABG_ASSERT_NOT_REACHED;
    }
}

/// Convert an ELF symbol visiblity given by the symbols ->st_other
/// data member as returned by the GELF_ST_VISIBILITY macro into a
/// elf_symbol::visiblity value.
///
/// @param stv the value of the ->st_other data member of the ELF
/// symbol.
///
/// @return the converted elf_symbol::visiblity value.
elf_symbol::visibility
stv_to_elf_symbol_visibility(unsigned char stv)
{
  switch (stv)
    {
    case STV_DEFAULT:
      return elf_symbol::DEFAULT_VISIBILITY;
    case STV_INTERNAL:
      return elf_symbol::INTERNAL_VISIBILITY;
    case STV_HIDDEN:
      return elf_symbol::HIDDEN_VISIBILITY;
    case STV_PROTECTED:
      return elf_symbol::PROTECTED_VISIBILITY;
    default:
      ABG_ASSERT_NOT_REACHED;
    }
}

/// Convert the value of the e_machine field of GElf_Ehdr into a
/// string.  This is to get a string representing the architecture of
/// the elf file at hand.
///
/// @param e_machine the value of GElf_Ehdr::e_machine.
///
/// @return the string representation of GElf_Ehdr::e_machine.
std::string
e_machine_to_string(GElf_Half e_machine)
{
  switch (e_machine)
    {
    case EM_NONE:
      return "elf-no-arch";
    case EM_M32:
      return "elf-att-we-32100";
    case EM_SPARC:
      return "elf-sun-sparc";
    case EM_386:
      return "elf-intel-80386";
    case EM_68K:
      return "elf-motorola-68k";
    case EM_88K:
      return "elf-motorola-88k";
    case EM_860:
      return "elf-intel-80860";
    case EM_MIPS:
      return "elf-mips-r3000-be";
    case EM_S370:
      return "elf-ibm-s370";
    case EM_MIPS_RS3_LE:
      return "elf-mips-r3000-le";
    case EM_PARISC:
      return "elf-hp-parisc";
    case EM_VPP500:
      return "elf-fujitsu-vpp500";
    case EM_SPARC32PLUS:
      return "elf-sun-sparc-v8plus";
    case EM_960:
      return "elf-intel-80960";
    case EM_PPC:
      return "elf-powerpc";
    case EM_PPC64:
      return "elf-powerpc-64";
    case EM_S390:
      return "elf-ibm-s390";
    case EM_V800:
      return "elf-nec-v800";
    case EM_FR20:
      return "elf-fujitsu-fr20";
    case EM_RH32:
      return "elf-trw-rh32";
    case EM_RCE:
      return "elf-motorola-rce";
    case EM_ARM:
      return "elf-arm";
    case EM_FAKE_ALPHA:
      return "elf-digital-alpha";
    case EM_SH:
      return "elf-hitachi-sh";
    case EM_SPARCV9:
      return "elf-sun-sparc-v9-64";
    case EM_TRICORE:
      return "elf-siemens-tricore";
    case EM_ARC:
      return "elf-argonaut-risc-core";
    case EM_H8_300:
      return "elf-hitachi-h8-300";
    case EM_H8_300H:
      return "elf-hitachi-h8-300h";
    case EM_H8S:
      return "elf-hitachi-h8s";
    case EM_H8_500:
      return "elf-hitachi-h8-500";
    case EM_IA_64:
      return "elf-intel-ia-64";
    case EM_MIPS_X:
      return "elf-stanford-mips-x";
    case EM_COLDFIRE:
      return "elf-motorola-coldfire";
    case EM_68HC12:
      return "elf-motorola-68hc12";
    case EM_MMA:
      return "elf-fujitsu-mma";
    case EM_PCP:
      return "elf-siemens-pcp";
    case EM_NCPU:
      return "elf-sony-ncpu";
    case EM_NDR1:
      return "elf-denso-ndr1";
    case EM_STARCORE:
      return "elf-motorola-starcore";
    case EM_ME16:
      return "elf-toyota-me16";
    case EM_ST100:
      return "elf-stm-st100";
    case EM_TINYJ:
      return "elf-alc-tinyj";
    case EM_X86_64:
      return "elf-amd-x86_64";
    case EM_PDSP:
      return "elf-sony-pdsp";
    case EM_FX66:
      return "elf-siemens-fx66";
    case EM_ST9PLUS:
      return "elf-stm-st9+";
    case EM_ST7:
      return "elf-stm-st7";
    case EM_68HC16:
      return "elf-motorola-68hc16";
    case EM_68HC11:
      return "elf-motorola-68hc11";
    case EM_68HC08:
      return "elf-motorola-68hc08";
    case EM_68HC05:
      return "elf-motorola-68hc05";
    case EM_SVX:
      return "elf-sg-svx";
    case EM_ST19:
      return "elf-stm-st19";
    case EM_VAX:
      return "elf-digital-vax";
    case EM_CRIS:
      return "elf-axis-cris";
    case EM_JAVELIN:
      return "elf-infineon-javelin";
    case EM_FIREPATH:
      return "elf-firepath";
    case EM_ZSP:
      return "elf-lsi-zsp";
    case EM_MMIX:
      return "elf-don-knuth-mmix";
    case EM_HUANY:
      return "elf-harvard-huany";
    case EM_PRISM:
      return "elf-sitera-prism";
    case EM_AVR:
      return "elf-atmel-avr";
    case EM_FR30:
      return "elf-fujistu-fr30";
    case EM_D10V:
      return "elf-mitsubishi-d10v";
    case EM_D30V:
      return "elf-mitsubishi-d30v";
    case EM_V850:
      return "elf-nec-v850";
    case EM_M32R:
      return "elf-mitsubishi-m32r";
    case EM_MN10300:
      return "elf-matsushita-mn10300";
    case EM_MN10200:
      return "elf-matsushita-mn10200";
    case EM_PJ:
      return "elf-picojava";
    case EM_OPENRISC:
      return "elf-openrisc-32";
    case EM_ARC_A5:
      return "elf-arc-a5";
    case EM_XTENSA:
      return "elf-tensilica-xtensa";

#ifdef HAVE_EM_AARCH64_MACRO
    case EM_AARCH64:
      return "elf-arm-aarch64";
#endif

#ifdef HAVE_EM_TILEPRO_MACRO
    case EM_TILEPRO:
      return "elf-tilera-tilepro";
#endif

#ifdef HAVE_EM_TILEGX_MACRO
    case EM_TILEGX:
      return "elf-tilera-tilegx";
#endif

#ifdef HAVE_EM_RISCV_MACRO
    case EM_RISCV:
      return "elf-riscv";
#endif

    case EM_NUM:
      return "elf-last-arch-number";
    case EM_ALPHA:
      return "elf-non-official-alpha";
    default:
      {
	std::ostringstream o;
	o << "elf-unknown-arch-value-" << e_machine;
	return o.str();
      }
    }
}

/// Find and return a section by its name.
///
/// @param elf_handle the elf handle to use.
///
/// @param name the section name.
///
/// @return the section found, nor nil if none was found.
Elf_Scn*
find_section_by_name(Elf* elf_handle, const std::string& name)
{
  size_t section_header_string_index = 0;
  if (elf_getshdrstrndx (elf_handle, &section_header_string_index) < 0)
    return 0;

  Elf_Scn* section = 0;
  GElf_Shdr header_mem, *header;
  while ((section = elf_nextscn(elf_handle, section)) != 0)
    {
      header = gelf_getshdr(section, &header_mem);
      if (header == NULL)
        continue;

      const char* section_name =
	elf_strptr(elf_handle, section_header_string_index, header->sh_name);
      if (section_name && name == section_name)
	return section;
    }

  return 0;
}

/// Find and return a section by its name and its type.
///
/// @param elf_handle the elf handle to use.
///
/// @param name the name of the section.
///
/// @param section_type the type of the section.  This is the
/// Elf32_Shdr::sh_type (or Elf64_Shdr::sh_type) data member.
/// Examples of values of this parameter are SHT_PROGBITS or SHT_NOBITS.
///
/// @return the section found, nor nil if none was found.
Elf_Scn*
find_section(Elf* elf_handle, const std::string& name, Elf64_Word section_type)
{
  size_t section_header_string_index = 0;
  if (elf_getshdrstrndx (elf_handle, &section_header_string_index) < 0)
    return 0;

  Elf_Scn* section = 0;
  GElf_Shdr header_mem, *header;
  while ((section = elf_nextscn(elf_handle, section)) != 0)
    {
      header = gelf_getshdr(section, &header_mem);
      if (header == NULL || header->sh_type != section_type)
      continue;

      const char* section_name =
	elf_strptr(elf_handle, section_header_string_index, header->sh_name);
      if (section_name && name == section_name)
	return section;
    }

  return 0;
}

/// Find and return a section by its type.
///
/// @param elf_handle the elf handle to use.
///
/// @param section_type the type of the section.  This is the
/// Elf32_Shdr::sh_type (or Elf64_Shdr::sh_type) data member.
/// Examples of values of this parameter are SHT_PROGBITS or SHT_NOBITS.
///
/// @return the section found, or nil if none was found.
Elf_Scn*
find_section(Elf* elf_handle, Elf64_Word section_type)
{
  Elf_Scn* section = nullptr;
  while ((section = elf_nextscn(elf_handle, section)) != 0)
    {
      GElf_Shdr header_mem, *header;
      header = gelf_getshdr(section, &header_mem);
      if (header->sh_type == section_type)
	break;
    }
  return section;
}

/// Find and return the .symtab section
///
/// @param elf_handle the elf handle to use.
///
/// @return the section found, or nil if none was found
Elf_Scn*
find_symtab_section(Elf* elf_handle)
{
  return find_section(elf_handle, SHT_SYMTAB);
}

/// Find and return the .symtab section
///
/// @param elf_handle the elf handle to use.
///
/// @return the section found, or nil if none was found
Elf_Scn*
find_dynsym_section(Elf* elf_handle)
{
  return find_section(elf_handle, SHT_DYNSYM);
}

/// Find the symbol table.
///
/// If we are looking at a relocatable or executable file, this
/// function will return the .symtab symbol table (of type
/// SHT_SYMTAB).  But if we are looking at a DSO it returns the
/// .dynsym symbol table (of type SHT_DYNSYM).
///
/// @param elf_handle the elf handle to consider.
///
/// @param symtab the symbol table found.
///
/// @return the symbol table section
Elf_Scn*
find_symbol_table_section(Elf* elf_handle)
{
  Elf_Scn *dynsym = find_dynsym_section(elf_handle),
	  *sym_tab = find_symtab_section(elf_handle);

  if (dynsym || sym_tab)
    {
      GElf_Ehdr eh_mem;
      GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
      if (elf_header->e_type == ET_REL
	  || elf_header->e_type == ET_EXEC)
	return sym_tab ? sym_tab : dynsym;
      else
	return dynsym ? dynsym : sym_tab;
    }
  return nullptr;
}

/// Find the index (in the section headers table) of the symbol table
/// section.
///
/// If we are looking at a relocatable or executable file, this
/// function will return the index for the .symtab symbol table (of
/// type SHT_SYMTAB).  But if we are looking at a DSO it returns the
/// index for the .dynsym symbol table (of type SHT_DYNSYM).
///
/// @param elf_handle the elf handle to use.
///
/// @param symtab_index the index of the symbol_table, that was found.
///
/// @return true iff the symbol table section index was found.
bool
find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index)
{
  Elf_Scn* section = find_symbol_table_section(elf_handle);

  if (!section)
    return false;

  symtab_index = elf_ndxscn(section);
  return true;
}

/// Get the offset offset of the hash table section.
///
/// @param elf_handle the elf handle to use.
///
/// @param ht_section_offset this is set to the resulting offset
/// of the hash table section.  This is set iff the function returns true.
///
/// @param symtab_section_offset the offset of the section of the
/// symbol table the hash table refers to.
hash_table_kind
find_hash_table_section_index(Elf*	elf_handle,
			      size_t&	ht_section_index,
			      size_t&	symtab_section_index)
{
  if (!elf_handle)
    return NO_HASH_TABLE_KIND;

  GElf_Shdr header_mem, *section_header;
  bool found_sysv_ht = false, found_gnu_ht = false;
  for (Elf_Scn* section = elf_nextscn(elf_handle, 0);
       section != 0;
       section = elf_nextscn(elf_handle, section))
    {
      section_header= gelf_getshdr(section, &header_mem);
      if (section_header->sh_type != SHT_HASH
	  && section_header->sh_type != SHT_GNU_HASH)
	continue;

      ht_section_index = elf_ndxscn(section);
      symtab_section_index = section_header->sh_link;

      if (section_header->sh_type == SHT_HASH)
	found_sysv_ht = true;
      else if (section_header->sh_type == SHT_GNU_HASH)
	found_gnu_ht = true;
    }

  if (found_gnu_ht)
    return GNU_HASH_TABLE_KIND;
  else if (found_sysv_ht)
    return SYSV_HASH_TABLE_KIND;
  else
    return NO_HASH_TABLE_KIND;
}

/// Find and return the .text section.
///
/// @param elf_handle the elf handle to use.
///
/// @return the .text section found.
Elf_Scn*
find_text_section(Elf* elf_handle)
{return find_section(elf_handle, ".text", SHT_PROGBITS);}

/// Find and return the .bss section.
///
/// @param elf_handle.
///
/// @return the .bss section found.
Elf_Scn*
find_bss_section(Elf* elf_handle)
{return find_section(elf_handle, ".bss", SHT_NOBITS);}

/// Find and return the .rodata section.
///
/// @param elf_handle.
///
/// @return the .rodata section found.
Elf_Scn*
find_rodata_section(Elf* elf_handle)
{return find_section(elf_handle, ".rodata", SHT_PROGBITS);}

/// Find and return the .data section.
///
/// @param elf_handle the elf handle to use.
///
/// @return the .data section found.
Elf_Scn*
find_data_section(Elf* elf_handle)
{return find_section(elf_handle, ".data", SHT_PROGBITS);}

/// Find and return the .data1 section.
///
/// @param elf_handle the elf handle to use.
///
/// @return the .data1 section found.
Elf_Scn*
find_data1_section(Elf* elf_handle)
{return find_section(elf_handle, ".data1", SHT_PROGBITS);}

/// Return the "Official Procedure descriptors section."  This
/// section is named .opd, and is usually present only on PPC64
/// ELFv1 binaries.
///
/// @param elf_handle the elf handle to consider.
///
/// @return the .opd section, if found.  Return nil otherwise.
Elf_Scn*
find_opd_section(Elf* elf_handle)
{return find_section(elf_handle, ".opd", SHT_PROGBITS);}

/// Return the SHT_GNU_versym, SHT_GNU_verdef and SHT_GNU_verneed
/// sections that are involved in symbol versionning.
///
/// @param elf_handle the elf handle to use.
///
/// @param versym_section the SHT_GNU_versym section found.  If the
/// section wasn't found, this is set to nil.
///
/// @param verdef_section the SHT_GNU_verdef section found.  If the
/// section wasn't found, this is set to nil.
///
/// @param verneed_section the SHT_GNU_verneed section found.  If the
/// section wasn't found, this is set to nil.
///
/// @return true iff at least one of the sections where found.
bool
get_symbol_versionning_sections(Elf*		elf_handle,
				Elf_Scn*&	versym_section,
				Elf_Scn*&	verdef_section,
				Elf_Scn*&	verneed_section)
{
  Elf_Scn* section = NULL;
  GElf_Shdr mem;
  Elf_Scn* versym = NULL, *verdef = NULL, *verneed = NULL;

  while ((section = elf_nextscn(elf_handle, section)) != NULL)
    {
      GElf_Shdr* h = gelf_getshdr(section, &mem);
      if (h->sh_type == SHT_GNU_versym)
	versym = section;
      else if (h->sh_type == SHT_GNU_verdef)
	verdef = section;
      else if (h->sh_type == SHT_GNU_verneed)
	verneed = section;
    }

  if (versym || verdef || verneed)
    {
      // At least one the versionning sections was found.  Return it.
      versym_section = versym;
      verdef_section = verdef;
      verneed_section = verneed;
      return true;
    }

  return false;
}

/// Return the __ksymtab section of a linux kernel ELF file (either
/// a vmlinux binary or a kernel module).
///
/// @param elf_handle the elf handle to consider.
///
/// @return the __ksymtab section if found, nil otherwise.
Elf_Scn*
find_ksymtab_section(Elf* elf_handle)
{return find_section(elf_handle, "__ksymtab", SHT_PROGBITS);}

/// Return the __ksymtab_gpl section of a linux kernel ELF file (either
/// a vmlinux binary or a kernel module).
///
/// @param elf_handle the elf handle to consider.
///
/// @return the __ksymtab section if found, nil otherwise.
Elf_Scn*
find_ksymtab_gpl_section(Elf* elf_handle)
{return find_section(elf_handle, "__ksymtab_gpl", SHT_PROGBITS);}

/// Find the __ksymtab_strings section of a Linux kernel binary.
///
/// @param elf_handle the elf handle to use.
///
/// @return the find_ksymtab_strings_section of the linux kernel
/// binary denoted by @p elf_handle, or nil if such a section could
/// not be found.
Elf_Scn*
find_ksymtab_strings_section(Elf *elf_handle)
{
  if (is_linux_kernel(elf_handle))
    return find_section(elf_handle, "__ksymtab_strings", SHT_PROGBITS);
  return 0;
}

/// Return the .rel{a,} section corresponding to a given section.
///
/// @param elf_handle the elf handle to consider.
///
/// @param target_section the section to search the relocation section for
///
/// @return the .rel{a,} section if found, null otherwise.
Elf_Scn*
find_relocation_section(Elf* elf_handle, Elf_Scn* target_section)
{
  if (target_section)
    {
      // the relo section we are searching for has this index as sh_info
      size_t target_index = elf_ndxscn(target_section);

      // now iterate over all the sections, look for relocation sections and
      // find the one that points to the section we are searching for
      Elf_Scn*	section = 0;
      GElf_Shdr header_mem, *header;
      while ((section = elf_nextscn(elf_handle, section)) != 0)
	{
	  header = gelf_getshdr(section, &header_mem);
	  if (header == NULL
	      || (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
	    continue;

	  if (header->sh_info == target_index)
	    return section;
	}
    }
  return NULL;
}

/// Return the string table used by the given symbol table.
///
/// @param elf_handle the elf handle to use.
///
/// @param symtab_section section containing a symbol table.
///
/// @return the string table linked by the symtab, if it is not NULL.
Elf_Scn*
find_strtab_for_symtab_section(Elf* elf_handle, Elf_Scn* symtab_section)
{
  Elf_Scn *strtab_section = NULL;

  if (symtab_section)
    {
      GElf_Shdr symtab_shdr_mem, *symtab_shdr;

      symtab_shdr = gelf_getshdr(symtab_section, &symtab_shdr_mem);
      strtab_section = elf_getscn(elf_handle, symtab_shdr->sh_link);
    }

  return strtab_section;
}

/// Get the version definition (from the SHT_GNU_verdef section) of a
/// given symbol represented by a pointer to GElf_Versym.
///
/// @param elf_hande the elf handle to use.
///
/// @param versym the symbol to get the version definition for.
///
/// @param verdef_section the SHT_GNU_verdef section.
///
/// @param version the resulting version definition.  This is set iff
/// the function returns true.
///
/// @return true upon successful completion, false otherwise.
bool
get_version_definition_for_versym(Elf*			 elf_handle,
				  GElf_Versym*		 versym,
				  Elf_Scn*		 verdef_section,
				  elf_symbol::version&	 version)
{
  Elf_Data* verdef_data = elf_getdata(verdef_section, NULL);
  GElf_Verdef verdef_mem;
  GElf_Verdef* verdef = gelf_getverdef(verdef_data, 0, &verdef_mem);
  size_t vd_offset = 0;

  for (;; vd_offset += verdef->vd_next)
    {
      for (;verdef != 0;)
	{
	  if (verdef->vd_ndx == (*versym & 0x7fff))
	    // Found the version of the symbol.
	    break;
	  vd_offset += verdef->vd_next;
	  verdef = (verdef->vd_next == 0
		    ? 0
		    : gelf_getverdef(verdef_data, vd_offset, &verdef_mem));
	}

      if (verdef != 0)
	{
	  GElf_Verdaux verdaux_mem;
	  GElf_Verdaux *verdaux = gelf_getverdaux(verdef_data,
						  vd_offset + verdef->vd_aux,
						  &verdaux_mem);
	  GElf_Shdr header_mem;
	  GElf_Shdr* verdef_section_header = gelf_getshdr(verdef_section,
							  &header_mem);
	  size_t verdef_stridx = verdef_section_header->sh_link;
	  version.str(elf_strptr(elf_handle, verdef_stridx, verdaux->vda_name));
	  if (*versym & 0x8000)
	    version.is_default(false);
	  else
	    version.is_default(true);
	  return true;
	}
      if (!verdef || verdef->vd_next == 0)
	break;
    }
  return false;
}

/// Get the version needed (from the SHT_GNU_verneed section) to
/// resolve an undefined symbol represented by a pointer to
/// GElf_Versym.
///
/// @param elf_hande the elf handle to use.
///
/// @param versym the symbol to get the version definition for.
///
/// @param verneed_section the SHT_GNU_verneed section.
///
/// @param version the resulting version definition.  This is set iff
/// the function returns true.
///
/// @return true upon successful completion, false otherwise.
bool
get_version_needed_for_versym(Elf*			elf_handle,
			      GElf_Versym*		versym,
			      Elf_Scn*			verneed_section,
			      elf_symbol::version&	version)
{
  if (versym == 0 || elf_handle == 0 || verneed_section == 0)
    return false;

  size_t vn_offset = 0;
  Elf_Data* verneed_data = elf_getdata(verneed_section, NULL);
  GElf_Verneed verneed_mem;
  GElf_Verneed* verneed = gelf_getverneed(verneed_data, 0, &verneed_mem);

  for (;verneed; vn_offset += verneed->vn_next)
    {
      size_t vna_offset = vn_offset;
      GElf_Vernaux vernaux_mem;
      GElf_Vernaux *vernaux = gelf_getvernaux(verneed_data,
					      vn_offset + verneed->vn_aux,
					      &vernaux_mem);
      for (;vernaux != 0 && verneed;)
	{
	  if (vernaux->vna_other == *versym)
	    // Found the version of the symbol.
	    break;
	  vna_offset += verneed->vn_next;
	  verneed = (verneed->vn_next == 0
		     ? 0
		     : gelf_getverneed(verneed_data, vna_offset, &verneed_mem));
	}

      if (verneed != 0 && vernaux != 0 && vernaux->vna_other == *versym)
	{
	  GElf_Shdr header_mem;
	  GElf_Shdr* verneed_section_header = gelf_getshdr(verneed_section,
							   &header_mem);
	  size_t verneed_stridx = verneed_section_header->sh_link;
	  version.str(elf_strptr(elf_handle,
				 verneed_stridx,
				 vernaux->vna_name));
	  if (*versym & 0x8000)
	    version.is_default(false);
	  else
	    version.is_default(true);
	  return true;
	}

      if (!verneed || verneed->vn_next == 0)
	break;
    }
  return false;
}

/// Return the version for a symbol that is at a given index in its
/// SHT_SYMTAB section.
///
/// @param elf_handle the elf handle to use.
///
/// @param symbol_index the index of the symbol to consider.
///
/// @param get_def_version if this is true, it means that that we want
/// the version for a defined symbol; in that case, the version is
/// looked for in a section of type SHT_GNU_verdef.  Otherwise, if
/// this parameter is false, this means that we want the version for
/// an undefined symbol; in that case, the version is the needed one
/// for the symbol to be resolved; so the version is looked fo in a
/// section of type SHT_GNU_verneed.
///
/// @param version the version found for symbol at @p symbol_index.
///
/// @return true iff a version was found for symbol at index @p
/// symbol_index.
bool
get_version_for_symbol(Elf*			elf_handle,
		       size_t			symbol_index,
		       bool			get_def_version,
		       elf_symbol::version&	version)
{
  Elf_Scn *versym_section = NULL,
    *verdef_section = NULL,
    *verneed_section = NULL;

  if (!get_symbol_versionning_sections(elf_handle,
				       versym_section,
				       verdef_section,
				       verneed_section))
    return false;

  GElf_Versym versym_mem;
  Elf_Data* versym_data = (versym_section)
    ? elf_getdata(versym_section, NULL)
    : NULL;
  GElf_Versym* versym = (versym_data)
    ? gelf_getversym(versym_data, symbol_index, &versym_mem)
    : NULL;

  if (versym == 0 || *versym <= 1)
    // I got these value from the code of readelf.c in elfutils.
    // Apparently, if the symbol version entry has these values, the
    // symbol must be discarded. This is not documented in the
    // official specification.
    return false;

  if (get_def_version)
    {
      if (*versym == 0x8001)
	// I got this value from the code of readelf.c in elfutils
	// too.  It's not really documented in the official
	// specification.
	return false;

      if (verdef_section
	  && get_version_definition_for_versym(elf_handle, versym,
					       verdef_section, version))
	return true;
    }
  else
    {
      if (verneed_section
	  && get_version_needed_for_versym(elf_handle, versym,
					   verneed_section, version))
	return true;
    }

  return false;
}

/// Return the CRC from the "__crc_" symbol.
///
/// @param elf_handle the elf handle to use.
///
/// @param crc_symbol symbol containing CRC value.
///
/// @param crc_value the CRC found for @p crc_symbol.
///
/// @return true iff a CRC was found for given @p crc_symbol.
bool
get_crc_for_symbol(Elf* elf_handle, GElf_Sym* crc_symbol, uint32_t& crc_value)
{
  size_t crc_section_index = crc_symbol->st_shndx;
  GElf_Addr crc_symbol_address =
      maybe_adjust_et_rel_sym_addr_to_abs_addr(elf_handle, crc_symbol);
  if (crc_section_index == SHN_ABS)
    {
      crc_value = crc_symbol_address;
      return true;
    }

  Elf_Scn* kcrctab_section = elf_getscn(elf_handle, crc_section_index);
  if (kcrctab_section == NULL)
      return false;

  GElf_Shdr sheader_mem;
  GElf_Shdr* sheader = gelf_getshdr(kcrctab_section, &sheader_mem);
  if (sheader == NULL)
    return false;

  Elf_Data* kcrctab_data = elf_rawdata(kcrctab_section, NULL);
  if (kcrctab_data == NULL)
    return false;

  if (crc_symbol_address < sheader->sh_addr)
    return false;

  size_t offset = crc_symbol_address - sheader->sh_addr;
  if (offset + sizeof(uint32_t) > kcrctab_data->d_size
      || offset + sizeof(uint32_t) > sheader->sh_size)
    return false;

  crc_value = *reinterpret_cast<uint32_t*>(
      reinterpret_cast<char*>(kcrctab_data->d_buf) + offset);

  return true;
}

/// Test if the architecture of the current binary is ppc64.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the architecture of the current binary is ppc64.
bool
architecture_is_ppc64(Elf* elf_handle)
{
  GElf_Ehdr  eh_mem;
  GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
  return (elf_header && elf_header->e_machine == EM_PPC64);
}

/// Test if the architecture of the current binary is ppc32.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the architecture of the current binary is ppc32.
bool
architecture_is_ppc32(Elf* elf_handle)
{
  GElf_Ehdr  eh_mem;
  GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
  return (elf_header && elf_header->e_machine == EM_PPC);
}

/// Test if the architecture of the current binary is arm32.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the architecture of the current binary is arm32.
bool
architecture_is_arm32(Elf* elf_handle)
{
  GElf_Ehdr  eh_mem;
  GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
  return (elf_header && elf_header->e_machine == EM_ARM);
}

/// Test if the architecture of the current binary is arm64.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the architecture of the current binary is arm64.
bool
architecture_is_arm64(Elf* elf_handle)
{
#ifdef HAVE_EM_AARCH64_MACRO
  GElf_Ehdr  eh_mem;
  GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem);
  return (elf_header && elf_header->e_machine == EM_AARCH64);
#else
  return false;
#endif
}

/// Test if the endianness of the current binary is Big Endian.
///
/// https://en.wikipedia.org/wiki/Endianness.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the current binary is Big Endian.
bool
architecture_is_big_endian(Elf* elf_handle)
{
  GElf_Ehdr  elf_header;
  gelf_getehdr(elf_handle, &elf_header);

  bool is_big_endian = (elf_header.e_ident[EI_DATA] == ELFDATA2MSB);

  if (!is_big_endian)
    ABG_ASSERT(elf_header.e_ident[EI_DATA] == ELFDATA2LSB);

  return is_big_endian;
}

/// Read N bytes and convert their value into an integer type T.
///
/// Note that N cannot be bigger than 8 for now. The type passed needs to be at
/// least of the size of number_of_bytes.
///
/// @param bytes the array of bytes to read the next 8 bytes from.
/// Note that this array must be at least 8 bytes long.
///
/// @param number_of_bytes the number of bytes to read.  This number
/// cannot be bigger than 8.
///
/// @param is_big_endian if true, read the 8 bytes in Big Endian
/// mode, otherwise, read them in Little Endian.
///
/// @param result where to store the resuting integer that was read.
///
///
/// @param true if the 8 bytes could be read, false otherwise.
template <typename T>
bool
read_int_from_array_of_bytes(const uint8_t* bytes,
			     unsigned char  number_of_bytes,
			     bool	    is_big_endian,
			     T&		    result)
{
  if (!bytes)
    return false;

  ABG_ASSERT(number_of_bytes <= 8);
  ABG_ASSERT(number_of_bytes <= sizeof(T));

  T res = 0;

  const uint8_t* cur = bytes;
  if (is_big_endian)
    {
      // In Big Endian, the most significant byte is at the lowest
      // address.
      const uint8_t* msb = cur;
      res = *msb;

      // Now read the remaining least significant bytes.
      for (uint i = 1; i < number_of_bytes; ++i)
	res = (res << 8) | ((T)msb[i]);
    }
  else
    {
      // In Little Endian, the least significant byte is at the
      // lowest address.
      const uint8_t* lsb = cur;
      res = *lsb;
      // Now read the remaining most significant bytes.
      for (uint i = 1; i < number_of_bytes; ++i)
	res = res | (((T)lsb[i]) << i * 8);
    }

  result = res;
  return true;
}

/// Read 8 bytes and convert their value into an uint64_t.
///
/// @param bytes the array of bytes to read the next 8 bytes from.
/// Note that this array must be at least 8 bytes long.
///
/// @param result where to store the resuting uint64_t that was read.
///
/// @param is_big_endian if true, read the 8 bytes in Big Endian
/// mode, otherwise, read them in Little Endian.
///
/// @param true if the 8 bytes could be read, false otherwise.
bool
read_uint64_from_array_of_bytes(const uint8_t* bytes,
				bool	       is_big_endian,
				uint64_t&      result)
{
  return read_int_from_array_of_bytes(bytes, 8, is_big_endian, result);
}


/// Lookup the address of the function entry point that corresponds
/// to the address of a given function descriptor.
///
/// On PPC64, a function pointer is the address of a function
/// descriptor.  Function descriptors are located in the .opd
/// section.  Each function descriptor is a triplet of three
/// addresses, each one on 64 bits.  Among those three address only
/// the first one is of any interest to us: the address of the entry
/// point of the function.
///
/// This function returns the address of the entry point of the
/// function whose descriptor's address is given.
///
/// http://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUNC-DES
///
/// https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/deeply_understand_64_bit_powerpc_elf_abi_function_descriptors?lang=en
///
/// @param fn_desc_address the address of the function descriptor to
/// consider.
///
/// @return the address of the entry point of the function whose
/// descriptor has the address @p fn_desc_address.  If there is no
/// .opd section (e.g because we are not on ppc64) or more generally
/// if the function descriptor could not be found then this function
/// just returns the address of the fuction descriptor.
GElf_Addr
lookup_ppc64_elf_fn_entry_point_address(Elf* elf_handle, GElf_Addr fn_desc_address)
{
  if (!elf_handle)
    return fn_desc_address;

  if (!architecture_is_ppc64(elf_handle))
    return fn_desc_address;

  bool is_big_endian = architecture_is_big_endian(elf_handle);

  Elf_Scn* opd_section = find_opd_section(elf_handle);
  if (!opd_section)
    return fn_desc_address;

  GElf_Shdr header_mem;
  // The section header of the .opd section.
  GElf_Shdr* opd_sheader = gelf_getshdr(opd_section, &header_mem);

  // The offset of the function descriptor entry, in the .opd
  // section.
  size_t    fn_desc_offset = fn_desc_address - opd_sheader->sh_addr;
  Elf_Data* elf_data = elf_rawdata(opd_section, 0);

  // Ensure that the opd_section has at least 8 bytes, starting from
  // the offset we want read the data from.
  if (elf_data->d_size <= fn_desc_offset + 8)
    return fn_desc_address;

  // A pointer to the data of the .opd section, that we can actually
  // do something with.
  uint8_t* bytes = (uint8_t*)elf_data->d_buf;

  // The resulting address we are looking for is going to be formed
  // in this variable.
  GElf_Addr result = 0;
  ABG_ASSERT(read_uint64_from_array_of_bytes(bytes + fn_desc_offset,
					     is_big_endian, result));

  return result;
}

/// Test if the ELF binary denoted by a given ELF handle is a Linux
/// Kernel Module.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the binary denoted by @p elf_handle is a Linux
/// kernel module.
bool
is_linux_kernel_module(Elf *elf_handle)
{
  return (find_section(elf_handle, ".modinfo", SHT_PROGBITS)
	  && find_section(elf_handle,
			  ".gnu.linkonce.this_module",
			  SHT_PROGBITS));
}

/// Test if the ELF binary denoted by a given ELF handle is a Linux
/// Kernel binary (either vmlinux or a kernel module).
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the binary denoted by @p elf_handle is a Linux
/// kernel binary
bool
is_linux_kernel(Elf *elf_handle)
{
  return (find_section(elf_handle,
		       "__ksymtab_strings",
		       SHT_PROGBITS)
	  || is_linux_kernel_module(elf_handle));
}

/// Get the address at which a given binary is loaded in memory.
///
/// @param elf_handle the elf handle for the binary to consider.
///
/// @param load_address the address where the binary is loaded.  This
/// is set by the function iff it returns true.
///
/// @return true if the function could get the binary load address
/// and assign @p load_address to it.
bool
get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address)
{
  GElf_Ehdr elf_header;
  gelf_getehdr(elf_handle, &elf_header);
  size_t num_segments = elf_header.e_phnum;
  GElf_Phdr *program_header = NULL;
  GElf_Addr result;
  bool found_loaded_segment = false;
  GElf_Phdr ph_mem;

  for (unsigned i = 0; i < num_segments; ++i)
    {
      program_header = gelf_getphdr(elf_handle, i, &ph_mem);
      if (program_header && program_header->p_type == PT_LOAD)
	{
	  if (!found_loaded_segment)
	    {
	      result = program_header->p_vaddr;
	      found_loaded_segment = true;
	    }

	  if (program_header->p_vaddr < result)
	    // The resulting load address we want is the lowest
	    // load address of all the loaded segments.
	    result = program_header->p_vaddr;
	}
    }

  if (found_loaded_segment)
    {
      load_address = result;
      return true;
    }
  return false;
}

/// Return the size of a word for the current architecture.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return the size of a word.
unsigned char
get_architecture_word_size(Elf* elf_handle)
{
  unsigned char word_size = 0;
  GElf_Ehdr	elf_header;
  gelf_getehdr(elf_handle, &elf_header);
  if (elf_header.e_ident[EI_CLASS] == ELFCLASS32)
    word_size = 4;
  else if (elf_header.e_ident[EI_CLASS] == ELFCLASS64)
    word_size = 8;
  else
    ABG_ASSERT_NOT_REACHED;
  return word_size;
}

/// Test if the elf file being read is an executable.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the elf file being read is an / executable.
bool
is_executable(Elf* elf_handle)
{
  GElf_Ehdr  elf_header;
  gelf_getehdr(elf_handle, &elf_header);
  return elf_header.e_type == ET_EXEC;
}

/// Test if the elf file being read is a dynamic shared / object.
///
/// @param elf_handle the ELF handle to consider.
///
/// @return true iff the elf file being read is a / dynamic shared object.
bool
is_dso(Elf* elf_handle)
{
  GElf_Ehdr  elf_header;
  gelf_getehdr(elf_handle, &elf_header);
  return elf_header.e_type == ET_DYN;
}

/// Translate a section-relative symbol address (i.e, symbol value)
/// into an absolute symbol address by adding the address of the
/// section the symbol belongs to, to the address value.
///
/// This is useful when looking at symbol values coming from
/// relocatable files (of ET_REL kind).  If the binary is not
/// ET_REL, then the function does nothing and returns the input
/// address unchanged.
///
/// @param elf_handle the elf handle for the binary to consider.
///
/// @param sym the symbol whose address to possibly needs to be
/// translated.
///
/// @return the section-relative address, translated into an
/// absolute address, if @p sym is from an ET_REL binary.
/// Otherwise, return the address of @p sym, unchanged.
GElf_Addr
maybe_adjust_et_rel_sym_addr_to_abs_addr(Elf* elf_handle, GElf_Sym* sym)
{
  Elf_Scn*  symbol_section = elf_getscn(elf_handle, sym->st_shndx);
  GElf_Addr addr = sym->st_value;

  if (!symbol_section)
    return addr;

  GElf_Ehdr elf_header;
  if (!gelf_getehdr(elf_handle, &elf_header))
    return addr;

  if (elf_header.e_type != ET_REL)
    return addr;

  GElf_Shdr section_header;
  if (!gelf_getshdr(symbol_section, &section_header))
    return addr;

  return addr + section_header.sh_addr;
}

/// Test if a given address is in a given section.
///
/// @param addr the address to consider.
///
/// @param section the section to consider.
///
/// @return true iff @p addr is in section @p section.
bool
address_is_in_section(Dwarf_Addr addr, Elf_Scn* section)
{
  if (!section)
    return false;

  GElf_Shdr  sheader_mem;
  GElf_Shdr* sheader = gelf_getshdr(section, &sheader_mem);

  if (sheader->sh_addr <= addr && addr <= sheader->sh_addr + sheader->sh_size)
    return true;

  return false;
}

/// Return true if an address is in the ".opd" section that is
/// present on the ppc64 platform.
///
/// @param addr the address to consider.
///
/// @return true iff @p addr designates a word that is in the ".opd"
/// section.
bool
address_is_in_opd_section(Elf* elf_handle, Dwarf_Addr addr)
{
  Elf_Scn * opd_section = find_opd_section(elf_handle);
  if (!opd_section)
    return false;
  if (address_is_in_section(addr, opd_section))
    return true;
  return false;
}

/// Get data tag information of an ELF file by looking up into its
/// dynamic segment
///
/// @param elf the elf handle to use for the query.
///
/// @param dt_tag data tag to look for in dynamic segment
/// @param dt_tag_data vector of found information for a given @p data_tag
///
/// @return true iff data tag @p data_tag was found
bool
lookup_data_tag_from_dynamic_segment(Elf*                       elf,
                                     Elf64_Sxword               data_tag,
                                     vector<string>&            dt_tag_data)
{
  size_t num_prog_headers = 0;
  bool found = false;
  if (elf_getphdrnum(elf, &num_prog_headers) < 0)
    return found;

  // Cycle through each program header.
  for (size_t i = 0; i < num_prog_headers; ++i)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr *phdr = gelf_getphdr(elf, i, &phdr_mem);
      if (phdr == NULL || phdr->p_type != PT_DYNAMIC)
        continue;

      // Poke at the dynamic segment like a section, so that we can
      // get its section header information; also we'd like to read
      // the data of the segment by using elf_getdata() but that
      // function needs a Elf_Scn data structure to act on.
      // Elfutils doesn't really have any particular function to
      // access segment data, other than the functions used to
      // access section data.
      Elf_Scn *dynamic_section = gelf_offscn(elf, phdr->p_offset);
      GElf_Shdr  shdr_mem;
      GElf_Shdr *dynamic_section_header = gelf_getshdr(dynamic_section,
						       &shdr_mem);
      if (dynamic_section_header == NULL
          || dynamic_section_header->sh_type != SHT_DYNAMIC)
        continue;

      // Get data of the dynamic segment (seen as a section).
      Elf_Data *data = elf_getdata(dynamic_section, NULL);
      if (data == NULL)
        continue;

      // Get the index of the section headers string table.
      size_t string_table_index = 0;
      ABG_ASSERT (elf_getshdrstrndx(elf, &string_table_index) >= 0);

      size_t dynamic_section_header_entry_size = gelf_fsize(elf,
                                                            ELF_T_DYN, 1,
                                                            EV_CURRENT);

      GElf_Shdr link_mem;
      GElf_Shdr *link =
        gelf_getshdr(elf_getscn(elf,
                                dynamic_section_header->sh_link),
		     &link_mem);
      ABG_ASSERT(link != NULL);

      size_t num_dynamic_section_entries =
        dynamic_section_header->sh_size / dynamic_section_header_entry_size;

      // Now walk through all the DT_* data tags that are in the
      // segment/section
      for (size_t j = 0; j < num_dynamic_section_entries; ++j)
        {
          GElf_Dyn dynamic_section_mem;
          GElf_Dyn *dynamic_section = gelf_getdyn(data,
                                                  j,
                                                  &dynamic_section_mem);
          if (dynamic_section->d_tag == data_tag)
            {
              dt_tag_data.push_back(elf_strptr(elf,
                                               dynamic_section_header->sh_link,
					       dynamic_section->d_un.d_val));
              found = true;
            }
        }
    }
  return found;
}

const Dwfl_Callbacks&
initialize_dwfl_callbacks(Dwfl_Callbacks& cb,
			  char** debug_info_root_path)
{
  cb.find_debuginfo = dwfl_standard_find_debuginfo;
  cb.section_address = dwfl_offline_section_address;
  cb.debuginfo_path = debug_info_root_path;
  return cb;
}

dwfl_sptr
create_new_dwfl_handle(Dwfl_Callbacks& cb)
{
  dwfl_sptr handle(dwfl_begin(&cb), dwfl_deleter());
  return handle;
}

/// Fetch the SONAME ELF property from an ELF binary file.
///
/// @param path The path to the elf file to consider.
///
/// @param soname out parameter. Set to the SONAME property of the
/// binary file, if it present in the ELF file.
///
/// return false if an error occured while looking for the SONAME
/// property in the binary, true otherwise.
bool
get_soname_of_elf_file(const string& path, string &soname)
{

  int fd = open(path.c_str(), O_RDONLY);
  if (fd == -1)
    return false;

  elf_version (EV_CURRENT);
  Elf* elf = elf_begin (fd, ELF_C_READ_MMAP, NULL);

  GElf_Ehdr ehdr_mem;
  GElf_Ehdr* ehdr = gelf_getehdr (elf, &ehdr_mem);
  if (ehdr == NULL)
    return false;

  for (int i = 0; i < ehdr->e_phnum; ++i)
    {
      GElf_Phdr phdr_mem;
      GElf_Phdr* phdr = gelf_getphdr (elf, i, &phdr_mem);

      if (phdr != NULL && phdr->p_type == PT_DYNAMIC)
        {
          Elf_Scn* scn = gelf_offscn (elf, phdr->p_offset);
          GElf_Shdr shdr_mem;
          GElf_Shdr* shdr = gelf_getshdr (scn, &shdr_mem);
	  if (!(shdr == NULL || (shdr->sh_type == SHT_DYNAMIC
				 || shdr->sh_type == SHT_PROGBITS)))
	    // This program header doesn't look like one we are
	    // looking for.  Skip to the next.
	    continue;

          size_t entsize = (shdr != NULL && shdr->sh_entsize != 0
                            ? shdr->sh_entsize
                            : gelf_fsize (elf, ELF_T_DYN, 1, EV_CURRENT));
          int maxcnt = (shdr != NULL
                        ? shdr->sh_size / entsize : INT_MAX);
          Elf_Data* data = elf_getdata (scn, NULL);
          if (data == NULL)
            break;

          for (int cnt = 0; cnt < maxcnt; ++cnt)
            {
              GElf_Dyn dynmem;
              GElf_Dyn* dyn = gelf_getdyn (data, cnt, &dynmem);
              if (dyn == NULL)
                continue;

              if (dyn->d_tag == DT_NULL)
                break;

              if (dyn->d_tag != DT_SONAME)
                continue;

              soname = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
              break;
            }
          break;
        }
    }

  elf_end(elf);
  close(fd);

  return true;
}

} // end namespace elf_helpers
} // end namespace abigail
