From patchwork Tue Apr 21 06:35:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Matthias_M=C3=A4nnich?= X-Patchwork-Id: 39114 From: maennich@google.com (Matthias Maennich) Date: Tue, 21 Apr 2020 08:35:50 +0200 Subject: [PATCH v2 7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers) In-Reply-To: <20200421063551.222511-1-maennich@google.com> References: <20200420110846.218792-1-maennich@google.com> <20200421063551.222511-1-maennich@google.com> Message-ID: <20200421063551.222511-8-maennich@google.com> This migrates more architecture specific helpers over to the elf-helpers. No functional change intended. * src/abg-dwarf-reader.cc(elf_architecture_is_ppc64): Move function out and adjust callers to call the migrated functions. (elf_architecture_is_big_endian): Likewise. (architecture_word_size): Likewise. (current_elf_file_is_executable): Likewise. (current_elf_file_is_dso): Likewise. * src/abg-elf-helpers.cc (architecture_is_ppc64): Add new function. (architecture_is_big_endian): Likewise. (get_architecture_word_size): Likewise. (is_executable): Likewise. (is_dso): Likewise. * src/abg-elf-helpers.h (architecture_is_ppc64): Add new declaration. (architecture_is_big_endian): Likewise. (get_architecture_word_size): Likewise. (is_executable): Likewise. (is_dso): Likewise. Reviewed-by: Giuliano Procida Signed-off-by: Matthias Maennich --- src/abg-dwarf-reader.cc | 91 ++++------------------------------------- src/abg-elf-helpers.cc | 79 +++++++++++++++++++++++++++++++++++ src/abg-elf-helpers.h | 18 ++++++++ 3 files changed, 106 insertions(+), 82 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 56da03a60940..dc3332410b1e 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -5700,10 +5700,10 @@ public: if (!elf_handle()) return fn_desc_address; - if (!elf_architecture_is_ppc64()) + if (!architecture_is_ppc64(elf_handle())) return fn_desc_address; - bool is_big_endian = elf_architecture_is_big_endian(); + bool is_big_endian = architecture_is_big_endian(elf_handle()); Elf_Scn *opd_section = find_opd_section(); if (!opd_section) @@ -5979,7 +5979,7 @@ public: { if (!fun_entry_addr_sym_map_ && !fun_addr_sym_map_) maybe_load_symbol_maps(); - if (elf_architecture_is_ppc64()) + if (architecture_is_ppc64(elf_handle())) return fun_entry_addr_sym_map_; return fun_addr_sym_map_; } @@ -6335,79 +6335,6 @@ public: elf_architecture() const {return elf_architecture_;} - /// Return the size of a word for the current architecture. - /// @return the size of a word. - unsigned char - architecture_word_size() const - { - unsigned char word_size = 0; - GElf_Ehdr eh_mem; - GElf_Ehdr* elf_header = gelf_getehdr(elf_handle(), &eh_mem); - if (elf_header->e_ident[EI_CLASS] == ELFCLASS32) - word_size = 4; - else if (elf_header->e_ident[EI_CLASS] == ELFCLASS64) - word_size = 8; - else - ABG_ASSERT_NOT_REACHED; - return word_size; - } - - /// Test if the architecture of the current binary is ppc64. - /// - /// @return true iff the architecture of the current binary is ppc64. - bool - elf_architecture_is_ppc64() const - { - GElf_Ehdr eh_mem; - GElf_Ehdr* elf_header = gelf_getehdr(elf_handle(), &eh_mem); - - return (elf_header && elf_header->e_machine == EM_PPC64); - } - - /// Test if the endianness of the current binary is Big Endian. - /// - /// https://en.wikipedia.org/wiki/Endianness. - /// - /// @return true iff the current binary is Big Endian. - bool - elf_architecture_is_big_endian() const - { - GElf_Ehdr eh_mem; - GElf_Ehdr* elf_header = gelf_getehdr(elf_handle(), &eh_mem); - - bool is_big_endian = (elf_header->e_ident[EI_DATA] == ELFDATA2MSB); - - if (!is_big_endian) - ABG_ASSERT(elf_header->e_ident[EI_DATA] == ELFDATA2LSB); - - return is_big_endian; - } - - /// Test if the current elf file being read is an executable. - /// - /// @return true iff the current elf file being read is an - /// executable. - bool - current_elf_file_is_executable() const - { - GElf_Ehdr eh_mem; - GElf_Ehdr* elf_header = gelf_getehdr(elf_handle(), &eh_mem); - return elf_header->e_type == ET_EXEC; - } - - /// Test if the current elf file being read is a dynamic shared - /// object. - /// - /// @return true iff the current elf file being read is a - /// dynamic shared object. - bool - current_elf_file_is_dso() const - { - GElf_Ehdr eh_mem; - GElf_Ehdr* elf_header = gelf_getehdr(elf_handle(), &eh_mem); - return elf_header->e_type == ET_DYN; - } - /// Getter for the map of global variables symbol address -> global /// variable symbol index. /// @@ -6471,7 +6398,7 @@ public: GElf_Ehdr elf_header; ABG_ASSERT(gelf_getehdr(elf_handle(), &elf_header)); - bool is_ppc64 = elf_architecture_is_ppc64(); + bool is_ppc64 = architecture_is_ppc64(elf_handle()); for (size_t i = 0; i < nb_syms; ++i) { @@ -6688,7 +6615,7 @@ public: { Elf_Data* elf_data = elf_rawdata(section, 0); uint8_t* bytes = reinterpret_cast(elf_data->d_buf); - bool is_big_endian = elf_architecture_is_big_endian(); + bool is_big_endian = architecture_is_big_endian(elf_handle()); elf_symbol_sptr symbol; GElf_Addr symbol_address = 0; @@ -6696,7 +6623,7 @@ public: if (position_relative_relocations) symbol_value_size = sizeof(int32_t); else - symbol_value_size = architecture_word_size(); + symbol_value_size = get_architecture_word_size(elf_handle()); const int read_offset = (symbol_offset * symbol_value_size); bytes += read_offset; @@ -6886,7 +6813,7 @@ public: if (format == UNDEFINED_KSYMTAB_FORMAT) ; else if (format == PRE_V4_19_KSYMTAB_FORMAT) - result = architecture_word_size(); + result = get_architecture_word_size(elf_handle()); else if (format == V4_19_KSYMTAB_FORMAT) result = 4; else @@ -7065,7 +6992,7 @@ public: // // Lets thus walk the array of entries, and let's read just the // symbol address part of each entry. - bool is_big_endian = elf_architecture_is_big_endian(); + bool is_big_endian = architecture_is_big_endian(elf_handle()); elf_symbol_sptr symbol; unsigned char symbol_value_size = get_ksymtab_symbol_value_size(); @@ -7367,7 +7294,7 @@ public: if (!fun_addr_sym_map_) fun_addr_sym_map_.reset(new addr_elf_symbol_sptr_map_type); - if (!fun_entry_addr_sym_map_ && elf_architecture_is_ppc64()) + if (!fun_entry_addr_sym_map_ && architecture_is_ppc64(elf_handle())) fun_entry_addr_sym_map_.reset(new addr_elf_symbol_sptr_map_type); if (!var_syms_) diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc index b77440206fb0..895feb6f7768 100644 --- a/src/abg-elf-helpers.cc +++ b/src/abg-elf-helpers.cc @@ -829,6 +829,40 @@ get_version_for_symbol(Elf* elf_handle, return false; } +/// Test if the architecture of the current binary is ppc64. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return true iff the architecture of the current binary is ppc64. +bool +architecture_is_ppc64(Elf* elf_handle) +{ + GElf_Ehdr eh_mem; + GElf_Ehdr* elf_header = gelf_getehdr(elf_handle, &eh_mem); + return (elf_header && elf_header->e_machine == EM_PPC64); +} + +/// Test if the endianness of the current binary is Big Endian. +/// +/// https://en.wikipedia.org/wiki/Endianness. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return true iff the current binary is Big Endian. +bool +architecture_is_big_endian(Elf* elf_handle) +{ + GElf_Ehdr elf_header; + gelf_getehdr(elf_handle, &elf_header); + + bool is_big_endian = (elf_header.e_ident[EI_DATA] == ELFDATA2MSB); + + if (!is_big_endian) + ABG_ASSERT(elf_header.e_ident[EI_DATA] == ELFDATA2LSB); + + return is_big_endian; +} + /// Test if the ELF binary denoted by a given ELF handle is a Linux /// Kernel Module. /// @@ -907,6 +941,51 @@ get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address) return false; } +/// Return the size of a word for the current architecture. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return the size of a word. +unsigned char +get_architecture_word_size(Elf* elf_handle) +{ + unsigned char word_size = 0; + GElf_Ehdr elf_header; + gelf_getehdr(elf_handle, &elf_header); + if (elf_header.e_ident[EI_CLASS] == ELFCLASS32) + word_size = 4; + else if (elf_header.e_ident[EI_CLASS] == ELFCLASS64) + word_size = 8; + else + ABG_ASSERT_NOT_REACHED; + return word_size; +} + +/// Test if the elf file being read is an executable. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return true iff the elf file being read is an / executable. +bool +is_executable(Elf* elf_handle) +{ + GElf_Ehdr elf_header; + gelf_getehdr(elf_handle, &elf_header); + return elf_header.e_type == ET_EXEC; +} + +/// Test if the elf file being read is a dynamic shared / object. +/// +/// @param elf_handle the ELF handle to consider. +/// +/// @return true iff the elf file being read is a / dynamic shared object. +bool +is_dso(Elf* elf_handle) +{ + GElf_Ehdr elf_header; + gelf_getehdr(elf_handle, &elf_header); + return elf_header.e_type == ET_DYN; +} } // end namespace elf_helpers } // end namespace abigail diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h index 8a83bb4f2e95..6eff245a6a30 100644 --- a/src/abg-elf-helpers.h +++ b/src/abg-elf-helpers.h @@ -139,6 +139,15 @@ get_version_for_symbol(Elf* elf_handle, bool get_def_version, elf_symbol::version& version); +// +// Architecture specific helpers +// +bool +architecture_is_ppc64(Elf* elf_handle); + +bool +architecture_is_big_endian(Elf* elf_handle); + // // Helpers for Linux Kernel Binaries // @@ -156,6 +165,15 @@ is_linux_kernel(Elf *elf_handle); bool get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address); +unsigned char +get_architecture_word_size(Elf* elf_handle); + +bool +is_executable(Elf* elf_handle); + +bool +is_dso(Elf* elf_handle); + } // end namespace elf_helpers } // end namespace abigail