[v2,2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader

Message ID 20200421063551.222511-3-maennich@google.com
State Committed
Headers
Series Refactor dwarf-reader: split out ELF helpers |

Commit Message

Matthias Männich April 21, 2020, 6:35 a.m. UTC
  Move some definitions from abg-dwarf-reader to abg-elf-helpers that are
strictly only related to ELF.

    * abg-dwarf-reader.cc(stt_to_elf_symbol_type): Move function out.
    (stb_to_elf_symbol_binding): Likewise.
    (stv_to_elf_symbol_visibility): Likewise.
    (e_machine_to_string): Likewise.
    (find_section): Likewise.
    (find_symbol_table_section): Likewise.
    (find_symbol_table_section_index): Likewise.
    (enum hash_table_kind): Likewise.
    (find_hash_table_section_index): Likewise.
    (get_symbol_versionning_sections): Likewise.
    (find_text_section): Likewise.
    (find_bss_section): Likewise.
    (find_rodata_section): Likewise.
    (find_data_section): Likewise.
    (find_data1_section): Likewise.
    * abg-elf-helpers.cc(stt_to_elf_symbol_type): Move function in.
    (stb_to_elf_symbol_binding): Likewise.
    (stv_to_elf_symbol_visibility): Likewise.
    (e_machine_to_string): Likewise.
    (find_section): Likewise.
    (find_symbol_table_section): Likewise.
    (find_symbol_table_section_index): Likewise.
    (enum hash_table_kind): Likewise.
    (find_hash_table_section_index): Likewise.
    (get_symbol_versionning_sections): Likewise.
    (find_text_section): Likewise.
    (find_bss_section): Likewise.
    (find_rodata_section): Likewise.
    (find_data_section): Likewise.
    (find_data1_section): Likewise.
    * abg-elf-helpers.h(stt_to_elf_symbol_type): Add declaration.
    (stb_to_elf_symbol_binding): Likewise.
    (stv_to_elf_symbol_visibility): Likewise.
    (e_machine_to_string): Likewise.
    (find_section): Likewise.
    (find_symbol_table_section): Likewise.
    (find_symbol_table_section_index): Likewise.
    (enum hash_table_kind): Likewise.
    (find_hash_table_section_index): Likewise.
    (get_symbol_versionning_sections): Likewise.
    (find_text_section): Likewise.
    (find_bss_section): Likewise.
    (find_rodata_section): Likewise.
    (find_data_section): Likewise.
    (find_data1_section): Likewise.

Reviewed-by: Giuliano Procida <gprocida@google.com>
Signed-off-by: Matthias Maennich <maennich@google.com>
---
 src/abg-dwarf-reader.cc | 594 +---------------------------------------
 src/abg-elf-helpers.cc  | 471 +++++++++++++++++++++++++++++++
 src/abg-elf-helpers.h   |  65 +++++
 3 files changed, 540 insertions(+), 590 deletions(-)
  

Comments

Dodji Seketeli April 22, 2020, 9:44 a.m. UTC | #1
Matthias Maennich <maennich@google.com> a ?crit:

> Move some definitions from abg-dwarf-reader to abg-elf-helpers that are
> strictly only related to ELF.
>
>     * abg-dwarf-reader.cc(stt_to_elf_symbol_type): Move function out.
>     (stb_to_elf_symbol_binding): Likewise.
>     (stv_to_elf_symbol_visibility): Likewise.
>     (e_machine_to_string): Likewise.
>     (find_section): Likewise.
>     (find_symbol_table_section): Likewise.
>     (find_symbol_table_section_index): Likewise.
>     (enum hash_table_kind): Likewise.
>     (find_hash_table_section_index): Likewise.
>     (get_symbol_versionning_sections): Likewise.
>     (find_text_section): Likewise.
>     (find_bss_section): Likewise.
>     (find_rodata_section): Likewise.
>     (find_data_section): Likewise.
>     (find_data1_section): Likewise.
>     * abg-elf-helpers.cc(stt_to_elf_symbol_type): Move function in.
>     (stb_to_elf_symbol_binding): Likewise.
>     (stv_to_elf_symbol_visibility): Likewise.
>     (e_machine_to_string): Likewise.
>     (find_section): Likewise.
>     (find_symbol_table_section): Likewise.
>     (find_symbol_table_section_index): Likewise.
>     (enum hash_table_kind): Likewise.
>     (find_hash_table_section_index): Likewise.
>     (get_symbol_versionning_sections): Likewise.
>     (find_text_section): Likewise.
>     (find_bss_section): Likewise.
>     (find_rodata_section): Likewise.
>     (find_data_section): Likewise.
>     (find_data1_section): Likewise.
>     * abg-elf-helpers.h(stt_to_elf_symbol_type): Add declaration.
>     (stb_to_elf_symbol_binding): Likewise.
>     (stv_to_elf_symbol_visibility): Likewise.
>     (e_machine_to_string): Likewise.
>     (find_section): Likewise.
>     (find_symbol_table_section): Likewise.
>     (find_symbol_table_section_index): Likewise.
>     (enum hash_table_kind): Likewise.
>     (find_hash_table_section_index): Likewise.
>     (get_symbol_versionning_sections): Likewise.
>     (find_text_section): Likewise.
>     (find_bss_section): Likewise.
>     (find_rodata_section): Likewise.
>     (find_data_section): Likewise.
>     (find_data1_section): Likewise.

I have just tabified this ChangeLog, added a white space in e.g:

>     * abg-dwarf-reader.cc(stt_to_elf_symbol_type): Move function out.

To make:

	* abg-dwarf-reader.cc (stt_to_elf_symbol_type): Move function out.

Applying to master.  Thanks!

Cheers,
  

Patch

diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
index 1c0d6ea0353f..6ec7e4b6e968 100644
--- a/src/abg-dwarf-reader.cc
+++ b/src/abg-dwarf-reader.cc
@@ -50,6 +50,8 @@ 
 #include "abg-suppression-priv.h"
 #include "abg-corpus-priv.h"
 
+#include "abg-elf-helpers.h"
+
 #include "abg-internal.h"
 // <headers defining libabigail's API go under here>
 ABG_BEGIN_EXPORT_DECLARATIONS
@@ -84,6 +86,8 @@  using std::stack;
 using std::deque;
 using std::list;
 
+using namespace elf_helpers; // TODO: avoid using namespace
+
 /// Where a DIE comes from. For instance, a DIE can come from the main
 /// debug info section, the alternate debug info section or from the
 /// type unit section.
@@ -290,9 +294,6 @@  static void
 add_symbol_to_map(const elf_symbol_sptr& sym,
 		  string_elf_symbols_map_type& map);
 
-static bool
-find_symbol_table_section(Elf* elf_handle, Elf_Scn*& section);
-
 static bool
 get_symbol_versionning_sections(Elf*		elf_handle,
 				Elf_Scn*&	versym_section,
@@ -546,548 +547,6 @@  compare_dies(const read_context& ctxt,
 	     const Dwarf_Die *l, const Dwarf_Die *r,
 	     bool update_canonical_dies_on_the_fly);
 
-/// 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.
-static elf_symbol::type
-stt_to_elf_symbol_type(unsigned char stt)
-{
-  elf_symbol::type t = elf_symbol::NOTYPE_TYPE;
-
-  switch (stt)
-    {
-    case STT_NOTYPE:
-      t = elf_symbol::NOTYPE_TYPE;
-      break;
-    case STT_OBJECT:
-      t = elf_symbol::OBJECT_TYPE;
-      break;
-    case STT_FUNC:
-      t = elf_symbol::FUNC_TYPE;
-      break;
-    case STT_SECTION:
-      t = elf_symbol::SECTION_TYPE;
-      break;
-    case STT_FILE:
-      t = elf_symbol::FILE_TYPE;
-      break;
-    case STT_COMMON:
-      t = elf_symbol::COMMON_TYPE;
-      break;
-    case STT_TLS:
-      t = elf_symbol::TLS_TYPE;
-      break;
-    case STT_GNU_IFUNC:
-      t = elf_symbol::GNU_IFUNC_TYPE;
-      break;
-    default:
-      // An unknown value that probably ought to be supported?  Let's
-      // abort right here rather than yielding garbage.
-      ABG_ASSERT_NOT_REACHED;
-    }
-
-  return t;
-}
-
-/// 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.
-static elf_symbol::binding
-stb_to_elf_symbol_binding(unsigned char stb)
-{
-  elf_symbol::binding b = elf_symbol::GLOBAL_BINDING;
-
-  switch (stb)
-    {
-    case STB_LOCAL:
-      b = elf_symbol::LOCAL_BINDING;
-      break;
-    case STB_GLOBAL:
-      b = elf_symbol::GLOBAL_BINDING;
-      break;
-    case STB_WEAK:
-      b = elf_symbol::WEAK_BINDING;
-      break;
-    case STB_GNU_UNIQUE:
-      b = elf_symbol::GNU_UNIQUE_BINDING;
-      break;
-    default:
-      ABG_ASSERT_NOT_REACHED;
-    }
-
-  return b;
-
-}
-
-/// 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.
-static elf_symbol::visibility
-stv_to_elf_symbol_visibility(unsigned char stv)
-{
-
-  elf_symbol::visibility v = elf_symbol::DEFAULT_VISIBILITY;
-
-  switch (stv)
-    {
-    case STV_DEFAULT:
-      v = elf_symbol::DEFAULT_VISIBILITY;
-      break;
-    case STV_INTERNAL:
-      v = elf_symbol::INTERNAL_VISIBILITY;
-      break;
-    case STV_HIDDEN:
-      v = elf_symbol::HIDDEN_VISIBILITY;
-      break;
-    case STV_PROTECTED:
-      v = elf_symbol::PROTECTED_VISIBILITY;
-      break;
-    default:
-      ABG_ASSERT_NOT_REACHED;
-    }
-
-  return v;
-}
-
-/// 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.
-static string
-e_machine_to_string(GElf_Half e_machine)
-{
-  string result;
-  switch (e_machine)
-    {
-    case EM_NONE:
-      result = "elf-no-arch";
-      break;
-    case EM_M32:
-      result = "elf-att-we-32100";
-      break;
-    case EM_SPARC:
-      result = "elf-sun-sparc";
-      break;
-    case EM_386:
-      result = "elf-intel-80386";
-      break;
-    case EM_68K:
-      result = "elf-motorola-68k";
-      break;
-    case EM_88K:
-      result = "elf-motorola-88k";
-      break;
-    case EM_860:
-      result = "elf-intel-80860";
-      break;
-    case EM_MIPS:
-      result = "elf-mips-r3000-be";
-      break;
-    case EM_S370:
-      result = "elf-ibm-s370";
-      break;
-    case EM_MIPS_RS3_LE:
-      result = "elf-mips-r3000-le";
-      break;
-    case EM_PARISC:
-      result = "elf-hp-parisc";
-      break;
-    case EM_VPP500:
-      result = "elf-fujitsu-vpp500";
-      break;
-    case EM_SPARC32PLUS:
-      result = "elf-sun-sparc-v8plus";
-      break;
-    case EM_960:
-      result = "elf-intel-80960";
-      break;
-    case EM_PPC:
-      result = "elf-powerpc";
-      break;
-    case EM_PPC64:
-      result = "elf-powerpc-64";
-      break;
-    case EM_S390:
-      result = "elf-ibm-s390";
-      break;
-    case EM_V800:
-      result = "elf-nec-v800";
-      break;
-    case EM_FR20:
-      result = "elf-fujitsu-fr20";
-      break;
-    case EM_RH32:
-      result = "elf-trw-rh32";
-      break;
-    case EM_RCE:
-      result = "elf-motorola-rce";
-      break;
-    case EM_ARM:
-      result = "elf-arm";
-      break;
-    case EM_FAKE_ALPHA:
-      result = "elf-digital-alpha";
-      break;
-    case EM_SH:
-      result = "elf-hitachi-sh";
-      break;
-    case EM_SPARCV9:
-      result = "elf-sun-sparc-v9-64";
-      break;
-    case EM_TRICORE:
-      result = "elf-siemens-tricore";
-      break;
-    case EM_ARC:
-      result = "elf-argonaut-risc-core";
-      break;
-    case EM_H8_300:
-      result = "elf-hitachi-h8-300";
-      break;
-    case EM_H8_300H:
-      result = "elf-hitachi-h8-300h";
-      break;
-    case EM_H8S:
-      result = "elf-hitachi-h8s";
-      break;
-    case EM_H8_500:
-      result = "elf-hitachi-h8-500";
-      break;
-    case EM_IA_64:
-      result = "elf-intel-ia-64";
-      break;
-    case EM_MIPS_X:
-      result = "elf-stanford-mips-x";
-      break;
-    case EM_COLDFIRE:
-      result = "elf-motorola-coldfire";
-      break;
-    case EM_68HC12:
-      result = "elf-motorola-68hc12";
-      break;
-    case EM_MMA:
-      result = "elf-fujitsu-mma";
-      break;
-    case EM_PCP:
-      result = "elf-siemens-pcp";
-      break;
-    case EM_NCPU:
-      result = "elf-sony-ncpu";
-      break;
-    case EM_NDR1:
-      result = "elf-denso-ndr1";
-      break;
-    case EM_STARCORE:
-      result = "elf-motorola-starcore";
-      break;
-    case EM_ME16:
-      result = "elf-toyota-me16";
-      break;
-    case EM_ST100:
-      result = "elf-stm-st100";
-      break;
-    case EM_TINYJ:
-      result = "elf-alc-tinyj";
-      break;
-    case EM_X86_64:
-      result = "elf-amd-x86_64";
-      break;
-    case EM_PDSP:
-      result = "elf-sony-pdsp";
-      break;
-    case EM_FX66:
-      result = "elf-siemens-fx66";
-      break;
-    case EM_ST9PLUS:
-      result = "elf-stm-st9+";
-      break;
-    case EM_ST7:
-      result = "elf-stm-st7";
-      break;
-    case EM_68HC16:
-      result = "elf-motorola-68hc16";
-      break;
-    case EM_68HC11:
-      result = "elf-motorola-68hc11";
-      break;
-    case EM_68HC08:
-      result = "elf-motorola-68hc08";
-      break;
-    case EM_68HC05:
-      result = "elf-motorola-68hc05";
-      break;
-    case EM_SVX:
-      result = "elf-sg-svx";
-      break;
-    case EM_ST19:
-      result = "elf-stm-st19";
-      break;
-    case EM_VAX:
-      result = "elf-digital-vax";
-      break;
-    case EM_CRIS:
-      result = "elf-axis-cris";
-      break;
-    case EM_JAVELIN:
-      result = "elf-infineon-javelin";
-      break;
-    case EM_FIREPATH:
-      result = "elf-firepath";
-      break;
-    case EM_ZSP:
-      result = "elf-lsi-zsp";
-      break;
-    case EM_MMIX:
-      result = "elf-don-knuth-mmix";
-      break;
-    case EM_HUANY:
-      result = "elf-harvard-huany";
-      break;
-    case EM_PRISM:
-      result = "elf-sitera-prism";
-      break;
-    case EM_AVR:
-      result = "elf-atmel-avr";
-      break;
-    case EM_FR30:
-      result = "elf-fujistu-fr30";
-      break;
-    case EM_D10V:
-      result = "elf-mitsubishi-d10v";
-      break;
-    case EM_D30V:
-      result = "elf-mitsubishi-d30v";
-      break;
-    case EM_V850:
-      result = "elf-nec-v850";
-      break;
-    case EM_M32R:
-      result = "elf-mitsubishi-m32r";
-      break;
-    case EM_MN10300:
-      result = "elf-matsushita-mn10300";
-      break;
-    case EM_MN10200:
-      result = "elf-matsushita-mn10200";
-      break;
-    case EM_PJ:
-      result = "elf-picojava";
-      break;
-    case EM_OPENRISC:
-      result = "elf-openrisc-32";
-      break;
-    case EM_ARC_A5:
-      result = "elf-arc-a5";
-      break;
-    case EM_XTENSA:
-      result = "elf-tensilica-xtensa";
-      break;
-
-#ifdef HAVE_EM_AARCH64_MACRO
-    case EM_AARCH64:
-      result = "elf-arm-aarch64";
-      break;
-#endif
-
-#ifdef HAVE_EM_TILEPRO_MACRO
-    case EM_TILEPRO:
-      result = "elf-tilera-tilepro";
-      break;
-#endif
-
-#ifdef HAVE_EM_TILEGX_MACRO
-    case EM_TILEGX:
-      result = "elf-tilera-tilegx";
-      break;
-#endif
-
-    case EM_NUM:
-      result = "elf-last-arch-number";
-      break;
-    case EM_ALPHA:
-      result = "elf-non-official-alpha";
-      break;
-    default:
-      {
-	std::ostringstream o;
-	o << "elf-unknown-arch-value-" << e_machine;
-	result = o.str();
-      }
-      break;
-    }
-  return result;
-}
-
-/// The kind of ELF hash table found by the function
-/// find_hash_table_section_index.
-enum hash_table_kind
-{
-  NO_HASH_TABLE_KIND = 0,
-  SYSV_HASH_TABLE_KIND,
-  GNU_HASH_TABLE_KIND
-};
-
-/// 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.
-static 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 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 true iff the symbol table is found.
-static bool
-find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
-{
-  Elf_Scn* section = 0, *dynsym = 0, *sym_tab = 0;
-  while ((section = elf_nextscn(elf_handle, section)) != 0)
-    {
-      GElf_Shdr header_mem, *header;
-      header = gelf_getshdr(section, &header_mem);
-      if (header->sh_type == SHT_DYNSYM)
-	dynsym = section;
-      else if (header->sh_type == SHT_SYMTAB)
-	sym_tab = section;
-    }
-
-  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)
-	symtab = sym_tab ? sym_tab : dynsym;
-      else
-	symtab = dynsym ? dynsym : sym_tab;
-      return true;
-    }
-  return false;
-}
-
-/// 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.
-static bool
-find_symbol_table_section_index(Elf* elf_handle,
-				size_t& symtab_index)
-{
-  Elf_Scn* section = 0;
-  if (!find_symbol_table_section(elf_handle, section))
-    return false;
-
-  symtab_index = elf_ndxscn(section);
-  return true;
-}
-
-/// 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.
-static Elf_Scn*
-find_section(Elf* elf_handle, const 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;
-}
 
 /// Test if the ELF binary denoted by a given ELF handle is a Linux
 /// Kernel Module.
@@ -1121,51 +580,6 @@  binary_is_linux_kernel(Elf *elf_handle)
 	  || binary_is_linux_kernel_module(elf_handle));
 }
 
-/// Find and return the .text section.
-///
-/// @param elf_handle the elf handle to use.
-///
-/// @return the .text section found.
-static 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.
-static 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.
-static 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.
-static 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.
-static Elf_Scn*
-find_data1_section(Elf* elf_handle)
-{return find_section(elf_handle, ".data1", SHT_PROGBITS);}
-
 /// Find the __ksymtab_strings section of a Linux kernel binary.
 ///
 ///
diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
index e99fe4a5c306..b0113a4efd2c 100644
--- a/src/abg-elf-helpers.cc
+++ b/src/abg-elf-helpers.cc
@@ -24,11 +24,482 @@ 
 
 #include "abg-elf-helpers.h"
 
+#include <elf.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
+
+    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 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 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 true iff the symbol table is found.
+bool
+find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
+{
+  Elf_Scn* section = 0, *dynsym = 0, *sym_tab = 0;
+  while ((section = elf_nextscn(elf_handle, section)) != 0)
+    {
+      GElf_Shdr header_mem, *header;
+      header = gelf_getshdr(section, &header_mem);
+      if (header->sh_type == SHT_DYNSYM)
+	dynsym = section;
+      else if (header->sh_type == SHT_SYMTAB)
+	sym_tab = section;
+    }
+
+  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)
+	symtab = sym_tab ? sym_tab : dynsym;
+      else
+	symtab = dynsym ? dynsym : sym_tab;
+      return true;
+    }
+  return false;
+}
+
+/// 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 = 0;
+  if (!find_symbol_table_section(elf_handle, 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);}
+
+
 } // end namespace elf_helpers
 } // end namespace abigail
diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
index bffa46cc3c2d..58720da0fa9e 100644
--- a/src/abg-elf-helpers.h
+++ b/src/abg-elf-helpers.h
@@ -25,12 +25,77 @@ 
 #ifndef __ABG_ELF_HELPERS_H__
 #define __ABG_ELF_HELPERS_H__
 
+#include "config.h"
+
+#include <gelf.h>
+#include <string>
+
+#include "abg-ir.h"
+
 namespace abigail
 {
 
 namespace elf_helpers
 {
 
+//
+// ELF Value Converters
+//
+
+elf_symbol::type
+stt_to_elf_symbol_type(unsigned char stt);
+
+elf_symbol::binding
+stb_to_elf_symbol_binding(unsigned char stb);
+
+elf_symbol::visibility
+stv_to_elf_symbol_visibility(unsigned char stv);
+
+std::string
+e_machine_to_string(GElf_Half e_machine);
+
+//
+// ELF section helpers
+//
+
+Elf_Scn*
+find_section(Elf*		elf_handle,
+	     const std::string& name,
+	     Elf64_Word		section_type);
+
+bool
+find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab);
+
+bool
+find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index);
+
+enum hash_table_kind
+{
+  NO_HASH_TABLE_KIND = 0,
+  SYSV_HASH_TABLE_KIND,
+  GNU_HASH_TABLE_KIND
+};
+
+hash_table_kind
+find_hash_table_section_index(Elf*	elf_handle,
+			      size_t&	ht_section_index,
+			      size_t&	symtab_section_index);
+
+Elf_Scn*
+find_text_section(Elf* elf_handle);
+
+Elf_Scn*
+find_bss_section(Elf* elf_handle);
+
+Elf_Scn*
+find_rodata_section(Elf* elf_handle);
+
+Elf_Scn*
+find_data_section(Elf* elf_handle);
+
+Elf_Scn*
+find_data1_section(Elf* elf_handle);
+
 } // end namespace elf_helpers
 } // end namespace abigail