[7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers)
Commit Message
This migrates more architecture specific helpers over to the
elf-helpers. No functional change intended.
Signed-off-by: Matthias Maennich <maennich@google.com>
* 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.
Signed-off-by: Matthias Maennich <maennich@google.com>
---
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(-)
Comments
Hi.
On Mon, 20 Apr 2020 at 12:09, Matthias Maennich <maennich@google.com> wrote:
>
> This migrates more architecture specific helpers over to the
> elf-helpers. No functional change intended.
>
> Signed-off-by: Matthias Maennich <maennich@google.com>
Stray line.
> * 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 <gprocida@google.com>
> Signed-off-by: Matthias Maennich <maennich@google.com>
> ---
> 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<uint8_t*>(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
>
> --
> 2.26.1.301.g55bc3eb7cb9-goog
>
@@ -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<uint8_t*>(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_)
@@ -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
@@ -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