public inbox for libabigail@sourceware.org
 help / color / mirror / Atom feed
From: Giuliano Procida <gprocida@google.com>
To: Matthias Maennich <maennich@google.com>
Cc: libabigail@sourceware.org, Dodji Seketeli <dodji@seketeli.org>,
	kernel-team@android.com
Subject: Re: [PATCH 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers
Date: Mon, 20 Apr 2020 16:24:50 +0100	[thread overview]
Message-ID: <CAGvU0HmL2ouTpYzMCUp8aH20-Hx1M+b7DiTzA+POKJn_Qr_-7w@mail.gmail.com> (raw)
In-Reply-To: <20200420110846.218792-7-maennich@google.com>

Hi.

On Mon, 20 Apr 2020 at 12:09, Matthias Maennich <maennich@google.com> wrote:
>
> This change migrates all ELF helpers related to section lookup to
> abg-elf-helpers.{cc,h}. It also homogenizes the interface of those to
> always return Elf_Scn* and NULL in case that section can't be found.
> Though this smells like a functional change, this latter change is
> purely cosmetic.
>
>         * src/abg-dwarf-reader.cc (read_context::find_symbol_table_section):
>         adjust to new interface of elf_helpers::find_symbol_table_section.
>         (find_opd_section): use elf_helpers::find_opd_section for lookup.
>         (find_ksymtab_section): use elf_helpers::find_ksymtab_section.
>         (find_ksymtab_gpl_section): use elf_helpers::find_ksymtab_gpl_section.
>         (find_relocation_section): Move out function.
>         (get_binary_load_address): Move out function.
>         (find_ksymtab_reloc_section): use elf_helpers::find_relocation_section
>         (find_ksymtab_gpl_reloc_section): use elf_helpers::find_relocation_section
>         * src/elf-helpers.cc (find_symbol_table_section): change
>         interface to match other find_*_section functions.
>         (find_symbol_table_section_index): Adjust for the new interface
>         of find_symbol_table_section.
>         (find_opd_section): New function.
>         (find_ksymtab_section): New function.
>         (find_ksymtab_gpl_section): New function.
>         (find_relocation_section): New function.
>         (get_binary_load_address): New function.
>         * src/elf-helpers.h (find_symbol_table_section): Change declaration.
>         (find_opd_section): New function declation.
>         (find_ksymtab_section): New function declation.
>         (find_ksymtab_gpl_section): New function declation.
>         (find_relocation_section): New function declation.
>         (get_binary_load_address): New function declation.
>
> Signed-off-by: Matthias Maennich <maennich@google.com>
> ---
>  src/abg-dwarf-reader.cc | 112 ++++++----------------------------
>  src/abg-elf-helpers.cc  | 129 +++++++++++++++++++++++++++++++++++++---
>  src/abg-elf-helpers.h   |  22 ++++++-
>  3 files changed, 157 insertions(+), 106 deletions(-)
>
> diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc
> index ec1f9f3fe8f3..56da03a60940 100644
> --- a/src/abg-dwarf-reader.cc
> +++ b/src/abg-dwarf-reader.cc
> @@ -542,53 +542,6 @@ compare_dies(const read_context& ctxt,
>              bool update_canonical_dies_on_the_fly);
>
>
> -/// Get the address at which a given binary is loaded in memory⋅
> -///
> -/// @param elf_handle the elf handle for the binary to consider.
> -///
> -/// @param load_address the address where the binary is loaded.  This
> -/// is set by the function iff it returns true.
> -///
> -/// @return true if the function could get the binary load address
> -/// and assign @p load_address to it.
> -static bool
> -get_binary_load_address(Elf *elf_handle,
> -                       GElf_Addr &load_address)
> -{
> -  GElf_Ehdr eh_mem;
> -  GElf_Ehdr *elf_header = gelf_getehdr(elf_handle, &eh_mem);
> -  size_t num_segments = elf_header->e_phnum;
> -  GElf_Phdr *program_header = 0;
> -  GElf_Addr result;
> -  bool found_loaded_segment = false;
> -  GElf_Phdr ph_mem;
> -
> -  for (unsigned i = 0; i < num_segments; ++i)
> -    {
> -      program_header = gelf_getphdr(elf_handle, i, &ph_mem);
> -      if (program_header && program_header->p_type == PT_LOAD)
> -       {
> -         if (!found_loaded_segment)
> -           {
> -             result = program_header->p_vaddr;
> -             found_loaded_segment = true;
> -           }
> -
> -         if (program_header->p_vaddr < result)
> -           // The resulting load address we want is the lowest
> -           // load address of all the loaded segments.
> -           result = program_header->p_vaddr;
> -       }
> -    }
> -
> -  if (found_loaded_segment)
> -    {
> -      load_address = result;
> -      return true;
> -    }
> -  return false;
> -}
> -
>  /// Find the file name of the alternate debug info file.
>  ///
>  /// @param elf_module the elf module to consider.
> @@ -5282,8 +5235,8 @@ public:
>    find_symbol_table_section() const
>    {
>      if (!symtab_section_)
> -      dwarf_reader::find_symbol_table_section(elf_handle(),
> -                                             const_cast<read_context*>(this)->symtab_section_);
> +      const_cast<read_context*>(this)->symtab_section_ =
> +         elf_helpers::find_symbol_table_section(elf_handle());
>      return symtab_section_;
>    }
>
> @@ -5296,8 +5249,8 @@ public:
>    find_opd_section() const
>    {
>      if (!opd_section_)
> -      const_cast<read_context*>(this)->opd_section_=
> -       find_section(elf_handle(), ".opd", SHT_PROGBITS);
> +      const_cast<read_context*>(this)->opd_section_ =
> +         elf_helpers::find_opd_section(elf_handle());
>      return opd_section_;
>    }
>
> @@ -5310,39 +5263,21 @@ public:
>    {
>      if (!ksymtab_section_)
>        const_cast<read_context*>(this)->ksymtab_section_ =
> -       find_section(elf_handle(), "__ksymtab", SHT_PROGBITS);
> +         elf_helpers::find_ksymtab_section(elf_handle());
>      return ksymtab_section_;
>    }
>
> -  /// Return the .rel{a,} section corresponding to a given section.
> -  ///
> -  /// @param target_section the section to search the relocation section for
> +  /// Return the __ksymtab_gpl section of a linux kernel ELF file
> +  /// (either a vmlinux binary or a kernel module).
>    ///
> -  /// @return the .rel{a,} section if found, null otherwise.
> +  /// @return the __ksymtab_gpl section if found, nil otherwise.
>    Elf_Scn*
> -  find_relocation_section(Elf_Scn* target_section) const
> +  find_ksymtab_gpl_section() const
>    {
> -    if (target_section)
> -      {
> -       // the relo section we are searching for has this index as sh_info
> -       size_t target_index = elf_ndxscn(target_section);
> -
> -       // now iterate over all the sections, look for relocation sections and
> -       // find the one that points to the section we are searching for
> -       Elf_Scn*  section = 0;
> -       GElf_Shdr header_mem, *header;
> -       while ((section = elf_nextscn(elf_handle(), section)) != 0)
> -         {
> -           header = gelf_getshdr(section, &header_mem);
> -           if (header == NULL
> -               || (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
> -             continue;
> -
> -           if (header->sh_info == target_index)
> -             return section;
> -         }
> -      }
> -    return NULL;
> +    if (!ksymtab_gpl_section_)
> +      const_cast<read_context*>(this)->ksymtab_gpl_section_ =
> +         elf_helpers::find_ksymtab_gpl_section(elf_handle());
> +    return ksymtab_gpl_section_;
>    }
>
>    /// Return the .rel{a,}__ksymtab section of a linux kernel ELF file (either
> @@ -5354,25 +5289,12 @@ public:
>    {
>      if (!ksymtab_reloc_section_)
>        {
> -       const_cast<read_context*>(this)->ksymtab_reloc_section_
> -           = find_relocation_section(find_ksymtab_section());
> +       const_cast<read_context*>(this)->ksymtab_reloc_section_ =
> +           find_relocation_section(elf_handle(), find_ksymtab_section());
>        }
>      return ksymtab_reloc_section_;
>    }
>
> -  /// Return the __ksymtab_gpl section of a linux kernel ELF file
> -  /// (either a vmlinux binary or a kernel module).
> -  ///
> -  /// @return the __ksymtab_gpl section if found, nil otherwise.
> -  Elf_Scn*
> -  find_ksymtab_gpl_section() const
> -  {
> -    if (!ksymtab_gpl_section_)
> -      const_cast<read_context*>(this)->ksymtab_gpl_section_ =
> -       find_section(elf_handle(), "__ksymtab_gpl", SHT_PROGBITS);
> -    return ksymtab_gpl_section_;
> -  }
> -
>    /// Return the .rel{a,}__ksymtab_gpl section of a linux kernel ELF file
>    /// (either a vmlinux binary or a kernel module).
>    ///
> @@ -5382,8 +5304,8 @@ public:
>    {
>      if (!ksymtab_gpl_reloc_section_)
>        {
> -       const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_
> -           = find_relocation_section(find_ksymtab_gpl_section());
> +       const_cast<read_context*>(this)->ksymtab_gpl_reloc_section_ =
> +           find_relocation_section(elf_handle(), find_ksymtab_gpl_section());
>        }
>      return ksymtab_gpl_reloc_section_;
>    }
> diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc
> index ede191014369..b77440206fb0 100644
> --- a/src/abg-elf-helpers.cc
> +++ b/src/abg-elf-helpers.cc
> @@ -357,9 +357,9 @@ find_section(Elf* elf_handle, const std::string& name, Elf64_Word section_type)
>  ///
>  /// @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)
> +/// @return the symbol table section
> +Elf_Scn*
> +find_symbol_table_section(Elf* elf_handle)
>  {
>    Elf_Scn* section = 0, *dynsym = 0, *sym_tab = 0;
>    while ((section = elf_nextscn(elf_handle, section)) != 0)
> @@ -378,12 +378,11 @@ find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
>        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;
> +       return sym_tab ? sym_tab : dynsym;
>        else
> -       symtab = dynsym ? dynsym : sym_tab;
> -      return true;
> +       return dynsym ? dynsym : sym_tab;
>      }
> -  return false;
> +  return NULL;
>  }
>
>  /// Find the index (in the section headers table) of the symbol table
> @@ -402,8 +401,9 @@ find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab)
>  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))
> +  Elf_Scn* section = find_symbol_table_section(elf_handle);
> +
> +  if (!section)
>      return false;
>
>    symtab_index = elf_ndxscn(section);
> @@ -500,6 +500,17 @@ Elf_Scn*
>  find_data1_section(Elf* elf_handle)
>  {return find_section(elf_handle, ".data1", SHT_PROGBITS);}
>
> +/// Return the "Official Procedure descriptors section."  This
> +/// section is named .opd, and is usually present only on PPC64
> +/// ELFv1 binaries.
> +///
> +/// @param elf_handle the elf handle to consider.
> +///
> +/// @return the .opd section, if found.  Return nil otherwise.
> +Elf_Scn*
> +find_opd_section(Elf* elf_handle)
> +{return find_section(elf_handle, ".opd", SHT_PROGBITS);}
> +
>  /// Return the SHT_GNU_versym, SHT_GNU_verdef and SHT_GNU_verneed
>  /// sections that are involved in symbol versionning.
>  ///
> @@ -548,6 +559,26 @@ get_symbol_versionning_sections(Elf*               elf_handle,
>    return false;
>  }
>
> +/// Return the __ksymtab section of a linux kernel ELF file (either
> +/// a vmlinux binary or a kernel module).
> +///
> +/// @param elf_handle the elf handle to consider.
> +///
> +/// @return the __ksymtab section if found, nil otherwise.
> +Elf_Scn*
> +find_ksymtab_section(Elf* elf_handle)
> +{return find_section(elf_handle, "__ksymtab", SHT_PROGBITS);}
> +
> +/// Return the __ksymtab_gpl section of a linux kernel ELF file (either
> +/// a vmlinux binary or a kernel module).
> +///
> +/// @param elf_handle the elf handle to consider.
> +///
> +/// @return the __ksymtab section if found, nil otherwise.
> +Elf_Scn*
> +find_ksymtab_gpl_section(Elf* elf_handle)
> +{return find_section(elf_handle, "__ksymtab_gpl", SHT_PROGBITS);}
> +
>  /// Find the __ksymtab_strings section of a Linux kernel binary.
>  ///
>  /// @param elf_handle the elf handle to use.
> @@ -563,6 +594,39 @@ find_ksymtab_strings_section(Elf *elf_handle)
>    return 0;
>  }
>
> +/// Return the .rel{a,} section corresponding to a given section.
> +///
> +/// @param elf_handle the elf handle to consider.
> +///
> +/// @param target_section the section to search the relocation section for
> +///
> +/// @return the .rel{a,} section if found, null otherwise.
> +Elf_Scn*
> +find_relocation_section(Elf* elf_handle, Elf_Scn* target_section)
> +{
> +  if (target_section)
> +    {
> +      // the relo section we are searching for has this index as sh_info
> +      size_t target_index = elf_ndxscn(target_section);
> +
> +      // now iterate over all the sections, look for relocation sections and
> +      // find the one that points to the section we are searching for
> +      Elf_Scn* section = 0;
> +      GElf_Shdr header_mem, *header;
> +      while ((section = elf_nextscn(elf_handle, section)) != 0)
> +       {
> +         header = gelf_getshdr(section, &header_mem);
> +         if (header == NULL
> +             || (header->sh_type != SHT_RELA && header->sh_type != SHT_REL))
> +           continue;
> +
> +         if (header->sh_info == target_index)
> +           return section;
> +       }
> +    }
> +  return NULL;
> +}
> +
>  /// Get the version definition (from the SHT_GNU_verdef section) of a
>  /// given symbol represented by a pointer to GElf_Versym.
>  ///
> @@ -797,5 +861,52 @@ is_linux_kernel(Elf *elf_handle)
>           || is_linux_kernel_module(elf_handle));
>  }
>
> +/// Get the address at which a given binary is loaded in memory⋅
> +///
> +/// @param elf_handle the elf handle for the binary to consider.
> +///
> +/// @param load_address the address where the binary is loaded.  This
> +/// is set by the function iff it returns true.
> +///
> +/// @return true if the function could get the binary load address
> +/// and assign @p load_address to it.

Should be returning nullable load_address.


> +bool
> +get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address)
> +{
> +  GElf_Ehdr elf_header;
> +  gelf_getehdr(elf_handle, &elf_header);
> +  size_t num_segments = elf_header.e_phnum;
> +  GElf_Phdr *program_header = NULL;
> +  GElf_Addr result;
> +  bool found_loaded_segment = false;
> +  GElf_Phdr ph_mem;
> +
> +  for (unsigned i = 0; i < num_segments; ++i)
> +    {
> +      program_header = gelf_getphdr(elf_handle, i, &ph_mem);
> +      if (program_header && program_header->p_type == PT_LOAD)
> +       {
> +         if (!found_loaded_segment)
> +           {
> +             result = program_header->p_vaddr;
> +             found_loaded_segment = true;
> +           }
> +
> +         if (program_header->p_vaddr < result)
> +           // The resulting load address we want is the lowest
> +           // load address of all the loaded segments.
> +           result = program_header->p_vaddr;
> +       }
> +    }
> +
> +  if (found_loaded_segment)
> +    {
> +      load_address = result;
> +      return true;
> +    }
> +  return false;
> +}
> +
> +
>  } // end namespace elf_helpers
>  } // end namespace abigail
> diff --git a/src/abg-elf-helpers.h b/src/abg-elf-helpers.h
> index 7ddd887de959..8a83bb4f2e95 100644
> --- a/src/abg-elf-helpers.h
> +++ b/src/abg-elf-helpers.h
> @@ -63,8 +63,8 @@ find_section(Elf*             elf_handle,
>              const std::string& name,
>              Elf64_Word         section_type);
>
> -bool
> -find_symbol_table_section(Elf* elf_handle, Elf_Scn*& symtab);
> +Elf_Scn*
> +find_symbol_table_section(Elf* elf_handle);
>
>  bool
>  find_symbol_table_section_index(Elf* elf_handle, size_t& symtab_index);
> @@ -96,15 +96,27 @@ find_data_section(Elf* elf_handle);
>  Elf_Scn*
>  find_data1_section(Elf* elf_handle);
>
> +Elf_Scn*
> +find_opd_section(Elf* elf_handle);
> +
>  bool
>  get_symbol_versionning_sections(Elf*           elf_handle,
>                                 Elf_Scn*&       versym_section,
>                                 Elf_Scn*&       verdef_section,
>                                 Elf_Scn*&       verneed_section);
>
> +Elf_Scn*
> +find_ksymtab_section(Elf* elf_handle);
> +
> +Elf_Scn*
> +find_ksymtab_gpl_section(Elf* elf_handle);
> +
>  Elf_Scn*
>  find_ksymtab_strings_section(Elf *elf_handle);
>
> +Elf_Scn*
> +find_relocation_section(Elf* elf_handle, Elf_Scn* target_section);
> +
>  //
>  // Helpers for symbol versioning
>  //
> @@ -137,6 +149,12 @@ is_linux_kernel_module(Elf *elf_handle);
>  bool
>  is_linux_kernel(Elf *elf_handle);
>
> +//
> +// Misc Helpers
> +//
> +
> +bool
> +get_binary_load_address(Elf* elf_handle, GElf_Addr& load_address);
>
>  } // end namespace elf_helpers
>  } // end namespace abigail
> --
> 2.26.1.301.g55bc3eb7cb9-goog
>

  reply	other threads:[~2020-04-20 15:25 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-20 11:08 [PATCH 0/8] Refactor dwarf-reader: split out ELF helpers Matthias Maennich
2020-04-20 11:08 ` [PATCH 1/8] abg-dwarf-reader split: create abg-elf-helpers.{h, cc} and test case Matthias Maennich
2020-04-20 15:35   ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader Matthias Maennich
2020-04-20 15:34   ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 3/8] abg-elf-helpers: move some versioning " Matthias Maennich
2020-04-20 15:33   ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 4/8] abg-elf-helpers: move some kernel " Matthias Maennich
2020-04-20 14:32   ` Giuliano Procida
2020-04-20 15:30     ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 5/8] abg-elf-helpers: consolidate the is_linux_kernel* helpers Matthias Maennich
2020-04-20 15:29   ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers Matthias Maennich
2020-04-20 15:24   ` Giuliano Procida [this message]
2020-04-21  6:14     ` Matthias Maennich
2020-04-21 11:02       ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers) Matthias Maennich
2020-04-20 15:25   ` Giuliano Procida
2020-04-20 11:08 ` [PATCH 8/8] abg-elf-helpers: migrate maybe_adjust_et_rel_sym_addr_to_abs_addr Matthias Maennich
2020-04-21  6:35 ` [PATCH v2 0/8] Refactor dwarf-reader: split out ELF helpers Matthias Maennich
2020-04-21  6:35   ` [PATCH v2 1/8] abg-dwarf-reader split: create abg-elf-helpers.{h, cc} and test case Matthias Maennich
2020-04-22  9:42     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 2/8] abg-elf-helpers: move some elf helpers from abg-dwarf-reader Matthias Maennich
2020-04-22  9:44     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 3/8] abg-elf-helpers: move some versioning " Matthias Maennich
2020-04-22  9:46     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 4/8] abg-elf-helpers: move some kernel " Matthias Maennich
2020-04-22  9:47     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 5/8] abg-elf-helpers: consolidate the is_linux_kernel* helpers Matthias Maennich
2020-04-22  9:48     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 6/8] abg-dwarf-reader: migrate more ELF helpers to elf-helpers Matthias Maennich
2020-04-22  9:53     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 7/8] abg-elf-helpers: migrate more elf helpers (architecture specific helpers) Matthias Maennich
2020-04-22  9:55     ` Dodji Seketeli
2020-04-21  6:35   ` [PATCH v2 8/8] abg-elf-helpers: migrate maybe_adjust_et_rel_sym_addr_to_abs_addr Matthias Maennich
2020-04-22  9:56     ` Dodji Seketeli
2020-04-22  9:57   ` [PATCH v2 0/8] Refactor dwarf-reader: split out ELF helpers Dodji Seketeli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAGvU0HmL2ouTpYzMCUp8aH20-Hx1M+b7DiTzA+POKJn_Qr_-7w@mail.gmail.com \
    --to=gprocida@google.com \
    --cc=dodji@seketeli.org \
    --cc=kernel-team@android.com \
    --cc=libabigail@sourceware.org \
    --cc=maennich@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).