[2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader
Commit Message
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.cc(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.
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
Looks good.
On Mon, 20 Apr 2020 at 12:09, Matthias Maennich <maennich@google.com> wrote:
>
> 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.
Wrong file name.
> * abg-elf-helpers.cc(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(-)
>
> 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, §ion_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, §ion_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
>
> --
> 2.26.1.301.g55bc3eb7cb9-goog
>
@@ -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, §ion_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.
///
///
@@ -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, §ion_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
@@ -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